32 #include "jni_util.h" 33 #include "io_util.h" 34 35 /* 36 * Platform-specific support for java.lang.Process 37 */ 38 #include <assert.h> 39 #include <stddef.h> 40 #include <stdlib.h> 41 #include <sys/types.h> 42 #include <ctype.h> 43 #include <sys/wait.h> 44 #include <signal.h> 45 #include <string.h> 46 #include <errno.h> 47 #include <dirent.h> 48 #include <unistd.h> 49 #include <fcntl.h> 50 #include <limits.h> 51 52 #ifdef __APPLE__ 53 #include <crt_externs.h> 54 #define environ (*_NSGetEnviron()) 55 #endif 56 57 /* 58 * There are 3 possible strategies we might use to "fork": 59 * 60 * - fork(2). Very portable and reliable but subject to 61 * failure due to overcommit (see the documentation on 62 * /proc/sys/vm/overcommit_memory in Linux proc(5)). 63 * This is the ancient problem of spurious failure whenever a large 64 * process starts a small subprocess. 65 * 66 * - vfork(). Using this is scary because all relevant man pages 67 * contain dire warnings, e.g. Linux vfork(2). But at least it's 68 * documented in the glibc docs and is standardized by XPG4. 69 * http://www.opengroup.org/onlinepubs/000095399/functions/vfork.html 70 * On Linux, one might think that vfork() would be implemented using 71 * the clone system call with flag CLONE_VFORK, but in fact vfork is 72 * a separate system call (which is a good sign, suggesting that 73 * vfork will continue to be supported at least on Linux). 74 * Another good sign is that glibc implements posix_spawn using 75 * vfork whenever possible. Note that we cannot use posix_spawn 76 * ourselves because there's no reliable way to close all inherited 77 * file descriptors. 78 * 79 * - clone() with flags CLONE_VM but not CLONE_THREAD. clone() is 80 * Linux-specific, but this ought to work - at least the glibc 81 * sources contain code to handle different combinations of CLONE_VM 82 * and CLONE_THREAD. However, when this was implemented, it 83 * appeared to fail on 32-bit i386 (but not 64-bit x86_64) Linux with 84 * the simple program 85 * Runtime.getRuntime().exec("/bin/true").waitFor(); 86 * with: 87 * # Internal Error (os_linux_x86.cpp:683), pid=19940, tid=2934639536 88 * # Error: pthread_getattr_np failed with errno = 3 (ESRCH) 89 * We believe this is a glibc bug, reported here: 90 * http://sources.redhat.com/bugzilla/show_bug.cgi?id=10311 91 * but the glibc maintainers closed it as WONTFIX. 92 * 93 * Based on the above analysis, we are currently using vfork() on 94 * Linux and fork() on other Unix systems, but the code to use clone() 95 * remains. 96 */ 97 98 #define START_CHILD_USE_CLONE 0 /* clone() currently disabled; see above. */ 99 100 #ifndef START_CHILD_USE_CLONE 101 #ifdef __linux__ 102 #define START_CHILD_USE_CLONE 1 103 #else 104 #define START_CHILD_USE_CLONE 0 105 #endif 106 #endif 107 108 /* By default, use vfork() on Linux. */ 109 #ifndef START_CHILD_USE_VFORK 110 #ifdef __linux__ 111 #define START_CHILD_USE_VFORK 1 112 #else 113 #define START_CHILD_USE_VFORK 0 114 #endif 115 #endif 116 117 #if START_CHILD_USE_CLONE 118 #include <sched.h> 119 #define START_CHILD_SYSTEM_CALL "clone" 120 #elif START_CHILD_USE_VFORK 121 #define START_CHILD_SYSTEM_CALL "vfork" 122 #else 123 #define START_CHILD_SYSTEM_CALL "fork" 124 #endif 125 126 #ifndef STDIN_FILENO 127 #define STDIN_FILENO 0 128 #endif 129 130 #ifndef STDOUT_FILENO 131 #define STDOUT_FILENO 1 132 #endif 133 134 #ifndef STDERR_FILENO 135 #define STDERR_FILENO 2 136 #endif 137 138 #ifndef SA_NOCLDSTOP 139 #define SA_NOCLDSTOP 0 140 #endif 141 142 #ifndef SA_RESTART 143 #define SA_RESTART 0 197 198 static void* 199 xmalloc(JNIEnv *env, size_t size) 200 { 201 void *p = malloc(size); 202 if (p == NULL) 203 JNU_ThrowOutOfMemoryError(env, NULL); 204 return p; 205 } 206 207 #define NEW(type, n) ((type *) xmalloc(env, (n) * sizeof(type))) 208 209 /** 210 * If PATH is not defined, the OS provides some default value. 211 * Unfortunately, there's no portable way to get this value. 212 * Fortunately, it's only needed if the child has PATH while we do not. 213 */ 214 static const char* 215 defaultPath(void) 216 { 217 #ifdef __solaris__ 218 /* These really are the Solaris defaults! */ 219 return (geteuid() == 0 || getuid() == 0) ? 220 "/usr/xpg4/bin:/usr/ccs/bin:/usr/bin:/opt/SUNWspro/bin:/usr/sbin" : 221 "/usr/xpg4/bin:/usr/ccs/bin:/usr/bin:/opt/SUNWspro/bin:"; 222 #else 223 return ":/bin:/usr/bin"; /* glibc */ 224 #endif 225 } 226 227 static const char* 228 effectivePath(void) 229 { 230 const char *s = getenv("PATH"); 231 return (s != NULL) ? s : defaultPath(); 232 } 233 234 static int 235 countOccurrences(const char *s, char c) 236 { 237 int count; 238 for (count = 0; *s != '\0'; s++) 239 count += (*s == c); 240 return count; 241 } 242 243 static const char * const * 244 splitPath(JNIEnv *env, const char *path) 254 for (q = p; (*q != ':') && (*q != '\0'); q++) 255 ; 256 if (q == p) /* empty PATH component => "." */ 257 pathv[i] = "./"; 258 else { 259 int addSlash = ((*(q - 1)) != '/'); 260 pathv[i] = NEW(char, q - p + addSlash + 1); 261 memcpy(pathv[i], p, q - p); 262 if (addSlash) 263 pathv[i][q - p] = '/'; 264 pathv[i][q - p + addSlash] = '\0'; 265 } 266 } 267 return (const char * const *) pathv; 268 } 269 270 /** 271 * Cached value of JVM's effective PATH. 272 * (We don't support putenv("PATH=...") in native code) 273 */ 274 static const char *parentPath; 275 276 /** 277 * Split, canonicalized version of parentPath 278 */ 279 static const char * const *parentPathv; 280 281 static jfieldID field_exitcode; 282 283 JNIEXPORT void JNICALL 284 Java_java_lang_UNIXProcess_initIDs(JNIEnv *env, jclass clazz) 285 { 286 field_exitcode = (*env)->GetFieldID(env, clazz, "exitcode", "I"); 287 288 parentPath = effectivePath(); 289 parentPathv = splitPath(env, parentPath); 290 291 setSIGCHLDHandler(env); 292 } 293 294 295 #ifndef WIFEXITED 296 #define WIFEXITED(status) (((status)&0xFF) == 0) 297 #endif 298 299 #ifndef WEXITSTATUS 300 #define WEXITSTATUS(status) (((status)>>8)&0xFF) 301 #endif 302 303 #ifndef WIFSIGNALED 304 #define WIFSIGNALED(status) (((status)&0xFF) > 0 && ((status)&0xFF00) == 0) 305 #endif 306 307 #ifndef WTERMSIG 308 #define WTERMSIG(status) ((status)&0x7F) 309 #endif 310 311 /* Block until a child process exits and return its exit code. 312 Note, can only be called once for any given pid. */ 313 JNIEXPORT jint JNICALL 314 Java_java_lang_UNIXProcess_waitForProcessExit(JNIEnv* env, 315 jobject junk, 316 jint pid) 317 { 318 /* We used to use waitid() on Solaris, waitpid() on Linux, but 319 * waitpid() is more standard, so use it on all POSIX platforms. */ 320 int status; 321 /* Wait for the child process to exit. This returns immediately if 322 the child has already exited. */ 323 while (waitpid(pid, &status, 0) < 0) { 324 switch (errno) { 325 case ECHILD: return 0; 326 case EINTR: break; 327 default: return -1; 328 } 329 } 330 331 if (WIFEXITED(status)) { 332 /* 333 * The child exited normally; get its exit code. 334 */ 335 return WEXITSTATUS(status); 336 } else if (WIFSIGNALED(status)) { 337 /* The child exited because of a signal. 338 * The best value to return is 0x80 + signal number, 339 * because that is what all Unix shells do, and because 340 * it allows callers to distinguish between process exit and 421 /* We use readdir64 instead of readdir to work around Solaris bug 422 * 6395699: /proc/self/fd fails to report file descriptors >= 1024 on Solaris 9 423 */ 424 while ((dirp = readdir64(dp)) != NULL) { 425 int fd; 426 if (isAsciiDigit(dirp->d_name[0]) && 427 (fd = strtol(dirp->d_name, NULL, 10)) >= from_fd + 2) 428 restartableClose(fd); 429 } 430 431 closedir(dp); 432 433 return 1; 434 } 435 436 static int 437 moveDescriptor(int fd_from, int fd_to) 438 { 439 if (fd_from != fd_to) { 440 if ((restartableDup2(fd_from, fd_to) == -1) || 441 (restartableClose(fd_from) == -1)) 442 return -1; 443 } 444 return 0; 445 } 446 447 static const char * 448 getBytes(JNIEnv *env, jbyteArray arr) 449 { 450 return arr == NULL ? NULL : 451 (const char*) (*env)->GetByteArrayElements(env, arr, NULL); 452 } 453 454 static void 455 releaseBytes(JNIEnv *env, jbyteArray arr, const char* parr) 456 { 457 if (parr != NULL) 458 (*env)->ReleaseByteArrayElements(env, arr, (jbyte*) parr, JNI_ABORT); 459 } 460 461 static void 462 initVectorFromBlock(const char**vector, const char* block, int count) 463 { 464 int i; 465 const char *p; 466 for (i = 0, p = block; i < count; i++) { 467 /* Invariant: p always points to the start of a C string. */ 468 vector[i] = p; 469 while (*(p++)); 470 } 471 vector[count] = NULL; 472 } 473 474 static void 475 throwIOException(JNIEnv *env, int errnum, const char *defaultDetail) 476 { 477 static const char * const format = "error=%d, %s"; 478 const char *detail = defaultDetail; 479 char *errmsg; 480 jstring s; 481 482 if (errnum != 0) { 483 const char *s = strerror(errnum); 484 if (strcmp(s, "Unknown error") != 0) 485 detail = s; 486 } 487 /* ASCII Decimal representation uses 2.4 times as many bits as binary. */ 488 errmsg = NEW(char, strlen(format) + strlen(detail) + 3 * sizeof(errnum)); 524 { 525 /* Use the extra word of space provided for us in argv by caller. */ 526 const char *argv0 = argv[0]; 527 const char *const *end = argv; 528 while (*end != NULL) 529 ++end; 530 memmove(argv+2, argv+1, (end-argv) * sizeof (*end)); 531 argv[0] = "/bin/sh"; 532 argv[1] = file; 533 execve(argv[0], (char **) argv, (char **) envp); 534 /* Can't even exec /bin/sh? Big trouble, but let's soldier on... */ 535 memmove(argv+1, argv+2, (end-argv) * sizeof (*end)); 536 argv[0] = argv0; 537 } 538 539 /** 540 * Like execve(2), except that in case of ENOEXEC, FILE is assumed to 541 * be a shell script and the system default shell is invoked to run it. 542 */ 543 static void 544 execve_with_shell_fallback(const char *file, 545 const char *argv[], 546 const char *const envp[]) 547 { 548 #if START_CHILD_USE_CLONE || START_CHILD_USE_VFORK 549 /* shared address space; be very careful. */ 550 execve(file, (char **) argv, (char **) envp); 551 if (errno == ENOEXEC) 552 execve_as_traditional_shell_script(file, argv, envp); 553 #else 554 /* unshared address space; we can mutate environ. */ 555 environ = (char **) envp; 556 execvp(file, (char **) argv); 557 #endif 558 } 559 560 /** 561 * 'execvpe' should have been included in the Unix standards, 562 * and is a GNU extension in glibc 2.10. 563 * 564 * JDK_execvpe is identical to execvp, except that the child environment is 565 * specified via the 3rd argument instead of being inherited from environ. 566 */ 567 static void 568 JDK_execvpe(const char *file, 569 const char *argv[], 570 const char *const envp[]) 571 { 572 if (envp == NULL || (char **) envp == environ) { 573 execvp(file, (char **) argv); 574 return; 575 } 576 577 if (*file == '\0') { 578 errno = ENOENT; 579 return; 580 } 581 582 if (strchr(file, '/') != NULL) { 583 execve_with_shell_fallback(file, argv, envp); 584 } else { 585 /* We must search PATH (parent's, not child's) */ 586 char expanded_file[PATH_MAX]; 587 int filelen = strlen(file); 588 int sticky_errno = 0; 589 const char * const * dirs; 590 for (dirs = parentPathv; *dirs; dirs++) { 591 const char * dir = *dirs; 592 int dirlen = strlen(dir); 593 if (filelen + dirlen + 1 >= PATH_MAX) { 594 errno = ENAMETOOLONG; 595 continue; 596 } 597 memcpy(expanded_file, dir, dirlen); 598 memcpy(expanded_file + dirlen, file, filelen); 599 expanded_file[dirlen + filelen] = '\0'; 600 execve_with_shell_fallback(expanded_file, argv, envp); 601 /* There are 3 responses to various classes of errno: 602 * return immediately, continue (especially for ENOENT), 603 * or continue with "sticky" errno. 604 * 605 * From exec(3): 606 * 607 * If permission is denied for a file (the attempted 608 * execve returned EACCES), these functions will continue 609 * searching the rest of the search path. If no other 610 * file is found, however, they will return with the 611 * global variable errno set to EACCES. 612 */ 613 switch (errno) { 614 case EACCES: 615 sticky_errno = errno; 616 /* FALLTHRU */ 617 case ENOENT: 618 case ENOTDIR: 619 #ifdef ELOOP 620 case ELOOP: 622 #ifdef ESTALE 623 case ESTALE: 624 #endif 625 #ifdef ENODEV 626 case ENODEV: 627 #endif 628 #ifdef ETIMEDOUT 629 case ETIMEDOUT: 630 #endif 631 break; /* Try other directories in PATH */ 632 default: 633 return; 634 } 635 } 636 if (sticky_errno != 0) 637 errno = sticky_errno; 638 } 639 } 640 641 /* 642 * Reads nbyte bytes from file descriptor fd into buf, 643 * The read operation is retried in case of EINTR or partial reads. 644 * 645 * Returns number of bytes read (normally nbyte, but may be less in 646 * case of EOF). In case of read errors, returns -1 and sets errno. 647 */ 648 static ssize_t 649 readFully(int fd, void *buf, size_t nbyte) 650 { 651 ssize_t remaining = nbyte; 652 for (;;) { 653 ssize_t n = read(fd, buf, remaining); 654 if (n == 0) { 655 return nbyte - remaining; 656 } else if (n > 0) { 657 remaining -= n; 658 if (remaining <= 0) 659 return nbyte; 660 /* We were interrupted in the middle of reading the bytes. 661 * Unlikely, but possible. */ 662 buf = (void *) (((char *)buf) + n); 663 } else if (errno == EINTR) { 664 /* Strange signals like SIGJVM1 are possible at any time. 665 * See http://www.dreamsongs.com/WorseIsBetter.html */ 666 } else { 667 return -1; 668 } 669 } 670 } 671 672 typedef struct _ChildStuff 673 { 674 int in[2]; 675 int out[2]; 676 int err[2]; 677 int fail[2]; 678 int fds[3]; 679 const char **argv; 680 const char **envv; 681 const char *pdir; 682 jboolean redirectErrorStream; 683 #if START_CHILD_USE_CLONE 684 void *clone_stack; 685 #endif 686 } ChildStuff; 687 688 static void 689 copyPipe(int from[2], int to[2]) 690 { 691 to[0] = from[0]; 692 to[1] = from[1]; 693 } 694 695 /** 696 * Child process after a successful fork() or clone(). 697 * This function must not return, and must be prepared for either all 698 * of its address space to be shared with its parent, or to be a copy. 699 * It must not modify global variables such as "environ". 700 */ 701 static int 702 childProcess(void *arg) 703 { 704 const ChildStuff* p = (const ChildStuff*) arg; 705 706 /* Close the parent sides of the pipes. 707 Closing pipe fds here is redundant, since closeDescriptors() 708 would do it anyways, but a little paranoia is a good thing. */ 709 if ((closeSafely(p->in[1]) == -1) || 710 (closeSafely(p->out[0]) == -1) || 711 (closeSafely(p->err[0]) == -1) || 712 (closeSafely(p->fail[0]) == -1)) 713 goto WhyCantJohnnyExec; 714 715 /* Give the child sides of the pipes the right fileno's. */ 716 /* Note: it is possible for in[0] == 0 */ 717 if ((moveDescriptor(p->in[0] != -1 ? p->in[0] : p->fds[0], 718 STDIN_FILENO) == -1) || 719 (moveDescriptor(p->out[1]!= -1 ? p->out[1] : p->fds[1], 720 STDOUT_FILENO) == -1)) 721 goto WhyCantJohnnyExec; 722 723 if (p->redirectErrorStream) { 724 if ((closeSafely(p->err[1]) == -1) || 725 (restartableDup2(STDOUT_FILENO, STDERR_FILENO) == -1)) 726 goto WhyCantJohnnyExec; 727 } else { 728 if (moveDescriptor(p->err[1] != -1 ? p->err[1] : p->fds[2], 729 STDERR_FILENO) == -1) 730 goto WhyCantJohnnyExec; 731 } 732 733 if (moveDescriptor(p->fail[1], FAIL_FILENO) == -1) 734 goto WhyCantJohnnyExec; 735 736 /* close everything */ 737 if (closeDescriptors() == 0) { /* failed, close the old way */ 738 int max_fd = (int)sysconf(_SC_OPEN_MAX); 739 int fd; 740 for (fd = FAIL_FILENO + 1; fd < max_fd; fd++) 741 if (restartableClose(fd) == -1 && errno != EBADF) 742 goto WhyCantJohnnyExec; 743 } 744 745 /* change to the new working directory */ 746 if (p->pdir != NULL && chdir(p->pdir) < 0) 747 goto WhyCantJohnnyExec; 748 749 if (fcntl(FAIL_FILENO, F_SETFD, FD_CLOEXEC) == -1) 750 goto WhyCantJohnnyExec; 751 752 JDK_execvpe(p->argv[0], p->argv, p->envv); 753 754 WhyCantJohnnyExec: 755 /* We used to go to an awful lot of trouble to predict whether the 756 * child would fail, but there is no reliable way to predict the 757 * success of an operation without *trying* it, and there's no way 758 * to try a chdir or exec in the parent. Instead, all we need is a 759 * way to communicate any failure back to the parent. Easy; we just 760 * send the errno back to the parent over a pipe in case of failure. 761 * The tricky thing is, how do we communicate the *success* of exec? 762 * We use FD_CLOEXEC together with the fact that a read() on a pipe 763 * yields EOF when the write ends (we have two of them!) are closed. 764 */ 765 { 766 int errnum = errno; 767 restartableWrite(FAIL_FILENO, &errnum, sizeof(errnum)); 768 } 769 restartableClose(FAIL_FILENO); 770 _exit(-1); 771 return 0; /* Suppress warning "no return value from function" */ 772 } 773 774 /** 775 * Start a child process running function childProcess. 776 * This function only returns in the parent. 777 * We are unusually paranoid; use of clone/vfork is 778 * especially likely to tickle gcc/glibc bugs. 779 */ 780 #ifdef __attribute_noinline__ /* See: sys/cdefs.h */ 781 __attribute_noinline__ 782 #endif 783 static pid_t 784 startChild(ChildStuff *c) { 785 #if START_CHILD_USE_CLONE 786 #define START_CHILD_CLONE_STACK_SIZE (64 * 1024) 787 /* 788 * See clone(2). 789 * Instead of worrying about which direction the stack grows, just 790 * allocate twice as much and start the stack in the middle. 791 */ 792 if ((c->clone_stack = malloc(2 * START_CHILD_CLONE_STACK_SIZE)) == NULL) 793 /* errno will be set to ENOMEM */ 794 return -1; 795 return clone(childProcess, 796 c->clone_stack + START_CHILD_CLONE_STACK_SIZE, 797 CLONE_VFORK | CLONE_VM | SIGCHLD, c); 798 #else 799 #if START_CHILD_USE_VFORK 800 /* 801 * We separate the call to vfork into a separate function to make 802 * very sure to keep stack of child from corrupting stack of parent, 803 * as suggested by the scary gcc warning: 804 * warning: variable 'foo' might be clobbered by 'longjmp' or 'vfork' 805 */ 806 volatile pid_t resultPid = vfork(); 807 #else 808 /* 809 * From Solaris fork(2): In Solaris 10, a call to fork() is 810 * identical to a call to fork1(); only the calling thread is 811 * replicated in the child process. This is the POSIX-specified 812 * behavior for fork(). 813 */ 814 pid_t resultPid = fork(); 815 #endif 816 if (resultPid == 0) 817 childProcess(c); 818 assert(resultPid != 0); /* childProcess never returns */ 819 return resultPid; 820 #endif /* ! START_CHILD_USE_CLONE */ 821 } 822 823 JNIEXPORT jint JNICALL 824 Java_java_lang_UNIXProcess_forkAndExec(JNIEnv *env, 825 jobject process, 826 jbyteArray prog, 827 jbyteArray argBlock, jint argc, 828 jbyteArray envBlock, jint envc, 829 jbyteArray dir, 830 jintArray std_fds, 831 jboolean redirectErrorStream) 832 { 833 int errnum; 834 int resultPid = -1; 835 int in[2], out[2], err[2], fail[2]; 836 jint *fds = NULL; 837 const char *pprog = NULL; 838 const char *pargBlock = NULL; 839 const char *penvBlock = NULL; 840 ChildStuff *c; 841 842 in[0] = in[1] = out[0] = out[1] = err[0] = err[1] = fail[0] = fail[1] = -1; 843 844 if ((c = NEW(ChildStuff, 1)) == NULL) return -1; 845 c->argv = NULL; 846 c->envv = NULL; 847 c->pdir = NULL; 848 #if START_CHILD_USE_CLONE 849 c->clone_stack = NULL; 850 #endif 851 852 /* Convert prog + argBlock into a char ** argv. 853 * Add one word room for expansion of argv for use by 854 * execve_as_traditional_shell_script. 855 */ 856 assert(prog != NULL && argBlock != NULL); 857 if ((pprog = getBytes(env, prog)) == NULL) goto Catch; 858 if ((pargBlock = getBytes(env, argBlock)) == NULL) goto Catch; 859 if ((c->argv = NEW(const char *, argc + 3)) == NULL) goto Catch; 860 c->argv[0] = pprog; 861 initVectorFromBlock(c->argv+1, pargBlock, argc); 862 863 if (envBlock != NULL) { 864 /* Convert envBlock into a char ** envv */ 865 if ((penvBlock = getBytes(env, envBlock)) == NULL) goto Catch; 866 if ((c->envv = NEW(const char *, envc + 1)) == NULL) goto Catch; 867 initVectorFromBlock(c->envv, penvBlock, envc); 868 } 869 870 if (dir != NULL) { 871 if ((c->pdir = getBytes(env, dir)) == NULL) goto Catch; 872 } 873 874 assert(std_fds != NULL); 875 fds = (*env)->GetIntArrayElements(env, std_fds, NULL); 876 if (fds == NULL) goto Catch; 877 878 if ((fds[0] == -1 && pipe(in) < 0) || 879 (fds[1] == -1 && pipe(out) < 0) || 880 (fds[2] == -1 && pipe(err) < 0) || 881 (pipe(fail) < 0)) { 882 throwIOException(env, errno, "Bad file descriptor"); 883 goto Catch; 884 } 885 c->fds[0] = fds[0]; 886 c->fds[1] = fds[1]; 887 c->fds[2] = fds[2]; 888 889 copyPipe(in, c->in); 890 copyPipe(out, c->out); 891 copyPipe(err, c->err); 892 copyPipe(fail, c->fail); 893 894 c->redirectErrorStream = redirectErrorStream; 895 896 resultPid = startChild(c); 897 assert(resultPid != 0); 898 899 if (resultPid < 0) { 900 throwIOException(env, errno, START_CHILD_SYSTEM_CALL " failed"); 901 goto Catch; 902 } 903 904 restartableClose(fail[1]); fail[1] = -1; /* See: WhyCantJohnnyExec */ 905 906 switch (readFully(fail[0], &errnum, sizeof(errnum))) { 907 case 0: break; /* Exec succeeded */ 908 case sizeof(errnum): 909 waitpid(resultPid, NULL, 0); 910 throwIOException(env, errnum, "Exec failed"); 911 goto Catch; 912 default: 913 throwIOException(env, errno, "Read failed"); 914 goto Catch; 915 } 916 917 fds[0] = (in [1] != -1) ? in [1] : -1; 918 fds[1] = (out[0] != -1) ? out[0] : -1; 919 fds[2] = (err[0] != -1) ? err[0] : -1; 920 921 Finally: 922 #if START_CHILD_USE_CLONE 923 free(c->clone_stack); 924 #endif 925 926 /* Always clean up the child's side of the pipes */ 927 closeSafely(in [0]); 928 closeSafely(out[1]); 929 closeSafely(err[1]); 930 931 /* Always clean up fail descriptors */ 932 closeSafely(fail[0]); 933 closeSafely(fail[1]); 934 935 releaseBytes(env, prog, pprog); 936 releaseBytes(env, argBlock, pargBlock); 937 releaseBytes(env, envBlock, penvBlock); 938 releaseBytes(env, dir, c->pdir); 939 940 free(c->argv); 941 free(c->envv); 942 free(c); 943 944 if (fds != NULL) 945 (*env)->ReleaseIntArrayElements(env, std_fds, fds, 0); 946 947 return resultPid; 948 949 Catch: 950 /* Clean up the parent's side of the pipes in case of failure only */ 951 closeSafely(in [1]); 952 closeSafely(out[0]); 953 closeSafely(err[0]); 954 goto Finally; 955 } 956 957 JNIEXPORT void JNICALL 958 Java_java_lang_UNIXProcess_destroyProcess(JNIEnv *env, 959 jobject junk, 960 jint pid, 961 jboolean force) 962 { 963 int sig = (force == JNI_TRUE) ? SIGKILL : SIGTERM; 964 kill(pid, sig); 965 } | 32 #include "jni_util.h" 33 #include "io_util.h" 34 35 /* 36 * Platform-specific support for java.lang.Process 37 */ 38 #include <assert.h> 39 #include <stddef.h> 40 #include <stdlib.h> 41 #include <sys/types.h> 42 #include <ctype.h> 43 #include <sys/wait.h> 44 #include <signal.h> 45 #include <string.h> 46 #include <errno.h> 47 #include <dirent.h> 48 #include <unistd.h> 49 #include <fcntl.h> 50 #include <limits.h> 51 52 #if defined(__solaris__) || defined(__APPLE__) 53 #include <spawn.h> 54 #endif 55 56 #include "unixprocess_md.h" 57 58 #ifdef __APPLE__ 59 #include <crt_externs.h> 60 #define environ (*_NSGetEnviron()) 61 #endif 62 63 /* 64 * There are 4 possible strategies we might use to "fork": 65 * 66 * - fork(2). Very portable and reliable but subject to 67 * failure due to overcommit (see the documentation on 68 * /proc/sys/vm/overcommit_memory in Linux proc(5)). 69 * This is the ancient problem of spurious failure whenever a large 70 * process starts a small subprocess. 71 * 72 * - vfork(). Using this is scary because all relevant man pages 73 * contain dire warnings, e.g. Linux vfork(2). But at least it's 74 * documented in the glibc docs and is standardized by XPG4. 75 * http://www.opengroup.org/onlinepubs/000095399/functions/vfork.html 76 * On Linux, one might think that vfork() would be implemented using 77 * the clone system call with flag CLONE_VFORK, but in fact vfork is 78 * a separate system call (which is a good sign, suggesting that 79 * vfork will continue to be supported at least on Linux). 80 * Another good sign is that glibc implements posix_spawn using 81 * vfork whenever possible. Note that we cannot use posix_spawn 82 * ourselves because there's no reliable way to close all inherited 83 * file descriptors. 84 * 85 * - clone() with flags CLONE_VM but not CLONE_THREAD. clone() is 86 * Linux-specific, but this ought to work - at least the glibc 87 * sources contain code to handle different combinations of CLONE_VM 88 * and CLONE_THREAD. However, when this was implemented, it 89 * appeared to fail on 32-bit i386 (but not 64-bit x86_64) Linux with 90 * the simple program 91 * Runtime.getRuntime().exec("/bin/true").waitFor(); 92 * with: 93 * # Internal Error (os_linux_x86.cpp:683), pid=19940, tid=2934639536 94 * # Error: pthread_getattr_np failed with errno = 3 (ESRCH) 95 * We believe this is a glibc bug, reported here: 96 * http://sources.redhat.com/bugzilla/show_bug.cgi?id=10311 97 * but the glibc maintainers closed it as WONTFIX. 98 * 99 * - posix_spawn(). While posix_spawn() is a fairly elaborate and 100 * complicated system call, it can't quite do everything that the old 101 * fork()/exec() combination can do, so the only feasible way to do 102 * this, is to use posix_spawn to launch a new helper executable 103 * "jprochelper", which in turn execs the target (after cleaning 104 * up file-descriptors etc.) The end result is the same as before, 105 * a child process linked to the parent in the same way, but it 106 * avoids the problem of duplicating the parent (VM) process 107 * address space temporarily, before launching the target command. 108 * 109 * Based on the above analysis, we are currently using vfork() on 110 * Linux and spawn() on other Unix systems, but the code to use clone() 111 * and fork() remains. 112 */ 113 114 #ifdef __linux__ 115 #include <sched.h> 116 #endif 117 118 #ifndef STDIN_FILENO 119 #define STDIN_FILENO 0 120 #endif 121 122 #ifndef STDOUT_FILENO 123 #define STDOUT_FILENO 1 124 #endif 125 126 #ifndef STDERR_FILENO 127 #define STDERR_FILENO 2 128 #endif 129 130 #ifndef SA_NOCLDSTOP 131 #define SA_NOCLDSTOP 0 132 #endif 133 134 #ifndef SA_RESTART 135 #define SA_RESTART 0 189 190 static void* 191 xmalloc(JNIEnv *env, size_t size) 192 { 193 void *p = malloc(size); 194 if (p == NULL) 195 JNU_ThrowOutOfMemoryError(env, NULL); 196 return p; 197 } 198 199 #define NEW(type, n) ((type *) xmalloc(env, (n) * sizeof(type))) 200 201 /** 202 * If PATH is not defined, the OS provides some default value. 203 * Unfortunately, there's no portable way to get this value. 204 * Fortunately, it's only needed if the child has PATH while we do not. 205 */ 206 static const char* 207 defaultPath(void) 208 { 209 #ifdef _CS_PATH 210 char *pathbuf; 211 size_t n; 212 n = confstr(_CS_PATH,NULL,(size_t) 0); 213 pathbuf = malloc(n); 214 if (pathbuf == NULL) 215 abort(); 216 confstr(_CS_PATH, pathbuf, n); 217 return pathbuf; 218 #else 219 #ifdef __solaris__ 220 /* These really are the Solaris defaults! */ 221 return (geteuid() == 0 || getuid() == 0) ? 222 "/usr/xpg4/bin:/usr/ccs/bin:/usr/bin:/opt/SUNWspro/bin:/usr/sbin" : 223 "/usr/xpg4/bin:/usr/ccs/bin:/usr/bin:/opt/SUNWspro/bin:"; 224 #else 225 return ":/bin:/usr/bin"; /* glibc */ 226 #endif 227 #endif 228 } 229 230 static const char* 231 effectivePath(void) 232 { 233 const char *s = getenv("PATH"); 234 return (s != NULL) ? s : defaultPath(); 235 } 236 237 static int 238 countOccurrences(const char *s, char c) 239 { 240 int count; 241 for (count = 0; *s != '\0'; s++) 242 count += (*s == c); 243 return count; 244 } 245 246 static const char * const * 247 splitPath(JNIEnv *env, const char *path) 257 for (q = p; (*q != ':') && (*q != '\0'); q++) 258 ; 259 if (q == p) /* empty PATH component => "." */ 260 pathv[i] = "./"; 261 else { 262 int addSlash = ((*(q - 1)) != '/'); 263 pathv[i] = NEW(char, q - p + addSlash + 1); 264 memcpy(pathv[i], p, q - p); 265 if (addSlash) 266 pathv[i][q - p] = '/'; 267 pathv[i][q - p + addSlash] = '\0'; 268 } 269 } 270 return (const char * const *) pathv; 271 } 272 273 /** 274 * Cached value of JVM's effective PATH. 275 * (We don't support putenv("PATH=...") in native code) 276 */ 277 const char *xx_parentPath; 278 279 /** 280 * Split, canonicalized version of xx_parentPath 281 */ 282 const char * const *xx_parentPathv; 283 284 static jfieldID field_exitcode; 285 static jfieldID helperfield; 286 287 JNIEXPORT void JNICALL 288 Java_java_lang_UNIXProcess_initIDs(JNIEnv *env, jclass clazz) 289 { 290 field_exitcode = (*env)->GetFieldID(env, clazz, "exitcode", "I"); 291 helperfield = (*env)->GetStaticFieldID(env, clazz, 292 "helperpath", "Ljava/lang/String;"); 293 xx_parentPath = effectivePath(); 294 xx_parentPathv = splitPath(env, xx_parentPath); 295 296 setSIGCHLDHandler(env); 297 } 298 299 300 #ifndef WIFEXITED 301 #define WIFEXITED(status) (((status)&0xFF) == 0) 302 #endif 303 304 #ifndef WEXITSTATUS 305 #define WEXITSTATUS(status) (((status)>>8)&0xFF) 306 #endif 307 308 #ifndef WIFSIGNALED 309 #define WIFSIGNALED(status) (((status)&0xFF) > 0 && ((status)&0xFF00) == 0) 310 #endif 311 312 #ifndef WTERMSIG 313 #define WTERMSIG(status) ((status)&0x7F) 314 #endif 315 316 /* Block until a child process exits and return its exit code. 317 Note, can only be called once for any given pid. */ 318 JNIEXPORT jint JNICALL 319 Java_java_lang_UNIXProcess_waitForProcessExit(JNIEnv* env, 320 jobject junk, 321 jint pid) 322 { 323 /* We used to use waitid() on Solaris, waitpid() on Linux, but 324 * waitpid() is more standard, so use it on all POSIX platforms. */ 325 int status; 326 327 /* Wait for the child process to exit. This returns immediately if 328 the child has already exited. */ 329 while (waitpid(pid, &status, 0) < 0) { 330 switch (errno) { 331 case ECHILD: return 0; 332 case EINTR: break; 333 default: return -1; 334 } 335 } 336 337 if (WIFEXITED(status)) { 338 /* 339 * The child exited normally; get its exit code. 340 */ 341 return WEXITSTATUS(status); 342 } else if (WIFSIGNALED(status)) { 343 /* The child exited because of a signal. 344 * The best value to return is 0x80 + signal number, 345 * because that is what all Unix shells do, and because 346 * it allows callers to distinguish between process exit and 427 /* We use readdir64 instead of readdir to work around Solaris bug 428 * 6395699: /proc/self/fd fails to report file descriptors >= 1024 on Solaris 9 429 */ 430 while ((dirp = readdir64(dp)) != NULL) { 431 int fd; 432 if (isAsciiDigit(dirp->d_name[0]) && 433 (fd = strtol(dirp->d_name, NULL, 10)) >= from_fd + 2) 434 restartableClose(fd); 435 } 436 437 closedir(dp); 438 439 return 1; 440 } 441 442 static int 443 moveDescriptor(int fd_from, int fd_to) 444 { 445 if (fd_from != fd_to) { 446 if ((restartableDup2(fd_from, fd_to) == -1) || 447 (restartableClose(fd_from) == -1)) { 448 return -1; 449 } 450 } 451 return 0; 452 } 453 454 static const char * 455 getBytes(JNIEnv *env, jbyteArray arr) 456 { 457 return arr == NULL ? NULL : 458 (const char*) (*env)->GetByteArrayElements(env, arr, NULL); 459 } 460 461 static void 462 releaseBytes(JNIEnv *env, jbyteArray arr, const char* parr) 463 { 464 if (parr != NULL) 465 (*env)->ReleaseByteArrayElements(env, arr, (jbyte*) parr, JNI_ABORT); 466 } 467 468 void 469 xx_initVectorFromBlock(const char**vector, const char* block, int count) 470 { 471 int i; 472 const char *p; 473 474 for (i = 0, p = block; i < count; i++) { 475 /* Invariant: p always points to the start of a C string. */ 476 vector[i] = p; 477 478 while (*(p++)); 479 } 480 vector[count] = NULL; 481 } 482 483 static void 484 throwIOException(JNIEnv *env, int errnum, const char *defaultDetail) 485 { 486 static const char * const format = "error=%d, %s"; 487 const char *detail = defaultDetail; 488 char *errmsg; 489 jstring s; 490 491 if (errnum != 0) { 492 const char *s = strerror(errnum); 493 if (strcmp(s, "Unknown error") != 0) 494 detail = s; 495 } 496 /* ASCII Decimal representation uses 2.4 times as many bits as binary. */ 497 errmsg = NEW(char, strlen(format) + strlen(detail) + 3 * sizeof(errnum)); 533 { 534 /* Use the extra word of space provided for us in argv by caller. */ 535 const char *argv0 = argv[0]; 536 const char *const *end = argv; 537 while (*end != NULL) 538 ++end; 539 memmove(argv+2, argv+1, (end-argv) * sizeof (*end)); 540 argv[0] = "/bin/sh"; 541 argv[1] = file; 542 execve(argv[0], (char **) argv, (char **) envp); 543 /* Can't even exec /bin/sh? Big trouble, but let's soldier on... */ 544 memmove(argv+1, argv+2, (end-argv) * sizeof (*end)); 545 argv[0] = argv0; 546 } 547 548 /** 549 * Like execve(2), except that in case of ENOEXEC, FILE is assumed to 550 * be a shell script and the system default shell is invoked to run it. 551 */ 552 static void 553 execve_with_shell_fallback(int mode, const char *file, 554 const char *argv[], 555 const char *const envp[]) 556 { 557 if (mode == MODE_CLONE || mode == MODE_VFORK) { 558 /* shared address space; be very careful. */ 559 execve(file, (char **) argv, (char **) envp); 560 if (errno == ENOEXEC) 561 execve_as_traditional_shell_script(file, argv, envp); 562 } else { 563 /* unshared address space; we can mutate environ. */ 564 environ = (char **) envp; 565 execvp(file, (char **) argv); 566 } 567 } 568 569 /** 570 * 'execvpe' should have been included in the Unix standards, 571 * and is a GNU extension in glibc 2.10. 572 * 573 * JDK_execvpe is identical to execvp, except that the child environment is 574 * specified via the 3rd argument instead of being inherited from environ. 575 */ 576 static void 577 JDK_execvpe(int mode, const char *file, 578 const char *argv[], 579 const char *const envp[]) 580 { 581 if (envp == NULL || (char **) envp == environ) { 582 execvp(file, (char **) argv); 583 return; 584 } 585 586 if (*file == '\0') { 587 errno = ENOENT; 588 return; 589 } 590 591 if (strchr(file, '/') != NULL) { 592 execve_with_shell_fallback(mode, file, argv, envp); 593 } else { 594 /* We must search PATH (parent's, not child's) */ 595 char expanded_file[PATH_MAX]; 596 int filelen = strlen(file); 597 int sticky_errno = 0; 598 const char * const * dirs; 599 600 for (dirs = xx_parentPathv; *dirs; dirs++) { 601 const char * dir = *dirs; 602 int dirlen = strlen(dir); 603 if (filelen + dirlen + 1 >= PATH_MAX) { 604 errno = ENAMETOOLONG; 605 continue; 606 } 607 memcpy(expanded_file, dir, dirlen); 608 memcpy(expanded_file + dirlen, file, filelen); 609 expanded_file[dirlen + filelen] = '\0'; 610 execve_with_shell_fallback(mode, expanded_file, argv, envp); 611 /* There are 3 responses to various classes of errno: 612 * return immediately, continue (especially for ENOENT), 613 * or continue with "sticky" errno. 614 * 615 * From exec(3): 616 * 617 * If permission is denied for a file (the attempted 618 * execve returned EACCES), these functions will continue 619 * searching the rest of the search path. If no other 620 * file is found, however, they will return with the 621 * global variable errno set to EACCES. 622 */ 623 switch (errno) { 624 case EACCES: 625 sticky_errno = errno; 626 /* FALLTHRU */ 627 case ENOENT: 628 case ENOTDIR: 629 #ifdef ELOOP 630 case ELOOP: 632 #ifdef ESTALE 633 case ESTALE: 634 #endif 635 #ifdef ENODEV 636 case ENODEV: 637 #endif 638 #ifdef ETIMEDOUT 639 case ETIMEDOUT: 640 #endif 641 break; /* Try other directories in PATH */ 642 default: 643 return; 644 } 645 } 646 if (sticky_errno != 0) 647 errno = sticky_errno; 648 } 649 } 650 651 /* 652 * Reads nbyte bytes from file descriptor fd into buf. 653 * The read operation is retried in case of EINTR or partial reads. 654 * 655 * Returns number of bytes read (normally nbyte, but may be less in 656 * case of EOF). In case of read errors, returns -1 and sets errno. 657 */ 658 ssize_t 659 xx_readFully(int fd, void *buf, size_t nbyte) 660 { 661 ssize_t remaining = nbyte; 662 for (;;) { 663 ssize_t n = read(fd, buf, remaining); 664 if (n == 0) { 665 return nbyte - remaining; 666 } else if (n > 0) { 667 remaining -= n; 668 if (remaining <= 0) 669 return nbyte; 670 /* We were interrupted in the middle of reading the bytes. 671 * Unlikely, but possible. */ 672 buf = (void *) (((char *)buf) + n); 673 } else if (errno == EINTR) { 674 /* Strange signals like SIGJVM1 are possible at any time. 675 * See http://www.dreamsongs.com/WorseIsBetter.html */ 676 } else { 677 return -1; 678 } 679 } 680 } 681 682 static void 683 copyPipe(int from[2], int to[2]) 684 { 685 to[0] = from[0]; 686 to[1] = from[1]; 687 } 688 689 /** 690 * Child process after a successful v/fork(), clone() or posix_spawn(). 691 * This function must not return, and must be prepared for either all 692 * of its address space to be shared with its parent, or to be a copy. 693 * It must not modify global variables such as "environ". 694 */ 695 int 696 xx_childProcess(void *arg) 697 { 698 ChildStuff* p = (ChildStuff*) arg; 699 700 /* Close the parent sides of the pipes. 701 Closing pipe fds here is redundant, since closeDescriptors() 702 would do it anyways, but a little paranoia is a good thing. 703 We close both sides of the childenv pipe since in spawn 704 mode we are finished with it now, and it's not used at all 705 in the other modes */ 706 if ((closeSafely(p->in[1]) == -1) || 707 (closeSafely(p->out[0]) == -1) || 708 (closeSafely(p->err[0]) == -1) || 709 (closeSafely(p->childenv[0]) == -1) || 710 (closeSafely(p->childenv[1]) == -1) || 711 (closeSafely(p->fail[0]) == -1)) 712 goto WhyCantJohnnyExec; 713 714 p->in[1] = -1; p->out[0] = -1; p->err[0] = -1; 715 p->childenv[0] = -1; p->childenv[1] = -1; p->fail[0] = -1; 716 717 /* Give the child sides of the pipes the right fileno's. */ 718 /* Note: it is possible for in[0] == 0 */ 719 if ((moveDescriptor(p->in[0] != -1 ? p->in[0] : p->fds[0], 720 STDIN_FILENO) == -1) || 721 (moveDescriptor(p->out[1]!= -1 ? p->out[1] : p->fds[1], 722 STDOUT_FILENO) == -1)) { 723 goto WhyCantJohnnyExec; 724 } 725 726 if (p->redirectErrorStream) { 727 if ((closeSafely(p->err[1]) == -1) || 728 (restartableDup2(STDOUT_FILENO, STDERR_FILENO) == -1)) 729 goto WhyCantJohnnyExec; 730 } else { 731 if (moveDescriptor(p->err[1] != -1 ? p->err[1] : p->fds[2], 732 STDERR_FILENO) == -1) 733 goto WhyCantJohnnyExec; 734 } 735 736 if (moveDescriptor(p->fail[1], FAIL_FILENO) == -1) 737 goto WhyCantJohnnyExec; 738 739 /* close everything */ 740 if (closeDescriptors() == 0) { /* failed, close the old way */ 741 int max_fd = (int)sysconf(_SC_OPEN_MAX); 742 int fd; 743 for (fd = FAIL_FILENO + 1; fd < max_fd; fd++) 744 if (restartableClose(fd) == -1 && errno != EBADF) 745 goto WhyCantJohnnyExec; 746 } 747 748 /* change to the new working directory */ 749 if (p->pdir != NULL && chdir(p->pdir) < 0) 750 goto WhyCantJohnnyExec; 751 752 if (fcntl(FAIL_FILENO, F_SETFD, FD_CLOEXEC) == -1) 753 goto WhyCantJohnnyExec; 754 755 JDK_execvpe(p->mode, p->argv[0], p->argv, p->envv); 756 757 WhyCantJohnnyExec: 758 /* We used to go to an awful lot of trouble to predict whether the 759 * child would fail, but there is no reliable way to predict the 760 * success of an operation without *trying* it, and there's no way 761 * to try a chdir or exec in the parent. Instead, all we need is a 762 * way to communicate any failure back to the parent. Easy; we just 763 * send the errno back to the parent over a pipe in case of failure. 764 * The tricky thing is, how do we communicate the *success* of exec? 765 * We use FD_CLOEXEC together with the fact that a read() on a pipe 766 * yields EOF when the write ends (we have two of them!) are closed. 767 */ 768 { 769 int errnum = errno; 770 restartableWrite(FAIL_FILENO, &errnum, sizeof(errnum)); 771 } 772 restartableClose(FAIL_FILENO); 773 _exit(-1); 774 return 0; /* Suppress warning "no return value from function" */ 775 } 776 777 /* arg is an array of pointers to 0 terminated strings. array is terminated 778 * by a null element. 779 * 780 * *nelems and *nbytes receive the number of elements of array (incl 0) 781 * and total number of bytes (incl. 0) 782 * Note. An empty array will have one null element 783 * But if arg is null, then *nelems set to 0, and *nbytes to 0 784 */ 785 static void arraysize (const char * const *arg, int *nelems, int *nbytes) 786 { 787 int i, bytes, count; 788 const char * const *a = arg; 789 char *p; 790 int *q; 791 if (arg == 0) { 792 *nelems = 0; 793 *nbytes = 0; 794 return; 795 } 796 /* count the array elements and number of bytes */ 797 for (count=0, bytes=0; *a != 0; count++, a++) { 798 bytes += strlen (*a)+1; 799 } 800 *nbytes = bytes; 801 *nelems = count+1; 802 } 803 804 /* copy the strings from arg[] into buf, starting at given offset 805 * return new offset to next free byte 806 */ 807 static int copystrings (char *buf, int offset, const char * const *arg) { 808 char *p; 809 const char * const *a; 810 int count=0; 811 812 if (arg == 0) { 813 return offset; 814 } 815 for (p=buf+offset, a=arg; *a != 0; a++) { 816 int len = strlen (*a) +1; 817 memcpy (p, *a, len); 818 p += len; 819 count += len; 820 } 821 return offset+count; 822 } 823 824 /** 825 * Start a child process running function xx_childProcess. 826 * This function only returns in the parent. 827 * We are unusually paranoid; use of clone/vfork is 828 * especially likely to tickle gcc/glibc bugs. 829 */ 830 #ifdef __attribute_noinline__ /* See: sys/cdefs.h */ 831 __attribute_noinline__ 832 #endif 833 834 static pid_t 835 cloneChild(ChildStuff *c) { 836 #ifdef __linux__ 837 #define START_CHILD_CLONE_STACK_SIZE (64 * 1024) 838 839 /* 840 * See clone(2). 841 * Instead of worrying about which direction the stack grows, just 842 * allocate twice as much and start the stack in the middle. 843 */ 844 if ((c->clone_stack = malloc(2 * START_CHILD_CLONE_STACK_SIZE)) == NULL) 845 /* errno will be set to ENOMEM */ 846 return -1; 847 return clone(xx_childProcess, 848 c->clone_stack + START_CHILD_CLONE_STACK_SIZE, 849 CLONE_VFORK | CLONE_VM | SIGCHLD, c); 850 #else 851 /* not available on Solaris / Mac */ 852 assert(0); 853 #endif 854 } 855 856 static pid_t 857 vforkChild(ChildStuff *c) { 858 volatile pid_t resultPid; 859 860 /* 861 * We separate the call to vfork into a separate function to make 862 * very sure to keep stack of child from corrupting stack of parent, 863 * as suggested by the scary gcc warning: 864 * warning: variable 'foo' might be clobbered by 'longjmp' or 'vfork' 865 */ 866 resultPid = vfork(); 867 868 if (resultPid == 0) { 869 xx_childProcess(c); 870 } 871 assert(resultPid != 0); /* xx_childProcess never returns */ 872 return resultPid; 873 } 874 875 static pid_t 876 forkChild(ChildStuff *c) { 877 pid_t resultPid; 878 879 /* 880 * From Solaris fork(2): In Solaris 10, a call to fork() is 881 * identical to a call to fork1(); only the calling thread is 882 * replicated in the child process. This is the POSIX-specified 883 * behavior for fork(). 884 */ 885 resultPid = fork(); 886 887 if (resultPid == 0) { 888 xx_childProcess(c); 889 } 890 assert(resultPid != 0); /* xx_childProcess never returns */ 891 return resultPid; 892 } 893 894 static pid_t 895 spawnChild(JNIEnv *env, jobject process, ChildStuff *c) { 896 pid_t resultPid; 897 const char *helperpath; 898 jobject helperobj; 899 jboolean isCopy; 900 int i, offset, rval, bufsize; 901 char *buf, buf1[16]; 902 char *hlpargs[2]; 903 SpawnInfo sp; 904 905 helperobj = (*env)->GetStaticObjectField( 906 env, (*env)->GetObjectClass (env, process), 907 helperfield 908 ); 909 if (helperobj == NULL) { 910 return -1; 911 } 912 helperpath = GetStringPlatformChars (env, helperobj, &isCopy); 913 /* need to tell helper which fd is for receiving the childstuff 914 * and which fd to send response back on 915 */ 916 sprintf (buf1, "%d:%d", c->childenv[0], c->fail[1]); 917 /* put the fd string as argument to the helper cmd */ 918 hlpargs[0] = buf1; 919 hlpargs[1] = 0; 920 921 /* Following items are sent down the pipe to the helper 922 * after it is spawned. 923 * All strings are null terminated. All arrays of strings 924 * have an empty string for termination. 925 * - the ChildStuff struct 926 * - the SpawnInfo struct 927 * - the argv strings array 928 * - the envv strings array 929 * - the home directory string 930 * - the parentPath string 931 * - the parentPathv array 932 */ 933 /* First calculate the sizes */ 934 arraysize (c->argv, &sp.nargv, &sp.argvBytes); 935 bufsize = sp.argvBytes; 936 arraysize (c->envv, &sp.nenvv, &sp.envvBytes); 937 bufsize += sp.envvBytes; 938 sp.dirlen = c->pdir == 0 ? 0 : strlen (c->pdir)+1; 939 bufsize += sp.dirlen; 940 sp.parentPathLen = xx_parentPath == 0 ? 0 : strlen (xx_parentPath)+1; 941 bufsize += sp.parentPathLen; 942 arraysize (xx_parentPathv, &sp.nparentPathv, &sp.parentPathvBytes); 943 bufsize += sp.parentPathvBytes; 944 /* We need to clear FD_CLOEXEC if set in the fds[]. 945 * Files are created FD_CLOEXEC in Java. 946 * Otherwise, they will be closed when the target gets exec'd */ 947 for (i=0; i<3; i++) { 948 if (c->fds[i] != -1) { 949 int flags = fcntl(c->fds[i], F_GETFD); 950 if (flags & FD_CLOEXEC) { 951 fcntl (c->fds[i], F_SETFD, flags & (~1)); 952 } 953 } 954 } 955 956 rval = posix_spawn (&resultPid, helperpath, 0, 0, (char * const *) hlpargs, environ); 957 958 if (rval != 0) { 959 return -1; 960 } 961 962 /* now the lengths are known, copy the data */ 963 buf = NEW (char, bufsize); 964 if (buf == 0) { 965 return -1; 966 } 967 offset = copystrings (buf, 0, &c->argv[0]); 968 offset = copystrings (buf, offset, &c->envv[0]); 969 memcpy (buf+offset, c->pdir, sp.dirlen); 970 offset += sp.dirlen; 971 memcpy (buf+offset, xx_parentPath, sp.parentPathLen); 972 offset += sp.parentPathLen; 973 offset = copystrings (buf, offset, xx_parentPathv); 974 assert (offset == bufsize); 975 976 /* write the two structs and the data buffer */ 977 write (c->childenv[1], (char *)c, sizeof(*c)); 978 write (c->childenv[1], (char *)&sp, sizeof(sp)); 979 write (c->childenv[1], buf, bufsize); 980 free (buf); 981 982 /* In this mode an external main() in invoked which calls back into 983 * xx_childProcess() in this file, rather than directly 984 * via the statement below */ 985 return resultPid; 986 } 987 988 static pid_t 989 startChild(JNIEnv *env, jobject process, ChildStuff *c) { 990 switch (c->mode) { 991 case MODE_CLONE: 992 return cloneChild(c); 993 case MODE_VFORK: 994 return vforkChild(c); 995 case MODE_FORK: 996 return forkChild(c); 997 case MODE_SPAWN: 998 return spawnChild(env, process, c); 999 } 1000 } 1001 1002 JNIEXPORT jint JNICALL 1003 Java_java_lang_UNIXProcess_forkAndExec(JNIEnv *env, 1004 jobject process, 1005 jint mode, 1006 jbyteArray prog, 1007 jbyteArray argBlock, jint argc, 1008 jbyteArray envBlock, jint envc, 1009 jbyteArray dir, 1010 jintArray std_fds, 1011 jboolean redirectErrorStream) 1012 { 1013 int errnum; 1014 int resultPid = -1; 1015 int in[2], out[2], err[2], fail[2], childenv[2]; 1016 jint *fds = NULL; 1017 const char *pprog = NULL; 1018 const char *pargBlock = NULL; 1019 const char *penvBlock = NULL; 1020 ChildStuff *c; 1021 1022 in[0] = in[1] = out[0] = out[1] = err[0] = err[1] = fail[0] = fail[1] = -1; 1023 childenv[0] = childenv[1] = -1; 1024 1025 if ((c = NEW(ChildStuff, 1)) == NULL) return -1; 1026 c->argv = NULL; 1027 c->envv = NULL; 1028 c->pdir = NULL; 1029 c->clone_stack = NULL; 1030 1031 /* Convert prog + argBlock into a char ** argv. 1032 * Add one word room for expansion of argv for use by 1033 * execve_as_traditional_shell_script. 1034 * This word also used when using spawn mode 1035 */ 1036 assert(prog != NULL && argBlock != NULL); 1037 if ((pprog = getBytes(env, prog)) == NULL) goto Catch; 1038 if ((pargBlock = getBytes(env, argBlock)) == NULL) goto Catch; 1039 if ((c->argv = NEW(const char *, argc + 3)) == NULL) goto Catch; 1040 c->argv[0] = pprog; 1041 c->argc = argc + 2; 1042 xx_initVectorFromBlock(c->argv+1, pargBlock, argc); 1043 1044 if (envBlock != NULL) { 1045 /* Convert envBlock into a char ** envv */ 1046 if ((penvBlock = getBytes(env, envBlock)) == NULL) goto Catch; 1047 if ((c->envv = NEW(const char *, envc + 1)) == NULL) goto Catch; 1048 xx_initVectorFromBlock(c->envv, penvBlock, envc); 1049 } 1050 1051 if (dir != NULL) { 1052 if ((c->pdir = getBytes(env, dir)) == NULL) goto Catch; 1053 } 1054 1055 assert(std_fds != NULL); 1056 fds = (*env)->GetIntArrayElements(env, std_fds, NULL); 1057 if (fds == NULL) goto Catch; 1058 1059 if ((fds[0] == -1 && pipe(in) < 0) || 1060 (fds[1] == -1 && pipe(out) < 0) || 1061 (fds[2] == -1 && pipe(err) < 0) || 1062 (pipe(childenv) < 0) || 1063 (pipe(fail) < 0)) { 1064 throwIOException(env, errno, "Bad file descriptor"); 1065 goto Catch; 1066 } 1067 c->fds[0] = fds[0]; 1068 c->fds[1] = fds[1]; 1069 c->fds[2] = fds[2]; 1070 1071 copyPipe(in, c->in); 1072 copyPipe(out, c->out); 1073 copyPipe(err, c->err); 1074 copyPipe(fail, c->fail); 1075 copyPipe(childenv, c->childenv); 1076 1077 c->redirectErrorStream = redirectErrorStream; 1078 c->mode = mode; 1079 1080 resultPid = startChild(env, process, c); 1081 assert(resultPid != 0); 1082 1083 if (resultPid < 0) { 1084 switch (c->mode) { 1085 case MODE_CLONE: 1086 throwIOException(env, errno, "clone failed"); 1087 case MODE_VFORK: 1088 throwIOException(env, errno, "vfork failed"); 1089 case MODE_FORK: 1090 throwIOException(env, errno, "fork failed"); 1091 case MODE_SPAWN: 1092 throwIOException(env, errno, "spawn failed"); 1093 } 1094 goto Catch; 1095 } 1096 restartableClose(fail[1]); fail[1] = -1; /* See: WhyCantJohnnyExec */ 1097 1098 switch (xx_readFully(fail[0], &errnum, sizeof(errnum))) { 1099 case 0: break; /* Exec succeeded */ 1100 case sizeof(errnum): 1101 waitpid(resultPid, NULL, 0); 1102 throwIOException(env, errnum, "Exec failed"); 1103 goto Catch; 1104 default: 1105 throwIOException(env, errno, "Read failed"); 1106 goto Catch; 1107 } 1108 1109 fds[0] = (in [1] != -1) ? in [1] : -1; 1110 fds[1] = (out[0] != -1) ? out[0] : -1; 1111 fds[2] = (err[0] != -1) ? err[0] : -1; 1112 1113 Finally: 1114 free(c->clone_stack); 1115 1116 /* Always clean up the child's side of the pipes */ 1117 closeSafely(in [0]); 1118 closeSafely(out[1]); 1119 closeSafely(err[1]); 1120 1121 /* Always clean up fail and childEnv descriptors */ 1122 closeSafely(fail[0]); 1123 closeSafely(fail[1]); 1124 closeSafely(childenv[0]); 1125 closeSafely(childenv[1]); 1126 1127 releaseBytes(env, prog, pprog); 1128 releaseBytes(env, argBlock, pargBlock); 1129 releaseBytes(env, envBlock, penvBlock); 1130 releaseBytes(env, dir, c->pdir); 1131 1132 free(c->argv); 1133 free(c->envv); 1134 free(c); 1135 1136 if (fds != NULL) 1137 (*env)->ReleaseIntArrayElements(env, std_fds, fds, 0); 1138 1139 return resultPid; 1140 1141 Catch: 1142 /* Clean up the parent's side of the pipes in case of failure only */ 1143 closeSafely(in [1]); in[1] = -1; 1144 closeSafely(out[0]); out[0] = -1; 1145 closeSafely(err[0]); err[0] = -1; 1146 goto Finally; 1147 } 1148 1149 JNIEXPORT void JNICALL 1150 Java_java_lang_UNIXProcess_destroyProcess(JNIEnv *env, 1151 jobject junk, 1152 jint pid, 1153 jboolean force) 1154 { 1155 int sig = (force == JNI_TRUE) ? SIGKILL : SIGTERM; 1156 kill(pid, sig); 1157 } |