src/solaris/native/java/lang/UNIXProcess_md.c

Print this page




  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 }