< prev index next >

src/os/linux/vm/os_linux.cpp

Print this page
rev 8309 : 8078470: [Linux] Replace syscall use in os::fork_and_exec with glibc fork() and execve()
Reviewed-by: stuefe, dsamersoff, dcubed


5861         assert(status == 0, "invariant");
5862       } else {
5863         status = pthread_mutex_unlock(_mutex);
5864         assert(status == 0, "invariant");
5865         status = pthread_cond_signal(&_cond[_cur_index]);
5866         assert(status == 0, "invariant");
5867       }
5868     } else {
5869       pthread_mutex_unlock(_mutex);
5870       assert(status == 0, "invariant");
5871     }
5872   } else {
5873     pthread_mutex_unlock(_mutex);
5874     assert(status == 0, "invariant");
5875   }
5876 }
5877 
5878 
5879 extern char** environ;
5880 
5881 #ifndef __NR_fork
5882   #define __NR_fork IA32_ONLY(2) IA64_ONLY(not defined) AMD64_ONLY(57) AARCH64_ONLY(1079)
5883 #endif
5884 
5885 #ifndef __NR_execve
5886   #define __NR_execve IA32_ONLY(11) IA64_ONLY(1033) AMD64_ONLY(59) AARCH64_ONLY(221)
5887 #endif
5888 
5889 // Run the specified command in a separate process. Return its exit value,
5890 // or -1 on failure (e.g. can't fork a new process).
5891 // Unlike system(), this function can be called from signal handler. It
5892 // doesn't block SIGINT et al.
5893 int os::fork_and_exec(char* cmd) {
5894   const char * argv[4] = {"sh", "-c", cmd, NULL};
5895 
5896   // fork() in LinuxThreads/NPTL is not async-safe. It needs to run
5897   // pthread_atfork handlers and reset pthread library. All we need is a
5898   // separate process to execve. Make a direct syscall to fork process.
5899   // On IA64 there's no fork syscall, we have to use fork() and hope for
5900   // the best...
5901   pid_t pid = NOT_IA64(syscall(__NR_fork);)
5902   IA64_ONLY(fork();)
5903 
5904   if (pid < 0) {
5905     // fork failed
5906     return -1;
5907 
5908   } else if (pid == 0) {
5909     // child process
5910 
5911     // execve() in LinuxThreads will call pthread_kill_other_threads_np()
5912     // first to kill every thread on the thread list. Because this list is
5913     // not reset by fork() (see notes above), execve() will instead kill
5914     // every thread in the parent process. We know this is the only thread
5915     // in the new process, so make a system call directly.
5916     // IA64 should use normal execve() from glibc to match the glibc fork()
5917     // above.
5918     NOT_IA64(syscall(__NR_execve, "/bin/sh", argv, environ);)
5919     IA64_ONLY(execve("/bin/sh", (char* const*)argv, environ);)
5920 
5921     // execve failed
5922     _exit(-1);
5923 
5924   } else  {
5925     // copied from J2SE ..._waitForProcessExit() in UNIXProcess_md.c; we don't
5926     // care about the actual exit code, for now.
5927 
5928     int status;
5929 
5930     // Wait for the child process to exit.  This returns immediately if
5931     // the child has already exited. */
5932     while (waitpid(pid, &status, 0) < 0) {
5933       switch (errno) {
5934       case ECHILD: return 0;
5935       case EINTR: break;
5936       default: return -1;
5937       }
5938     }
5939 




5861         assert(status == 0, "invariant");
5862       } else {
5863         status = pthread_mutex_unlock(_mutex);
5864         assert(status == 0, "invariant");
5865         status = pthread_cond_signal(&_cond[_cur_index]);
5866         assert(status == 0, "invariant");
5867       }
5868     } else {
5869       pthread_mutex_unlock(_mutex);
5870       assert(status == 0, "invariant");
5871     }
5872   } else {
5873     pthread_mutex_unlock(_mutex);
5874     assert(status == 0, "invariant");
5875   }
5876 }
5877 
5878 
5879 extern char** environ;
5880 








5881 // Run the specified command in a separate process. Return its exit value,
5882 // or -1 on failure (e.g. can't fork a new process).
5883 // Unlike system(), this function can be called from signal handler. It
5884 // doesn't block SIGINT et al.
5885 int os::fork_and_exec(char* cmd) {
5886   const char * argv[4] = {"sh", "-c", cmd, NULL};
5887 
5888   pid_t pid = fork();






5889 
5890   if (pid < 0) {
5891     // fork failed
5892     return -1;
5893 
5894   } else if (pid == 0) {
5895     // child process
5896 
5897     execve("/bin/sh", (char* const*)argv, environ);








5898 
5899     // execve failed
5900     _exit(-1);
5901 
5902   } else  {
5903     // copied from J2SE ..._waitForProcessExit() in UNIXProcess_md.c; we don't
5904     // care about the actual exit code, for now.
5905 
5906     int status;
5907 
5908     // Wait for the child process to exit.  This returns immediately if
5909     // the child has already exited. */
5910     while (waitpid(pid, &status, 0) < 0) {
5911       switch (errno) {
5912       case ECHILD: return 0;
5913       case EINTR: break;
5914       default: return -1;
5915       }
5916     }
5917 


< prev index next >