< prev index next >

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

Print this page




 296                 break; /* Try other directories in PATH */
 297             default:
 298                 return;
 299             }
 300         }
 301         if (sticky_errno != 0)
 302             errno = sticky_errno;
 303     }
 304 }
 305 
 306 /**
 307  * Child process after a successful fork().
 308  * This function must not return, and must be prepared for either all
 309  * of its address space to be shared with its parent, or to be a copy.
 310  * It must not modify global variables such as "environ".
 311  */
 312 int
 313 childProcess(void *arg)
 314 {
 315     const ChildStuff* p = (const ChildStuff*) arg;
 316     int fail_pipe_fd = p->fail[1];
 317 
 318     if (p->sendAlivePing) {
 319         /* Child shall signal aliveness to parent at the very first
 320          * moment. */
 321         int code = CHILD_IS_ALIVE;
 322         restartableWrite(fail_pipe_fd, &code, sizeof(code));
 323     }
 324 
 325     /* Close the parent sides of the pipes.
 326        Closing pipe fds here is redundant, since closeDescriptors()
 327        would do it anyways, but a little paranoia is a good thing. */
 328     if ((closeSafely(p->in[1])   == -1) ||
 329         (closeSafely(p->out[0])  == -1) ||
 330         (closeSafely(p->err[0])  == -1) ||
 331         (closeSafely(p->childenv[0])  == -1) ||
 332         (closeSafely(p->childenv[1])  == -1) ||
 333         (closeSafely(p->fail[0]) == -1))
 334         goto WhyCantJohnnyExec;
 335 
 336     /* Give the child sides of the pipes the right fileno's. */
 337     /* Note: it is possible for in[0] == 0 */
 338     if ((moveDescriptor(p->in[0] != -1 ?  p->in[0] : p->fds[0],
 339                         STDIN_FILENO) == -1) ||
 340         (moveDescriptor(p->out[1]!= -1 ? p->out[1] : p->fds[1],
 341                         STDOUT_FILENO) == -1))
 342         goto WhyCantJohnnyExec;
 343 
 344     if (p->redirectErrorStream) {
 345         if ((closeSafely(p->err[1]) == -1) ||
 346             (restartableDup2(STDOUT_FILENO, STDERR_FILENO) == -1))
 347             goto WhyCantJohnnyExec;
 348     } else {
 349         if (moveDescriptor(p->err[1] != -1 ? p->err[1] : p->fds[2],
 350                            STDERR_FILENO) == -1)
 351             goto WhyCantJohnnyExec;
 352     }
 353 
 354     if (moveDescriptor(fail_pipe_fd, FAIL_FILENO) == -1)
 355         goto WhyCantJohnnyExec;
 356 
 357     /* We moved the fail pipe fd */
 358     fail_pipe_fd = FAIL_FILENO;
 359 
 360     /* close everything */
 361     if (closeDescriptors() == 0) { /* failed,  close the old way */
 362         int max_fd = (int)sysconf(_SC_OPEN_MAX);
 363         int fd;
 364         for (fd = FAIL_FILENO + 1; fd < max_fd; fd++)
 365             if (close(fd) == -1 && errno != EBADF)
 366                 goto WhyCantJohnnyExec;
 367     }
 368 
 369     /* change to the new working directory */
 370     if (p->pdir != NULL && chdir(p->pdir) < 0)
 371         goto WhyCantJohnnyExec;
 372 
 373     if (fcntl(FAIL_FILENO, F_SETFD, FD_CLOEXEC) == -1)
 374         goto WhyCantJohnnyExec;
 375 
 376     JDK_execvpe(p->mode, p->argv[0], p->argv, p->envv);
 377 
 378  WhyCantJohnnyExec:
 379     /* We used to go to an awful lot of trouble to predict whether the
 380      * child would fail, but there is no reliable way to predict the
 381      * success of an operation without *trying* it, and there's no way
 382      * to try a chdir or exec in the parent.  Instead, all we need is a
 383      * way to communicate any failure back to the parent.  Easy; we just
 384      * send the errno back to the parent over a pipe in case of failure.
 385      * The tricky thing is, how do we communicate the *success* of exec?
 386      * We use FD_CLOEXEC together with the fact that a read() on a pipe
 387      * yields EOF when the write ends (we have two of them!) are closed.
 388      */
 389     {
 390         int errnum = errno;
 391         restartableWrite(fail_pipe_fd, &errnum, sizeof(errnum));
 392     }
 393     close(fail_pipe_fd);
 394     _exit(-1);
 395     return 0;  /* Suppress warning "no return value from function" */
 396 }


 296                 break; /* Try other directories in PATH */
 297             default:
 298                 return;
 299             }
 300         }
 301         if (sticky_errno != 0)
 302             errno = sticky_errno;
 303     }
 304 }
 305 
 306 /**
 307  * Child process after a successful fork().
 308  * This function must not return, and must be prepared for either all
 309  * of its address space to be shared with its parent, or to be a copy.
 310  * It must not modify global variables such as "environ".
 311  */
 312 int
 313 childProcess(void *arg)
 314 {
 315     const ChildStuff* p = (const ChildStuff*) arg;








 316 
 317     /* Close the parent sides of the pipes.
 318        Closing pipe fds here is redundant, since closeDescriptors()
 319        would do it anyways, but a little paranoia is a good thing. */
 320     if ((closeSafely(p->in[1])   == -1) ||
 321         (closeSafely(p->out[0])  == -1) ||
 322         (closeSafely(p->err[0])  == -1) ||
 323         (closeSafely(p->childenv[0])  == -1) ||
 324         (closeSafely(p->childenv[1])  == -1) ||
 325         (closeSafely(p->fail[0]) == -1))
 326         goto WhyCantJohnnyExec;
 327 
 328     /* Give the child sides of the pipes the right fileno's. */
 329     /* Note: it is possible for in[0] == 0 */
 330     if ((moveDescriptor(p->in[0] != -1 ?  p->in[0] : p->fds[0],
 331                         STDIN_FILENO) == -1) ||
 332         (moveDescriptor(p->out[1]!= -1 ? p->out[1] : p->fds[1],
 333                         STDOUT_FILENO) == -1))
 334         goto WhyCantJohnnyExec;
 335 
 336     if (p->redirectErrorStream) {
 337         if ((closeSafely(p->err[1]) == -1) ||
 338             (restartableDup2(STDOUT_FILENO, STDERR_FILENO) == -1))
 339             goto WhyCantJohnnyExec;
 340     } else {
 341         if (moveDescriptor(p->err[1] != -1 ? p->err[1] : p->fds[2],
 342                            STDERR_FILENO) == -1)
 343             goto WhyCantJohnnyExec;
 344     }
 345 
 346     if (moveDescriptor(p->fail[1], FAIL_FILENO) == -1)
 347         goto WhyCantJohnnyExec;
 348 



 349     /* close everything */
 350     if (closeDescriptors() == 0) { /* failed,  close the old way */
 351         int max_fd = (int)sysconf(_SC_OPEN_MAX);
 352         int fd;
 353         for (fd = FAIL_FILENO + 1; fd < max_fd; fd++)
 354             if (close(fd) == -1 && errno != EBADF)
 355                 goto WhyCantJohnnyExec;
 356     }
 357 
 358     /* change to the new working directory */
 359     if (p->pdir != NULL && chdir(p->pdir) < 0)
 360         goto WhyCantJohnnyExec;
 361 
 362     if (fcntl(FAIL_FILENO, F_SETFD, FD_CLOEXEC) == -1)
 363         goto WhyCantJohnnyExec;
 364 
 365     JDK_execvpe(p->mode, p->argv[0], p->argv, p->envv);
 366 
 367  WhyCantJohnnyExec:
 368     /* We used to go to an awful lot of trouble to predict whether the
 369      * child would fail, but there is no reliable way to predict the
 370      * success of an operation without *trying* it, and there's no way
 371      * to try a chdir or exec in the parent.  Instead, all we need is a
 372      * way to communicate any failure back to the parent.  Easy; we just
 373      * send the errno back to the parent over a pipe in case of failure.
 374      * The tricky thing is, how do we communicate the *success* of exec?
 375      * We use FD_CLOEXEC together with the fact that a read() on a pipe
 376      * yields EOF when the write ends (we have two of them!) are closed.
 377      */
 378     {
 379         int errnum = errno;
 380         restartableWrite(FAIL_FILENO, &errnum, sizeof(errnum));
 381     }
 382     close(FAIL_FILENO);
 383     _exit(-1);
 384     return 0;  /* Suppress warning "no return value from function" */
 385 }
< prev index next >