| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "base/process/launch.h" | 5 #include "base/process/launch.h" |
| 6 | 6 |
| 7 #include <dirent.h> | 7 #include <dirent.h> |
| 8 #include <errno.h> | 8 #include <errno.h> |
| 9 #include <fcntl.h> | 9 #include <fcntl.h> |
| 10 #include <sched.h> | 10 #include <sched.h> |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 60 #include <crt_externs.h> | 60 #include <crt_externs.h> |
| 61 #include <sys/event.h> | 61 #include <sys/event.h> |
| 62 #else | 62 #else |
| 63 extern char** environ; | 63 extern char** environ; |
| 64 #endif | 64 #endif |
| 65 | 65 |
| 66 namespace base { | 66 namespace base { |
| 67 | 67 |
| 68 namespace { | 68 namespace { |
| 69 | 69 |
| 70 #if !defined(OS_NACL_NONSFI) |
| 70 // Get the process's "environment" (i.e. the thing that setenv/getenv | 71 // Get the process's "environment" (i.e. the thing that setenv/getenv |
| 71 // work with). | 72 // work with). |
| 72 char** GetEnvironment() { | 73 char** GetEnvironment() { |
| 73 #if defined(OS_MACOSX) | 74 #if defined(OS_MACOSX) |
| 74 return *_NSGetEnviron(); | 75 return *_NSGetEnviron(); |
| 75 #else | 76 #else |
| 76 return environ; | 77 return environ; |
| 77 #endif | 78 #endif |
| 78 } | 79 } |
| 79 | 80 |
| (...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 182 // Now ask the kernel again and check that no restorer will leak. | 183 // Now ask the kernel again and check that no restorer will leak. |
| 183 if (sys_rt_sigaction(signum, NULL, &act) || act.k_sa_restorer) { | 184 if (sys_rt_sigaction(signum, NULL, &act) || act.k_sa_restorer) { |
| 184 RAW_LOG(FATAL, "Cound not fix sa_restorer."); | 185 RAW_LOG(FATAL, "Cound not fix sa_restorer."); |
| 185 } | 186 } |
| 186 #endif // !defined(NDEBUG) | 187 #endif // !defined(NDEBUG) |
| 187 } | 188 } |
| 188 } | 189 } |
| 189 #endif // !defined(OS_LINUX) || | 190 #endif // !defined(OS_LINUX) || |
| 190 // (!defined(__i386__) && !defined(__x86_64__) && !defined(__arm__)) | 191 // (!defined(__i386__) && !defined(__x86_64__) && !defined(__arm__)) |
| 191 | 192 |
| 192 #if defined(OS_LINUX) | 193 #endif // !defined(OS_NACL_NONSFI) |
| 194 |
| 195 #if defined(OS_LINUX) || defined(OS_NACL_NONSFI) |
| 193 bool IsRunningOnValgrind() { | 196 bool IsRunningOnValgrind() { |
| 194 return RUNNING_ON_VALGRIND; | 197 return RUNNING_ON_VALGRIND; |
| 195 } | 198 } |
| 196 | 199 |
| 197 // This function runs on the stack specified on the clone call. It uses longjmp | 200 // This function runs on the stack specified on the clone call. It uses longjmp |
| 198 // to switch back to the original stack so the child can return from sys_clone. | 201 // to switch back to the original stack so the child can return from sys_clone. |
| 199 int CloneHelper(void* arg) { | 202 int CloneHelper(void* arg) { |
| 200 jmp_buf* env_ptr = reinterpret_cast<jmp_buf*>(arg); | 203 jmp_buf* env_ptr = reinterpret_cast<jmp_buf*>(arg); |
| 201 longjmp(*env_ptr, 1); | 204 longjmp(*env_ptr, 1); |
| 202 | 205 |
| (...skipping 25 matching lines...) Expand all Loading... |
| 228 char stack_buf[PTHREAD_STACK_MIN]; | 231 char stack_buf[PTHREAD_STACK_MIN]; |
| 229 #if defined(ARCH_CPU_X86_FAMILY) || defined(ARCH_CPU_ARM_FAMILY) || \ | 232 #if defined(ARCH_CPU_X86_FAMILY) || defined(ARCH_CPU_ARM_FAMILY) || \ |
| 230 defined(ARCH_CPU_MIPS64_FAMILY) || defined(ARCH_CPU_MIPS_FAMILY) | 233 defined(ARCH_CPU_MIPS64_FAMILY) || defined(ARCH_CPU_MIPS_FAMILY) |
| 231 // The stack grows downward. | 234 // The stack grows downward. |
| 232 void* stack = stack_buf + sizeof(stack_buf); | 235 void* stack = stack_buf + sizeof(stack_buf); |
| 233 #else | 236 #else |
| 234 #error "Unsupported architecture" | 237 #error "Unsupported architecture" |
| 235 #endif | 238 #endif |
| 236 return clone(&CloneHelper, stack, flags, env, ptid, nullptr, ctid); | 239 return clone(&CloneHelper, stack, flags, env, ptid, nullptr, ctid); |
| 237 } | 240 } |
| 238 #endif // defined(OS_LINUX) | 241 #endif // defined(OS_LINUX) || defined(OS_NACL_NONSFI) |
| 239 | 242 |
| 240 } // anonymous namespace | 243 } // anonymous namespace |
| 241 | 244 |
| 245 #if !defined(OS_NACL_NONSFI) |
| 242 // Functor for |ScopedDIR| (below). | 246 // Functor for |ScopedDIR| (below). |
| 243 struct ScopedDIRClose { | 247 struct ScopedDIRClose { |
| 244 inline void operator()(DIR* x) const { | 248 inline void operator()(DIR* x) const { |
| 245 if (x) | 249 if (x) |
| 246 closedir(x); | 250 closedir(x); |
| 247 } | 251 } |
| 248 }; | 252 }; |
| 249 | 253 |
| 250 // Automatically closes |DIR*|s. | 254 // Automatically closes |DIR*|s. |
| 251 typedef scoped_ptr<DIR, ScopedDIRClose> ScopedDIR; | 255 typedef scoped_ptr<DIR, ScopedDIRClose> ScopedDIR; |
| (...skipping 482 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 734 bool GetAppOutputWithExitCode(const CommandLine& cl, | 738 bool GetAppOutputWithExitCode(const CommandLine& cl, |
| 735 std::string* output, | 739 std::string* output, |
| 736 int* exit_code) { | 740 int* exit_code) { |
| 737 // Run |execve()| with the current environment and store "unlimited" data. | 741 // Run |execve()| with the current environment and store "unlimited" data. |
| 738 GetAppOutputInternalResult result = GetAppOutputInternal( | 742 GetAppOutputInternalResult result = GetAppOutputInternal( |
| 739 cl.argv(), NULL, output, std::numeric_limits<std::size_t>::max(), true, | 743 cl.argv(), NULL, output, std::numeric_limits<std::size_t>::max(), true, |
| 740 exit_code); | 744 exit_code); |
| 741 return result == EXECUTE_SUCCESS; | 745 return result == EXECUTE_SUCCESS; |
| 742 } | 746 } |
| 743 | 747 |
| 744 #if defined(OS_LINUX) | 748 #endif // !defined(OS_NACL_NONSFI) |
| 749 |
| 750 #if defined(OS_LINUX) || defined(OS_NACL_NONSFI) |
| 745 pid_t ForkWithFlags(unsigned long flags, pid_t* ptid, pid_t* ctid) { | 751 pid_t ForkWithFlags(unsigned long flags, pid_t* ptid, pid_t* ctid) { |
| 746 const bool clone_tls_used = flags & CLONE_SETTLS; | 752 const bool clone_tls_used = flags & CLONE_SETTLS; |
| 747 const bool invalid_ctid = | 753 const bool invalid_ctid = |
| 748 (flags & (CLONE_CHILD_SETTID | CLONE_CHILD_CLEARTID)) && !ctid; | 754 (flags & (CLONE_CHILD_SETTID | CLONE_CHILD_CLEARTID)) && !ctid; |
| 749 const bool invalid_ptid = (flags & CLONE_PARENT_SETTID) && !ptid; | 755 const bool invalid_ptid = (flags & CLONE_PARENT_SETTID) && !ptid; |
| 750 | 756 |
| 751 // We do not support CLONE_VM. | 757 // We do not support CLONE_VM. |
| 752 const bool clone_vm_used = flags & CLONE_VM; | 758 const bool clone_vm_used = flags & CLONE_VM; |
| 753 | 759 |
| 754 if (clone_tls_used || invalid_ctid || invalid_ptid || clone_vm_used) { | 760 if (clone_tls_used || invalid_ctid || invalid_ptid || clone_vm_used) { |
| (...skipping 18 matching lines...) Expand all Loading... |
| 773 #endif | 779 #endif |
| 774 } | 780 } |
| 775 | 781 |
| 776 jmp_buf env; | 782 jmp_buf env; |
| 777 if (setjmp(env) == 0) { | 783 if (setjmp(env) == 0) { |
| 778 return CloneAndLongjmpInChild(flags, ptid, ctid, &env); | 784 return CloneAndLongjmpInChild(flags, ptid, ctid, &env); |
| 779 } | 785 } |
| 780 | 786 |
| 781 return 0; | 787 return 0; |
| 782 } | 788 } |
| 783 #endif // defined(OS_LINUX) | 789 #endif // defined(OS_LINUX) || defined(OS_NACL_NONSFI) |
| 784 | 790 |
| 785 } // namespace base | 791 } // namespace base |
| OLD | NEW |