< prev index next >

src/java.base/unix/native/libjava/ProcessImpl_md.c

Print this page




 638         (fds[1] == -1 && pipe(out) < 0) ||
 639         (fds[2] == -1 && pipe(err) < 0) ||
 640         (pipe(childenv) < 0) ||
 641         (pipe(fail) < 0)) {
 642         throwIOException(env, errno, "Bad file descriptor");
 643         goto Catch;
 644     }
 645     c->fds[0] = fds[0];
 646     c->fds[1] = fds[1];
 647     c->fds[2] = fds[2];
 648 
 649     copyPipe(in,   c->in);
 650     copyPipe(out,  c->out);
 651     copyPipe(err,  c->err);
 652     copyPipe(fail, c->fail);
 653     copyPipe(childenv, c->childenv);
 654 
 655     c->redirectErrorStream = redirectErrorStream;
 656     c->mode = mode;
 657 
 658     /* In posix_spawn mode, require the child process to signal aliveness
 659      * right after it comes up. This is because there are implementations of
 660      * posix_spawn() which do not report failed exec()s back to the caller
 661      * (e.g. glibc, see JDK-8223777). In those cases, the fork() will have
 662      * worked and successfully started the child process, but the exec() will
 663      * have failed. There is no way for us to distinguish this from a target
 664      * binary just exiting right after start.
 665      *
 666      * Note that we could do this additional handshake in all modes but for
 667      * prudence only do it when it is needed (in posix_spawn mode). */
 668     c->sendAlivePing = (mode == MODE_POSIX_SPAWN) ? 1 : 0;
 669 
 670     resultPid = startChild(env, process, c, phelperpath);
 671     assert(resultPid != 0);
 672 
 673     if (resultPid < 0) {
 674         switch (c->mode) {
 675           case MODE_VFORK:
 676             throwIOException(env, errno, "vfork failed");
 677             break;
 678           case MODE_FORK:
 679             throwIOException(env, errno, "fork failed");
 680             break;
 681           case MODE_POSIX_SPAWN:
 682             throwIOException(env, errno, "posix_spawn failed");
 683             break;
 684         }
 685         goto Catch;
 686     }
 687     close(fail[1]); fail[1] = -1; /* See: WhyCantJohnnyExec  (childproc.c)  */
 688 
 689     /* If we expect the child to ping aliveness, wait for it. */
 690     if (c->sendAlivePing) {
 691         switch(readFully(fail[0], &errnum, sizeof(errnum))) {
 692         case 0: /* First exec failed; */
 693             waitpid(resultPid, NULL, 0);
 694             throwIOException(env, 0, "Failed to exec spawn helper.");
 695             goto Catch;
 696         case sizeof(errnum):
 697             assert(errnum == CHILD_IS_ALIVE);
 698             if (errnum != CHILD_IS_ALIVE) {
 699                 /* Should never happen since the first thing the spawn
 700                  * helper should do is to send an alive ping to the parent,
 701                  * before doing any subsequent work. */
 702                 throwIOException(env, 0, "Bad code from spawn helper "
 703                                          "(Failed to exec spawn helper.");
 704                 goto Catch;
 705             }
 706             break;
 707         default:
 708             throwIOException(env, errno, "Read failed");
 709             goto Catch;
 710         }
 711     }
 712 
 713     switch (readFully(fail[0], &errnum, sizeof(errnum))) {
 714     case 0: break; /* Exec succeeded */
 715     case sizeof(errnum):
 716         waitpid(resultPid, NULL, 0);
 717         throwIOException(env, errnum, "Exec failed");
 718         goto Catch;
 719     default:
 720         throwIOException(env, errno, "Read failed");
 721         goto Catch;
 722     }
 723 
 724     fds[0] = (in [1] != -1) ? in [1] : -1;
 725     fds[1] = (out[0] != -1) ? out[0] : -1;
 726     fds[2] = (err[0] != -1) ? err[0] : -1;
 727 
 728  Finally:
 729     /* Always clean up the child's side of the pipes */
 730     closeSafely(in [0]);
 731     closeSafely(out[1]);




 638         (fds[1] == -1 && pipe(out) < 0) ||
 639         (fds[2] == -1 && pipe(err) < 0) ||
 640         (pipe(childenv) < 0) ||
 641         (pipe(fail) < 0)) {
 642         throwIOException(env, errno, "Bad file descriptor");
 643         goto Catch;
 644     }
 645     c->fds[0] = fds[0];
 646     c->fds[1] = fds[1];
 647     c->fds[2] = fds[2];
 648 
 649     copyPipe(in,   c->in);
 650     copyPipe(out,  c->out);
 651     copyPipe(err,  c->err);
 652     copyPipe(fail, c->fail);
 653     copyPipe(childenv, c->childenv);
 654 
 655     c->redirectErrorStream = redirectErrorStream;
 656     c->mode = mode;
 657 












 658     resultPid = startChild(env, process, c, phelperpath);
 659     assert(resultPid != 0);
 660 
 661     if (resultPid < 0) {
 662         switch (c->mode) {
 663           case MODE_VFORK:
 664             throwIOException(env, errno, "vfork failed");
 665             break;
 666           case MODE_FORK:
 667             throwIOException(env, errno, "fork failed");
 668             break;
 669           case MODE_POSIX_SPAWN:
 670             throwIOException(env, errno, "posix_spawn failed");
 671             break;
 672         }
 673         goto Catch;
 674     }
 675     close(fail[1]); fail[1] = -1; /* See: WhyCantJohnnyExec  (childproc.c)  */
























 676 
 677     switch (readFully(fail[0], &errnum, sizeof(errnum))) {
 678     case 0: break; /* Exec succeeded */
 679     case sizeof(errnum):
 680         waitpid(resultPid, NULL, 0);
 681         throwIOException(env, errnum, "Exec failed");
 682         goto Catch;
 683     default:
 684         throwIOException(env, errno, "Read failed");
 685         goto Catch;
 686     }
 687 
 688     fds[0] = (in [1] != -1) ? in [1] : -1;
 689     fds[1] = (out[0] != -1) ? out[0] : -1;
 690     fds[2] = (err[0] != -1) ? err[0] : -1;
 691 
 692  Finally:
 693     /* Always clean up the child's side of the pipes */
 694     closeSafely(in [0]);
 695     closeSafely(out[1]);


< prev index next >