395 396 if (stdout instanceof ProcessPipeInputStream) 397 ((ProcessPipeInputStream) stdout).processExited(); 398 399 if (stderr instanceof ProcessPipeInputStream) 400 ((ProcessPipeInputStream) stderr).processExited(); 401 402 if (stdin instanceof ProcessPipeOutputStream) 403 ((ProcessPipeOutputStream) stdin).processExited(); 404 405 return null; 406 }); 407 break; 408 409 case SOLARIS: 410 stdin = (fds[0] == -1) ? 411 ProcessBuilder.NullOutputStream.INSTANCE : 412 new BufferedOutputStream( 413 new FileOutputStream(newFileDescriptor(fds[0]))); 414 415 stdout = (fds[1] == -1) ? 416 ProcessBuilder.NullInputStream.INSTANCE : 417 new BufferedInputStream( 418 stdout_inner_stream = 419 new DeferredCloseInputStream( 420 newFileDescriptor(fds[1]))); 421 422 stderr = (fds[2] == -1) ? 423 ProcessBuilder.NullInputStream.INSTANCE : 424 new DeferredCloseInputStream(newFileDescriptor(fds[2])); 425 426 /* 427 * For each subprocess forked a corresponding reaper task 428 * is submitted. That task is the only thread which waits 429 * for the subprocess to terminate and it doesn't hold any 430 * locks while doing so. This design allows waitFor() and 431 * exitStatus() to be safely executed in parallel (and they 432 * need no native code). 433 */ 434 ProcessHandleImpl.completion(pid, true).handle((exitcode, throwable) -> { 435 synchronized (this) { 436 this.exitcode = (exitcode == null) ? -1 : exitcode.intValue(); 437 this.hasExited = true; 438 this.notifyAll(); 439 } 440 return null; 441 }); 442 break; 443 444 case AIX: 445 stdin = (fds[0] == -1) ? 446 ProcessBuilder.NullOutputStream.INSTANCE : 447 new ProcessPipeOutputStream(fds[0]); 448 449 stdout = (fds[1] == -1) ? 450 ProcessBuilder.NullInputStream.INSTANCE : 451 new DeferredCloseProcessPipeInputStream(fds[1]); 452 453 stderr = (fds[2] == -1) ? 454 ProcessBuilder.NullInputStream.INSTANCE : 455 new DeferredCloseProcessPipeInputStream(fds[2]); 456 457 ProcessHandleImpl.completion(pid, true).handle((exitcode, throwable) -> { 458 synchronized (this) { 459 this.exitcode = (exitcode == null) ? -1 : exitcode.intValue(); 460 this.hasExited = true; 461 this.notifyAll(); 462 } 463 464 if (stdout instanceof DeferredCloseProcessPipeInputStream) 465 ((DeferredCloseProcessPipeInputStream) stdout).processExited(); 466 467 if (stderr instanceof DeferredCloseProcessPipeInputStream) 468 ((DeferredCloseProcessPipeInputStream) stderr).processExited(); 469 | 395 396 if (stdout instanceof ProcessPipeInputStream) 397 ((ProcessPipeInputStream) stdout).processExited(); 398 399 if (stderr instanceof ProcessPipeInputStream) 400 ((ProcessPipeInputStream) stderr).processExited(); 401 402 if (stdin instanceof ProcessPipeOutputStream) 403 ((ProcessPipeOutputStream) stdin).processExited(); 404 405 return null; 406 }); 407 break; 408 409 case SOLARIS: 410 stdin = (fds[0] == -1) ? 411 ProcessBuilder.NullOutputStream.INSTANCE : 412 new BufferedOutputStream( 413 new FileOutputStream(newFileDescriptor(fds[0]))); 414 415 stdout = (fds[1] == -1 || forceNullOutputStream) ? 416 ProcessBuilder.NullInputStream.INSTANCE : 417 new BufferedInputStream( 418 stdout_inner_stream = 419 new DeferredCloseInputStream( 420 newFileDescriptor(fds[1]))); 421 422 stderr = (fds[2] == -1) ? 423 ProcessBuilder.NullInputStream.INSTANCE : 424 new DeferredCloseInputStream(newFileDescriptor(fds[2])); 425 426 /* 427 * For each subprocess forked a corresponding reaper task 428 * is submitted. That task is the only thread which waits 429 * for the subprocess to terminate and it doesn't hold any 430 * locks while doing so. This design allows waitFor() and 431 * exitStatus() to be safely executed in parallel (and they 432 * need no native code). 433 */ 434 ProcessHandleImpl.completion(pid, true).handle((exitcode, throwable) -> { 435 synchronized (this) { 436 this.exitcode = (exitcode == null) ? -1 : exitcode.intValue(); 437 this.hasExited = true; 438 this.notifyAll(); 439 } 440 return null; 441 }); 442 break; 443 444 case AIX: 445 stdin = (fds[0] == -1) ? 446 ProcessBuilder.NullOutputStream.INSTANCE : 447 new ProcessPipeOutputStream(fds[0]); 448 449 stdout = (fds[1] == -1 || forceNullOutputStream) ? 450 ProcessBuilder.NullInputStream.INSTANCE : 451 new DeferredCloseProcessPipeInputStream(fds[1]); 452 453 stderr = (fds[2] == -1) ? 454 ProcessBuilder.NullInputStream.INSTANCE : 455 new DeferredCloseProcessPipeInputStream(fds[2]); 456 457 ProcessHandleImpl.completion(pid, true).handle((exitcode, throwable) -> { 458 synchronized (this) { 459 this.exitcode = (exitcode == null) ? -1 : exitcode.intValue(); 460 this.hasExited = true; 461 this.notifyAll(); 462 } 463 464 if (stdout instanceof DeferredCloseProcessPipeInputStream) 465 ((DeferredCloseProcessPipeInputStream) stdout).processExited(); 466 467 if (stderr instanceof DeferredCloseProcessPipeInputStream) 468 ((DeferredCloseProcessPipeInputStream) stderr).processExited(); 469 |