jdk/src/java.base/unix/native/libjava/ProcessImpl_md.c
changeset 29724 638809ff54f3
parent 28665 fe8344cf6496
child 30784 28105f71beb2
equal deleted inserted replaced
29723:1f99eb44aa0b 29724:638809ff54f3
    95  *   a child process linked to the parent in the same way, but it
    95  *   a child process linked to the parent in the same way, but it
    96  *   avoids the problem of duplicating the parent (VM) process
    96  *   avoids the problem of duplicating the parent (VM) process
    97  *   address space temporarily, before launching the target command.
    97  *   address space temporarily, before launching the target command.
    98  *
    98  *
    99  * Based on the above analysis, we are currently using vfork() on
    99  * Based on the above analysis, we are currently using vfork() on
   100  * Linux and spawn() on other Unix systems, but the code to use clone()
   100  * Linux and posix_spawn() on other Unix systems.
   101  * and fork() remains.
       
   102  */
   101  */
   103 
   102 
   104 
   103 
   105 static void
   104 static void
   106 setSIGCHLDHandler(JNIEnv *env)
   105 setSIGCHLDHandler(JNIEnv *env)
   383     }
   382     }
   384     return offset+count;
   383     return offset+count;
   385 }
   384 }
   386 
   385 
   387 /**
   386 /**
   388  * We are unusually paranoid; use of clone/vfork is
   387  * We are unusually paranoid; use of vfork is
   389  * especially likely to tickle gcc/glibc bugs.
   388  * especially likely to tickle gcc/glibc bugs.
   390  */
   389  */
   391 #ifdef __attribute_noinline__  /* See: sys/cdefs.h */
   390 #ifdef __attribute_noinline__  /* See: sys/cdefs.h */
   392 __attribute_noinline__
   391 __attribute_noinline__
   393 #endif
       
   394 
       
   395 #define START_CHILD_USE_CLONE 0  /* clone() currently disabled; see above. */
       
   396 
       
   397 #ifdef START_CHILD_USE_CLONE
       
   398 static pid_t
       
   399 cloneChild(ChildStuff *c) {
       
   400 #ifdef __linux__
       
   401 #define START_CHILD_CLONE_STACK_SIZE (64 * 1024)
       
   402     /*
       
   403      * See clone(2).
       
   404      * Instead of worrying about which direction the stack grows, just
       
   405      * allocate twice as much and start the stack in the middle.
       
   406      */
       
   407     if ((c->clone_stack = malloc(2 * START_CHILD_CLONE_STACK_SIZE)) == NULL)
       
   408         /* errno will be set to ENOMEM */
       
   409         return -1;
       
   410     return clone(childProcess,
       
   411                  c->clone_stack + START_CHILD_CLONE_STACK_SIZE,
       
   412                  CLONE_VFORK | CLONE_VM | SIGCHLD, c);
       
   413 #else
       
   414 /* not available on Solaris / Mac */
       
   415     assert(0);
       
   416     return -1;
       
   417 #endif
       
   418 }
       
   419 #endif
   392 #endif
   420 
   393 
   421 static pid_t
   394 static pid_t
   422 vforkChild(ChildStuff *c) {
   395 vforkChild(ChildStuff *c) {
   423     volatile pid_t resultPid;
   396     volatile pid_t resultPid;
   588 
   561 
   589     if ((c = NEW(ChildStuff, 1)) == NULL) return -1;
   562     if ((c = NEW(ChildStuff, 1)) == NULL) return -1;
   590     c->argv = NULL;
   563     c->argv = NULL;
   591     c->envv = NULL;
   564     c->envv = NULL;
   592     c->pdir = NULL;
   565     c->pdir = NULL;
   593     c->clone_stack = NULL;
       
   594 
   566 
   595     /* Convert prog + argBlock into a char ** argv.
   567     /* Convert prog + argBlock into a char ** argv.
   596      * Add one word room for expansion of argv for use by
   568      * Add one word room for expansion of argv for use by
   597      * execve_as_traditional_shell_script.
   569      * execve_as_traditional_shell_script.
   598      * This word is also used when using spawn mode
   570      * This word is also used when using posix_spawn mode
   599      */
   571      */
   600     assert(prog != NULL && argBlock != NULL);
   572     assert(prog != NULL && argBlock != NULL);
   601     if ((phelperpath = getBytes(env, helperpath))   == NULL) goto Catch;
   573     if ((phelperpath = getBytes(env, helperpath))   == NULL) goto Catch;
   602     if ((pprog       = getBytes(env, prog))         == NULL) goto Catch;
   574     if ((pprog       = getBytes(env, prog))         == NULL) goto Catch;
   603     if ((pargBlock   = getBytes(env, argBlock))     == NULL) goto Catch;
   575     if ((pargBlock   = getBytes(env, argBlock))     == NULL) goto Catch;
   652             break;
   624             break;
   653           case MODE_FORK:
   625           case MODE_FORK:
   654             throwIOException(env, errno, "fork failed");
   626             throwIOException(env, errno, "fork failed");
   655             break;
   627             break;
   656           case MODE_POSIX_SPAWN:
   628           case MODE_POSIX_SPAWN:
   657             throwIOException(env, errno, "spawn failed");
   629             throwIOException(env, errno, "posix_spawn failed");
   658             break;
   630             break;
   659         }
   631         }
   660         goto Catch;
   632         goto Catch;
   661     }
   633     }
   662     close(fail[1]); fail[1] = -1; /* See: WhyCantJohnnyExec  (childproc.c)  */
   634     close(fail[1]); fail[1] = -1; /* See: WhyCantJohnnyExec  (childproc.c)  */
   675     fds[0] = (in [1] != -1) ? in [1] : -1;
   647     fds[0] = (in [1] != -1) ? in [1] : -1;
   676     fds[1] = (out[0] != -1) ? out[0] : -1;
   648     fds[1] = (out[0] != -1) ? out[0] : -1;
   677     fds[2] = (err[0] != -1) ? err[0] : -1;
   649     fds[2] = (err[0] != -1) ? err[0] : -1;
   678 
   650 
   679  Finally:
   651  Finally:
   680     free(c->clone_stack);
       
   681 
       
   682     /* Always clean up the child's side of the pipes */
   652     /* Always clean up the child's side of the pipes */
   683     closeSafely(in [0]);
   653     closeSafely(in [0]);
   684     closeSafely(out[1]);
   654     closeSafely(out[1]);
   685     closeSafely(err[1]);
   655     closeSafely(err[1]);
   686 
   656