Mercurial > hg > graal-jvmci-8
comparison src/os/linux/vm/os_linux.cpp @ 22989:915ca3e9d15e
8078470: [Linux] Replace syscall use in os::fork_and_exec with glibc fork() and execve()
Reviewed-by: stuefe, dsamersoff, dcubed
author | dholmes |
---|---|
date | Wed, 29 Apr 2015 19:37:10 -0400 |
parents | 8461d0b03127 |
children | 9a23a160ca57 |
comparison
equal
deleted
inserted
replaced
22988:99edc344d77c | 22989:915ca3e9d15e |
---|---|
5927 } | 5927 } |
5928 | 5928 |
5929 | 5929 |
5930 extern char** environ; | 5930 extern char** environ; |
5931 | 5931 |
5932 #ifndef __NR_fork | |
5933 #define __NR_fork IA32_ONLY(2) IA64_ONLY(not defined) AMD64_ONLY(57) | |
5934 #endif | |
5935 | |
5936 #ifndef __NR_execve | |
5937 #define __NR_execve IA32_ONLY(11) IA64_ONLY(1033) AMD64_ONLY(59) | |
5938 #endif | |
5939 | |
5940 // Run the specified command in a separate process. Return its exit value, | 5932 // Run the specified command in a separate process. Return its exit value, |
5941 // or -1 on failure (e.g. can't fork a new process). | 5933 // or -1 on failure (e.g. can't fork a new process). |
5942 // Unlike system(), this function can be called from signal handler. It | 5934 // Unlike system(), this function can be called from signal handler. It |
5943 // doesn't block SIGINT et al. | 5935 // doesn't block SIGINT et al. |
5944 int os::fork_and_exec(char* cmd) { | 5936 int os::fork_and_exec(char* cmd) { |
5945 const char * argv[4] = {"sh", "-c", cmd, NULL}; | 5937 const char * argv[4] = {"sh", "-c", cmd, NULL}; |
5946 | 5938 |
5947 // fork() in LinuxThreads/NPTL is not async-safe. It needs to run | 5939 pid_t pid = fork(); |
5948 // pthread_atfork handlers and reset pthread library. All we need is a | |
5949 // separate process to execve. Make a direct syscall to fork process. | |
5950 // On IA64 there's no fork syscall, we have to use fork() and hope for | |
5951 // the best... | |
5952 pid_t pid = NOT_IA64(syscall(__NR_fork);) | |
5953 IA64_ONLY(fork();) | |
5954 | 5940 |
5955 if (pid < 0) { | 5941 if (pid < 0) { |
5956 // fork failed | 5942 // fork failed |
5957 return -1; | 5943 return -1; |
5958 | 5944 |
5959 } else if (pid == 0) { | 5945 } else if (pid == 0) { |
5960 // child process | 5946 // child process |
5961 | 5947 |
5962 // execve() in LinuxThreads will call pthread_kill_other_threads_np() | 5948 execve("/bin/sh", (char* const*)argv, environ); |
5963 // first to kill every thread on the thread list. Because this list is | |
5964 // not reset by fork() (see notes above), execve() will instead kill | |
5965 // every thread in the parent process. We know this is the only thread | |
5966 // in the new process, so make a system call directly. | |
5967 // IA64 should use normal execve() from glibc to match the glibc fork() | |
5968 // above. | |
5969 NOT_IA64(syscall(__NR_execve, "/bin/sh", argv, environ);) | |
5970 IA64_ONLY(execve("/bin/sh", (char* const*)argv, environ);) | |
5971 | 5949 |
5972 // execve failed | 5950 // execve failed |
5973 _exit(-1); | 5951 _exit(-1); |
5974 | 5952 |
5975 } else { | 5953 } else { |