blob: 018296c5628b341310b395f548cb961df35e8df0 [file] [log] [blame]
[email protected]927054d2012-01-21 01:48:251// Copyright (c) 2012 The Chromium Authors. All rights reserved.
[email protected]3d5617e2008-08-27 14:36:192// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
[email protected]05d4b0a2009-01-29 17:51:515#include <dirent.h>
[email protected]c7856632009-01-13 17:38:496#include <errno.h>
[email protected]05d4b0a2009-01-29 17:51:517#include <fcntl.h>
[email protected]8cf7cebd2009-01-05 19:53:308#include <signal.h>
[email protected]05d4b0a2009-01-29 17:51:519#include <stdlib.h>
[email protected]0d83c732008-12-02 16:50:4710#include <sys/resource.h>
11#include <sys/time.h>
[email protected]3d5617e2008-08-27 14:36:1912#include <sys/types.h>
[email protected]43bc28322008-12-05 01:57:2113#include <sys/wait.h>
[email protected]3d5617e2008-08-27 14:36:1914#include <unistd.h>
[email protected]05d4b0a2009-01-29 17:51:5115
[email protected]64146372012-04-05 11:38:3616#include <iterator>
[email protected]fa3097a6a52008-12-17 22:41:5017#include <limits>
[email protected]3f04f2b2009-04-30 19:40:0318#include <set>
[email protected]3d5617e2008-08-27 14:36:1919
[email protected]5d91c9e2010-07-28 17:25:2820#include "base/command_line.h"
[email protected]cabe39c2010-02-02 02:28:1621#include "base/compiler_specific.h"
[email protected]72e243662011-06-11 00:46:1022#include "base/debug/debugger.h"
[email protected]58580352010-10-26 04:07:5023#include "base/debug/stack_trace.h"
[email protected]157c61b2009-05-01 21:37:3124#include "base/eintr_wrapper.h"
[email protected]955b7392011-03-09 00:49:2025#include "base/file_util.h"
[email protected]d88e17f2012-06-29 21:09:1426#include "base/files/dir_reader_posix.h"
[email protected]0d83c732008-12-02 16:50:4727#include "base/logging.h"
[email protected]3b63f8f42011-03-28 01:54:1528#include "base/memory/scoped_ptr.h"
[email protected]05d4b0a2009-01-29 17:51:5129#include "base/process_util.h"
[email protected]f1633932010-08-17 23:05:2830#include "base/stringprintf.h"
[email protected]44f9c952011-01-02 06:05:3931#include "base/synchronization/waitable_event.h"
[email protected]2f7a6ea2011-06-18 11:49:2732#include "base/third_party/dynamic_annotations/dynamic_annotations.h"
[email protected]ce072a72010-12-31 20:02:1633#include "base/threading/platform_thread.h"
[email protected]34b99632011-01-01 01:01:0634#include "base/threading/thread_restrictions.h"
[email protected]3d5617e2008-08-27 14:36:1935
[email protected]927054d2012-01-21 01:48:2536#if defined(OS_CHROMEOS)
37#include <sys/ioctl.h>
38#endif
39
[email protected]af824362011-12-04 14:19:4140#if defined(OS_FREEBSD)
41#include <sys/event.h>
42#include <sys/ucontext.h>
43#endif
44
[email protected]c0028792010-01-12 00:39:1545#if defined(OS_MACOSX)
[email protected]ef73044e2010-03-11 15:25:5446#include <crt_externs.h>
[email protected]56f0f262011-02-24 17:14:3647#include <sys/event.h>
[email protected]ef73044e2010-03-11 15:25:5448#else
49extern char** environ;
[email protected]c0028792010-01-12 00:39:1550#endif
51
[email protected]aa660752008-11-14 03:39:4652namespace base {
[email protected]3d5617e2008-08-27 14:36:1953
[email protected]d6fc9fd2009-10-27 18:03:4754namespace {
55
[email protected]2e844ef8e2011-06-30 20:01:2756// Get the process's "environment" (i.e. the thing that setenv/getenv
57// work with).
58char** GetEnvironment() {
59#if defined(OS_MACOSX)
60 return *_NSGetEnviron();
61#else
62 return environ;
63#endif
64}
65
66// Set the process's "environment" (i.e. the thing that setenv/getenv
67// work with).
68void SetEnvironment(char** env) {
69#if defined(OS_MACOSX)
70 *_NSGetEnviron() = env;
71#else
72 environ = env;
73#endif
74}
75
[email protected]eaec38c2010-11-29 19:30:2376int WaitpidWithTimeout(ProcessHandle handle, int64 wait_milliseconds,
77 bool* success) {
[email protected]d6fc9fd2009-10-27 18:03:4778 // This POSIX version of this function only guarantees that we wait no less
[email protected]2d9bb0222010-04-02 08:24:0179 // than |wait_milliseconds| for the process to exit. The child process may
80 // exit sometime before the timeout has ended but we may still block for up
81 // to 256 milliseconds after the fact.
[email protected]d6fc9fd2009-10-27 18:03:4782 //
83 // waitpid() has no direct support on POSIX for specifying a timeout, you can
84 // either ask it to block indefinitely or return immediately (WNOHANG).
85 // When a child process terminates a SIGCHLD signal is sent to the parent.
86 // Catching this signal would involve installing a signal handler which may
87 // affect other parts of the application and would be difficult to debug.
88 //
89 // Our strategy is to call waitpid() once up front to check if the process
90 // has already exited, otherwise to loop for wait_milliseconds, sleeping for
[email protected]2d9bb0222010-04-02 08:24:0191 // at most 256 milliseconds each time using usleep() and then calling
92 // waitpid(). The amount of time we sleep starts out at 1 milliseconds, and
93 // we double it every 4 sleep cycles.
[email protected]d6fc9fd2009-10-27 18:03:4794 //
95 // usleep() is speced to exit if a signal is received for which a handler
96 // has been installed. This means that when a SIGCHLD is sent, it will exit
97 // depending on behavior external to this function.
98 //
[email protected]eaec38c2010-11-29 19:30:2399 // This function is used primarily for unit tests, if we want to use it in
100 // the application itself it would probably be best to examine other routes.
101 int status = -1;
102 pid_t ret_pid = HANDLE_EINTR(waitpid(handle, &status, WNOHANG));
[email protected]2d9bb0222010-04-02 08:24:01103 static const int64 kMaxSleepInMicroseconds = 1 << 18; // ~256 milliseconds.
104 int64 max_sleep_time_usecs = 1 << 10; // ~1 milliseconds.
[email protected]eaec38c2010-11-29 19:30:23105 int64 double_sleep_time = 0;
[email protected]d6fc9fd2009-10-27 18:03:47106
107 // If the process hasn't exited yet, then sleep and try again.
[email protected]2d9bb0222010-04-02 08:24:01108 Time wakeup_time = Time::Now() +
109 TimeDelta::FromMilliseconds(wait_milliseconds);
[email protected]d6fc9fd2009-10-27 18:03:47110 while (ret_pid == 0) {
111 Time now = Time::Now();
112 if (now > wakeup_time)
113 break;
114 // Guaranteed to be non-negative!
115 int64 sleep_time_usecs = (wakeup_time - now).InMicroseconds();
[email protected]2d9bb0222010-04-02 08:24:01116 // Sleep for a bit while we wait for the process to finish.
117 if (sleep_time_usecs > max_sleep_time_usecs)
118 sleep_time_usecs = max_sleep_time_usecs;
[email protected]d6fc9fd2009-10-27 18:03:47119
120 // usleep() will return 0 and set errno to EINTR on receipt of a signal
121 // such as SIGCHLD.
122 usleep(sleep_time_usecs);
[email protected]eaec38c2010-11-29 19:30:23123 ret_pid = HANDLE_EINTR(waitpid(handle, &status, WNOHANG));
[email protected]2d9bb0222010-04-02 08:24:01124
125 if ((max_sleep_time_usecs < kMaxSleepInMicroseconds) &&
126 (double_sleep_time++ % 4 == 0)) {
127 max_sleep_time_usecs *= 2;
128 }
[email protected]d6fc9fd2009-10-27 18:03:47129 }
130
[email protected]eaec38c2010-11-29 19:30:23131 if (success)
132 *success = (ret_pid != -1);
133
134 return status;
[email protected]d6fc9fd2009-10-27 18:03:47135}
136
[email protected]1e932112011-06-29 20:53:22137// Android has built-in crash handling.
138#if !defined(OS_ANDROID)
[email protected]7e3edc22010-11-22 22:31:00139void StackDumpSignalHandler(int signal, siginfo_t* info, ucontext_t* context) {
[email protected]72e243662011-06-11 00:46:10140 if (debug::BeingDebugged())
141 debug::BreakDebugger();
142
[email protected]a42d4632011-10-26 21:48:00143 DLOG(ERROR) << "Received signal " << signal;
[email protected]58580352010-10-26 04:07:50144 debug::StackTrace().PrintBacktrace();
[email protected]7e3edc22010-11-22 22:31:00145
146 // TODO(shess): Port to Linux.
147#if defined(OS_MACOSX)
148 // TODO(shess): Port to 64-bit.
149#if ARCH_CPU_32_BITS
150 char buf[1024];
151 size_t len;
152
153 // NOTE: Even |snprintf()| is not on the approved list for signal
154 // handlers, but buffered I/O is definitely not on the list due to
155 // potential for |malloc()|.
156 len = static_cast<size_t>(
157 snprintf(buf, sizeof(buf),
158 "ax: %x, bx: %x, cx: %x, dx: %x\n",
159 context->uc_mcontext->__ss.__eax,
160 context->uc_mcontext->__ss.__ebx,
161 context->uc_mcontext->__ss.__ecx,
162 context->uc_mcontext->__ss.__edx));
163 write(STDERR_FILENO, buf, std::min(len, sizeof(buf) - 1));
164
165 len = static_cast<size_t>(
166 snprintf(buf, sizeof(buf),
167 "di: %x, si: %x, bp: %x, sp: %x, ss: %x, flags: %x\n",
168 context->uc_mcontext->__ss.__edi,
169 context->uc_mcontext->__ss.__esi,
170 context->uc_mcontext->__ss.__ebp,
171 context->uc_mcontext->__ss.__esp,
172 context->uc_mcontext->__ss.__ss,
173 context->uc_mcontext->__ss.__eflags));
174 write(STDERR_FILENO, buf, std::min(len, sizeof(buf) - 1));
175
176 len = static_cast<size_t>(
177 snprintf(buf, sizeof(buf),
178 "ip: %x, cs: %x, ds: %x, es: %x, fs: %x, gs: %x\n",
179 context->uc_mcontext->__ss.__eip,
180 context->uc_mcontext->__ss.__cs,
181 context->uc_mcontext->__ss.__ds,
182 context->uc_mcontext->__ss.__es,
183 context->uc_mcontext->__ss.__fs,
184 context->uc_mcontext->__ss.__gs));
185 write(STDERR_FILENO, buf, std::min(len, sizeof(buf) - 1));
186#endif // ARCH_CPU_32_BITS
187#endif // defined(OS_MACOSX)
[email protected]d6fc9fd2009-10-27 18:03:47188 _exit(1);
189}
[email protected]1e932112011-06-29 20:53:22190#endif // !defined(OS_ANDROID)
[email protected]d6fc9fd2009-10-27 18:03:47191
[email protected]620a0032010-09-04 02:32:59192void ResetChildSignalHandlersToDefaults() {
193 // The previous signal handlers are likely to be meaningless in the child's
194 // context so we reset them to the defaults for now. http://crbug.com/44953
[email protected]b25e61d2011-08-23 09:02:01195 // These signal handlers are set up at least in browser_main_posix.cc:
196 // BrowserMainPartsPosix::PreEarlyInitialization and process_util_posix.cc:
197 // EnableInProcessStackDumping.
[email protected]620a0032010-09-04 02:32:59198 signal(SIGHUP, SIG_DFL);
199 signal(SIGINT, SIG_DFL);
[email protected]ff09a4f2011-04-08 13:42:04200 signal(SIGILL, SIG_DFL);
201 signal(SIGABRT, SIG_DFL);
202 signal(SIGFPE, SIG_DFL);
203 signal(SIGBUS, SIG_DFL);
204 signal(SIGSEGV, SIG_DFL);
205 signal(SIGSYS, SIG_DFL);
206 signal(SIGTERM, SIG_DFL);
[email protected]620a0032010-09-04 02:32:59207}
208
[email protected]fa289832010-03-19 20:30:30209} // anonymous namespace
[email protected]d6fc9fd2009-10-27 18:03:47210
[email protected]43cf3252009-04-01 09:19:37211ProcessId GetCurrentProcId() {
[email protected]3d5617e2008-08-27 14:36:19212 return getpid();
213}
214
[email protected]113ab132008-09-18 20:42:55215ProcessHandle GetCurrentProcessHandle() {
216 return GetCurrentProcId();
217}
218
[email protected]6c6cc802009-04-03 17:01:36219bool OpenProcessHandle(ProcessId pid, ProcessHandle* handle) {
[email protected]5986ed22009-02-06 00:19:17220 // On Posix platforms, process handles are the same as PIDs, so we
221 // don't need to do anything.
[email protected]6c6cc802009-04-03 17:01:36222 *handle = pid;
223 return true;
[email protected]5986ed22009-02-06 00:19:17224}
225
[email protected]5d438dbad2009-04-30 08:59:39226bool OpenPrivilegedProcessHandle(ProcessId pid, ProcessHandle* handle) {
227 // On POSIX permissions are checked for each operation on process,
228 // not when opening a "handle".
229 return OpenProcessHandle(pid, handle);
230}
231
[email protected]7d11f6d52010-10-12 21:44:23232bool OpenProcessHandleWithAccess(ProcessId pid,
233 uint32 access_flags,
234 ProcessHandle* handle) {
235 // On POSIX permissions are checked for each operation on process,
236 // not when opening a "handle".
237 return OpenProcessHandle(pid, handle);
238}
239
[email protected]5986ed22009-02-06 00:19:17240void CloseProcessHandle(ProcessHandle process) {
241 // See OpenProcessHandle, nothing to do.
242 return;
243}
244
[email protected]43cf3252009-04-01 09:19:37245ProcessId GetProcId(ProcessHandle process) {
[email protected]fadb8ea2008-08-27 15:36:37246 return process;
[email protected]3d5617e2008-08-27 14:36:19247}
[email protected]fadb8ea2008-08-27 15:36:37248
[email protected]8cf7cebd2009-01-05 19:53:30249// Attempts to kill the process identified by the given process
250// entry structure. Ignores specified exit_code; posix can't force that.
251// Returns true if this is successful, false otherwise.
[email protected]cd4fd152009-02-09 19:28:41252bool KillProcess(ProcessHandle process_id, int exit_code, bool wait) {
[email protected]9610ef242009-11-18 02:41:26253 DCHECK_GT(process_id, 1) << " tried to kill invalid process_id";
254 if (process_id <= 1)
[email protected]9fd697a2009-07-07 14:00:59255 return false;
[email protected]f2d2ec22010-08-13 15:13:04256 static unsigned kMaxSleepMs = 1000;
257 unsigned sleep_ms = 4;
[email protected]9fd697a2009-07-07 14:00:59258
[email protected]140a7cd2009-04-28 01:37:23259 bool result = kill(process_id, SIGTERM) == 0;
[email protected]8cf7cebd2009-01-05 19:53:30260
[email protected]140a7cd2009-04-28 01:37:23261 if (result && wait) {
[email protected]8cf7cebd2009-01-05 19:53:30262 int tries = 60;
[email protected]2f7a6ea2011-06-18 11:49:27263
264 if (RunningOnValgrind()) {
265 // Wait for some extra time when running under Valgrind since the child
266 // processes may take some time doing leak checking.
267 tries *= 2;
268 }
269
[email protected]8cf7cebd2009-01-05 19:53:30270 // The process may not end immediately due to pending I/O
[email protected]d24423742009-07-13 23:31:28271 bool exited = false;
[email protected]8cf7cebd2009-01-05 19:53:30272 while (tries-- > 0) {
[email protected]a4dc33f2009-10-20 15:09:55273 pid_t pid = HANDLE_EINTR(waitpid(process_id, NULL, WNOHANG));
[email protected]d24423742009-07-13 23:31:28274 if (pid == process_id) {
275 exited = true;
[email protected]8cf7cebd2009-01-05 19:53:30276 break;
[email protected]d24423742009-07-13 23:31:28277 }
[email protected]bf4878d2010-06-16 20:12:01278 if (pid == -1) {
279 if (errno == ECHILD) {
280 // The wait may fail with ECHILD if another process also waited for
281 // the same pid, causing the process state to get cleaned up.
282 exited = true;
283 break;
284 }
285 DPLOG(ERROR) << "Error waiting for process " << process_id;
286 }
[email protected]140a7cd2009-04-28 01:37:23287
[email protected]f2d2ec22010-08-13 15:13:04288 usleep(sleep_ms * 1000);
289 if (sleep_ms < kMaxSleepMs)
290 sleep_ms *= 2;
[email protected]8cf7cebd2009-01-05 19:53:30291 }
[email protected]140a7cd2009-04-28 01:37:23292
[email protected]443b80e2010-12-14 00:42:23293 // If we're waiting and the child hasn't died by now, force it
294 // with a SIGKILL.
[email protected]32cd5302009-11-20 19:30:59295 if (!exited)
[email protected]d24423742009-07-13 23:31:28296 result = kill(process_id, SIGKILL) == 0;
[email protected]8cf7cebd2009-01-05 19:53:30297 }
[email protected]140a7cd2009-04-28 01:37:23298
[email protected]32cd5302009-11-20 19:30:59299 if (!result)
300 DPLOG(ERROR) << "Unable to terminate process " << process_id;
[email protected]140a7cd2009-04-28 01:37:23301
[email protected]8cf7cebd2009-01-05 19:53:30302 return result;
303}
304
[email protected]61b93f88f2010-09-22 17:28:30305bool KillProcessGroup(ProcessHandle process_group_id) {
306 bool result = kill(-1 * process_group_id, SIGKILL) == 0;
307 if (!result)
[email protected]a42d4632011-10-26 21:48:00308 DPLOG(ERROR) << "Unable to terminate process group " << process_group_id;
[email protected]61b93f88f2010-09-22 17:28:30309 return result;
310}
311
[email protected]05d4b0a2009-01-29 17:51:51312// A class to handle auto-closing of DIR*'s.
313class ScopedDIRClose {
314 public:
315 inline void operator()(DIR* x) const {
316 if (x) {
317 closedir(x);
318 }
319 }
320};
321typedef scoped_ptr_malloc<DIR, ScopedDIRClose> ScopedDIR;
322
[email protected]aec92f832009-05-06 16:40:12323#if defined(OS_LINUX)
324 static const rlim_t kSystemDefaultMaxFds = 8192;
[email protected]ef73044e2010-03-11 15:25:54325 static const char kFDDir[] = "/proc/self/fd";
[email protected]aec92f832009-05-06 16:40:12326#elif defined(OS_MACOSX)
327 static const rlim_t kSystemDefaultMaxFds = 256;
[email protected]ef73044e2010-03-11 15:25:54328 static const char kFDDir[] = "/dev/fd";
[email protected]a1208912010-02-17 14:15:08329#elif defined(OS_SOLARIS)
330 static const rlim_t kSystemDefaultMaxFds = 8192;
[email protected]ef73044e2010-03-11 15:25:54331 static const char kFDDir[] = "/dev/fd";
[email protected]4a34ce02009-08-31 22:25:00332#elif defined(OS_FREEBSD)
333 static const rlim_t kSystemDefaultMaxFds = 8192;
[email protected]ef73044e2010-03-11 15:25:54334 static const char kFDDir[] = "/dev/fd";
[email protected]8d578822010-01-25 23:54:54335#elif defined(OS_OPENBSD)
336 static const rlim_t kSystemDefaultMaxFds = 256;
[email protected]ef73044e2010-03-11 15:25:54337 static const char kFDDir[] = "/dev/fd";
[email protected]1e932112011-06-29 20:53:22338#elif defined(OS_ANDROID)
339 static const rlim_t kSystemDefaultMaxFds = 1024;
340 static const char kFDDir[] = "/proc/self/fd";
[email protected]aec92f832009-05-06 16:40:12341#endif
[email protected]ef73044e2010-03-11 15:25:54342
343void CloseSuperfluousFds(const base::InjectiveMultimap& saved_mapping) {
344 // DANGER: no calls to malloc are allowed from now on:
345 // http://crbug.com/36678
[email protected]3f04f2b2009-04-30 19:40:03346
[email protected]aec92f832009-05-06 16:40:12347 // Get the maximum number of FDs possible.
348 struct rlimit nofile;
349 rlim_t max_fds;
350 if (getrlimit(RLIMIT_NOFILE, &nofile)) {
351 // getrlimit failed. Take a best guess.
352 max_fds = kSystemDefaultMaxFds;
[email protected]ff09a4f2011-04-08 13:42:04353 RAW_LOG(ERROR, "getrlimit(RLIMIT_NOFILE) failed");
[email protected]aec92f832009-05-06 16:40:12354 } else {
355 max_fds = nofile.rlim_cur;
356 }
357
358 if (max_fds > INT_MAX)
359 max_fds = INT_MAX;
360
[email protected]ef73044e2010-03-11 15:25:54361 DirReaderPosix fd_dir(kFDDir);
[email protected]3f04f2b2009-04-30 19:40:03362
[email protected]ef73044e2010-03-11 15:25:54363 if (!fd_dir.IsValid()) {
[email protected]aec92f832009-05-06 16:40:12364 // Fallback case: Try every possible fd.
365 for (rlim_t i = 0; i < max_fds; ++i) {
[email protected]3f04f2b2009-04-30 19:40:03366 const int fd = static_cast<int>(i);
[email protected]ef73044e2010-03-11 15:25:54367 if (fd == STDIN_FILENO || fd == STDOUT_FILENO || fd == STDERR_FILENO)
368 continue;
[email protected]40350b12010-03-30 17:29:27369 InjectiveMultimap::const_iterator j;
370 for (j = saved_mapping.begin(); j != saved_mapping.end(); j++) {
371 if (fd == j->dest)
[email protected]ef73044e2010-03-11 15:25:54372 break;
373 }
[email protected]40350b12010-03-30 17:29:27374 if (j != saved_mapping.end())
[email protected]3f04f2b2009-04-30 19:40:03375 continue;
376
[email protected]cabe39c2010-02-02 02:28:16377 // Since we're just trying to close anything we can find,
378 // ignore any error return values of close().
[email protected]ff09a4f2011-04-08 13:42:04379 ignore_result(HANDLE_EINTR(close(fd)));
[email protected]3f04f2b2009-04-30 19:40:03380 }
381 return;
382 }
383
[email protected]ef73044e2010-03-11 15:25:54384 const int dir_fd = fd_dir.fd();
385
386 for ( ; fd_dir.Next(); ) {
[email protected]3f04f2b2009-04-30 19:40:03387 // Skip . and .. entries.
[email protected]ef73044e2010-03-11 15:25:54388 if (fd_dir.name()[0] == '.')
[email protected]3f04f2b2009-04-30 19:40:03389 continue;
390
391 char *endptr;
392 errno = 0;
[email protected]ef73044e2010-03-11 15:25:54393 const long int fd = strtol(fd_dir.name(), &endptr, 10);
394 if (fd_dir.name()[0] == 0 || *endptr || fd < 0 || errno)
[email protected]3f04f2b2009-04-30 19:40:03395 continue;
[email protected]ef73044e2010-03-11 15:25:54396 if (fd == STDIN_FILENO || fd == STDOUT_FILENO || fd == STDERR_FILENO)
397 continue;
398 InjectiveMultimap::const_iterator i;
399 for (i = saved_mapping.begin(); i != saved_mapping.end(); i++) {
400 if (fd == i->dest)
401 break;
402 }
403 if (i != saved_mapping.end())
[email protected]3f04f2b2009-04-30 19:40:03404 continue;
[email protected]699de0b2009-06-07 23:03:08405 if (fd == dir_fd)
406 continue;
[email protected]3f04f2b2009-04-30 19:40:03407
[email protected]aec92f832009-05-06 16:40:12408 // When running under Valgrind, Valgrind opens several FDs for its
409 // own use and will complain if we try to close them. All of
410 // these FDs are >= |max_fds|, so we can check against that here
411 // before closing. See https://bugs.kde.org/show_bug.cgi?id=191758
[email protected]cabe39c2010-02-02 02:28:16412 if (fd < static_cast<int>(max_fds)) {
413 int ret = HANDLE_EINTR(close(fd));
414 DPCHECK(ret == 0);
415 }
[email protected]3f04f2b2009-04-30 19:40:03416 }
417}
418
[email protected]a82af392012-02-24 04:40:20419char** AlterEnvironment(const EnvironmentVector& changes,
[email protected]ef73044e2010-03-11 15:25:54420 const char* const* const env) {
421 unsigned count = 0;
422 unsigned size = 0;
423
424 // First assume that all of the current environment will be included.
425 for (unsigned i = 0; env[i]; i++) {
426 const char *const pair = env[i];
427 count++;
428 size += strlen(pair) + 1 /* terminating NUL */;
429 }
430
[email protected]a82af392012-02-24 04:40:20431 for (EnvironmentVector::const_iterator j = changes.begin();
432 j != changes.end();
433 ++j) {
[email protected]ef73044e2010-03-11 15:25:54434 bool found = false;
435 const char *pair;
436
437 for (unsigned i = 0; env[i]; i++) {
438 pair = env[i];
439 const char *const equals = strchr(pair, '=');
440 if (!equals)
441 continue;
442 const unsigned keylen = equals - pair;
443 if (keylen == j->first.size() &&
444 memcmp(pair, j->first.data(), keylen) == 0) {
445 found = true;
446 break;
447 }
448 }
449
450 // if found, we'll either be deleting or replacing this element.
451 if (found) {
452 count--;
453 size -= strlen(pair) + 1;
454 if (j->second.size())
455 found = false;
456 }
457
458 // if !found, then we have a new element to add.
[email protected]6775e40a2011-03-04 21:03:47459 if (!found && !j->second.empty()) {
[email protected]ef73044e2010-03-11 15:25:54460 count++;
461 size += j->first.size() + 1 /* '=' */ + j->second.size() + 1 /* NUL */;
462 }
463 }
464
465 count++; // for the final NULL
466 uint8_t *buffer = new uint8_t[sizeof(char*) * count + size];
467 char **const ret = reinterpret_cast<char**>(buffer);
468 unsigned k = 0;
469 char *scratch = reinterpret_cast<char*>(buffer + sizeof(char*) * count);
470
471 for (unsigned i = 0; env[i]; i++) {
472 const char *const pair = env[i];
473 const char *const equals = strchr(pair, '=');
474 if (!equals) {
475 const unsigned len = strlen(pair);
476 ret[k++] = scratch;
477 memcpy(scratch, pair, len + 1);
478 scratch += len + 1;
479 continue;
480 }
481 const unsigned keylen = equals - pair;
482 bool handled = false;
[email protected]a82af392012-02-24 04:40:20483 for (EnvironmentVector::const_iterator
[email protected]ef73044e2010-03-11 15:25:54484 j = changes.begin(); j != changes.end(); j++) {
485 if (j->first.size() == keylen &&
486 memcmp(j->first.data(), pair, keylen) == 0) {
487 if (!j->second.empty()) {
488 ret[k++] = scratch;
489 memcpy(scratch, pair, keylen + 1);
490 scratch += keylen + 1;
491 memcpy(scratch, j->second.c_str(), j->second.size() + 1);
492 scratch += j->second.size() + 1;
493 }
494 handled = true;
495 break;
496 }
497 }
498
499 if (!handled) {
500 const unsigned len = strlen(pair);
501 ret[k++] = scratch;
502 memcpy(scratch, pair, len + 1);
503 scratch += len + 1;
504 }
505 }
506
507 // Now handle new elements
[email protected]a82af392012-02-24 04:40:20508 for (EnvironmentVector::const_iterator
[email protected]ef73044e2010-03-11 15:25:54509 j = changes.begin(); j != changes.end(); j++) {
[email protected]f6b8ce32011-03-02 00:03:18510 if (j->second.empty())
[email protected]ef73044e2010-03-11 15:25:54511 continue;
512
513 bool found = false;
514 for (unsigned i = 0; env[i]; i++) {
515 const char *const pair = env[i];
516 const char *const equals = strchr(pair, '=');
517 if (!equals)
518 continue;
519 const unsigned keylen = equals - pair;
520 if (keylen == j->first.size() &&
521 memcmp(pair, j->first.data(), keylen) == 0) {
522 found = true;
523 break;
524 }
525 }
526
527 if (!found) {
528 ret[k++] = scratch;
529 memcpy(scratch, j->first.data(), j->first.size());
530 scratch += j->first.size();
531 *scratch++ = '=';
532 memcpy(scratch, j->second.c_str(), j->second.size() + 1);
533 scratch += j->second.size() + 1;
534 }
535 }
536
537 ret[k] = NULL;
538 return ret;
539}
540
[email protected]898a81a2011-06-30 22:56:15541bool LaunchProcess(const std::vector<std::string>& argv,
[email protected]e5992182011-07-15 16:47:02542 const LaunchOptions& options,
543 ProcessHandle* process_handle) {
[email protected]84b2d1d2011-09-01 21:44:24544 size_t fd_shuffle_size = 0;
[email protected]898a81a2011-06-30 22:56:15545 if (options.fds_to_remap) {
[email protected]84b2d1d2011-09-01 21:44:24546 fd_shuffle_size = options.fds_to_remap->size();
[email protected]898a81a2011-06-30 22:56:15547 }
[email protected]84b2d1d2011-09-01 21:44:24548
549#if defined(OS_MACOSX)
550 if (options.synchronize) {
551 // When synchronizing, the "read" end of the synchronization pipe needs
552 // to make it to the child process. This is handled by mapping it back to
553 // itself.
554 ++fd_shuffle_size;
555 }
556#endif // defined(OS_MACOSX)
557
558 InjectiveMultimap fd_shuffle1;
559 InjectiveMultimap fd_shuffle2;
560 fd_shuffle1.reserve(fd_shuffle_size);
561 fd_shuffle2.reserve(fd_shuffle_size);
562
[email protected]ef73044e2010-03-11 15:25:54563 scoped_array<char*> argv_cstr(new char*[argv.size() + 1]);
[email protected]898a81a2011-06-30 22:56:15564 scoped_array<char*> new_environ;
565 if (options.environ)
566 new_environ.reset(AlterEnvironment(*options.environ, GetEnvironment()));
[email protected]ef73044e2010-03-11 15:25:54567
[email protected]84b2d1d2011-09-01 21:44:24568#if defined(OS_MACOSX)
569 int synchronization_pipe_fds[2];
570 file_util::ScopedFD synchronization_read_fd;
571 file_util::ScopedFD synchronization_write_fd;
572
573 if (options.synchronize) {
574 // wait means "don't return from LaunchProcess until the child exits", and
575 // synchronize means "return from LaunchProcess but don't let the child
576 // run until LaunchSynchronize is called". These two options are highly
577 // incompatible.
[email protected]a42d4632011-10-26 21:48:00578 DCHECK(!options.wait);
[email protected]84b2d1d2011-09-01 21:44:24579
580 // Create the pipe used for synchronization.
581 if (HANDLE_EINTR(pipe(synchronization_pipe_fds)) != 0) {
[email protected]a42d4632011-10-26 21:48:00582 DPLOG(ERROR) << "pipe";
[email protected]84b2d1d2011-09-01 21:44:24583 return false;
584 }
585
586 // The parent process will only use synchronization_write_fd as the write
587 // side of the pipe. It can close the read side as soon as the child
588 // process has forked off. The child process will only use
589 // synchronization_read_fd as the read side of the pipe. In that process,
590 // the write side can be closed as soon as it has forked.
591 synchronization_read_fd.reset(&synchronization_pipe_fds[0]);
592 synchronization_write_fd.reset(&synchronization_pipe_fds[1]);
593 }
594#endif // OS_MACOSX
595
596 pid_t pid;
[email protected]ca7c4562011-07-15 23:55:21597#if defined(OS_LINUX)
[email protected]84b2d1d2011-09-01 21:44:24598 if (options.clone_flags) {
[email protected]ca7c4562011-07-15 23:55:21599 pid = syscall(__NR_clone, options.clone_flags, 0, 0, 0);
[email protected]84b2d1d2011-09-01 21:44:24600 } else
[email protected]ca7c4562011-07-15 23:55:21601#endif
[email protected]84b2d1d2011-09-01 21:44:24602 {
[email protected]ca7c4562011-07-15 23:55:21603 pid = fork();
604 }
[email protected]84b2d1d2011-09-01 21:44:24605
[email protected]56f0f262011-02-24 17:14:36606 if (pid < 0) {
[email protected]a42d4632011-10-26 21:48:00607 DPLOG(ERROR) << "fork";
[email protected]2aea9e092009-08-06 20:03:01608 return false;
[email protected]84b2d1d2011-09-01 21:44:24609 } else if (pid == 0) {
[email protected]2aea9e092009-08-06 20:03:01610 // Child process
[email protected]61b93f88f2010-09-22 17:28:30611
[email protected]ff09a4f2011-04-08 13:42:04612 // DANGER: fork() rule: in the child, if you don't end up doing exec*(),
613 // you call _exit() instead of exit(). This is because _exit() does not
614 // call any previously-registered (in the parent) exit handlers, which
615 // might do things like block waiting for threads that don't even exist
616 // in the child.
617
[email protected]955b7392011-03-09 00:49:20618 // If a child process uses the readline library, the process block forever.
619 // In BSD like OSes including OS X it is safe to assign /dev/null as stdin.
620 // See http://crbug.com/56596.
621 int null_fd = HANDLE_EINTR(open("/dev/null", O_RDONLY));
622 if (null_fd < 0) {
[email protected]ff09a4f2011-04-08 13:42:04623 RAW_LOG(ERROR, "Failed to open /dev/null");
624 _exit(127);
625 }
626
627 file_util::ScopedFD null_fd_closer(&null_fd);
628 int new_fd = HANDLE_EINTR(dup2(null_fd, STDIN_FILENO));
629 if (new_fd != STDIN_FILENO) {
630 RAW_LOG(ERROR, "Failed to dup /dev/null for stdin");
631 _exit(127);
[email protected]955b7392011-03-09 00:49:20632 }
633
[email protected]898a81a2011-06-30 22:56:15634 if (options.new_process_group) {
[email protected]61b93f88f2010-09-22 17:28:30635 // Instead of inheriting the process group ID of the parent, the child
636 // starts off a new process group with pgid equal to its process ID.
[email protected]56f0f262011-02-24 17:14:36637 if (setpgid(0, 0) < 0) {
[email protected]ff09a4f2011-04-08 13:42:04638 RAW_LOG(ERROR, "setpgid failed");
639 _exit(127);
[email protected]56f0f262011-02-24 17:14:36640 }
[email protected]61b93f88f2010-09-22 17:28:30641 }
[email protected]84b2d1d2011-09-01 21:44:24642
[email protected]77540fdf2011-11-15 18:49:10643 if (options.maximize_rlimits) {
644 // Some resource limits need to be maximal in this child.
645 std::set<int>::const_iterator resource;
646 for (resource = options.maximize_rlimits->begin();
647 resource != options.maximize_rlimits->end();
648 ++resource) {
649 struct rlimit limit;
650 if (getrlimit(*resource, &limit) < 0) {
651 RAW_LOG(WARNING, "getrlimit failed");
652 } else if (limit.rlim_cur < limit.rlim_max) {
653 limit.rlim_cur = limit.rlim_max;
654 if (setrlimit(*resource, &limit) < 0) {
655 RAW_LOG(WARNING, "setrlimit failed");
656 }
657 }
658 }
659 }
660
[email protected]e9a8c19f2009-09-03 21:27:36661#if defined(OS_MACOSX)
662 RestoreDefaultExceptionHandler();
[email protected]84b2d1d2011-09-01 21:44:24663#endif // defined(OS_MACOSX)
[email protected]e9a8c19f2009-09-03 21:27:36664
[email protected]620a0032010-09-04 02:32:59665 ResetChildSignalHandlersToDefaults();
[email protected]01aa3cd2010-06-02 18:47:55666
[email protected]84b2d1d2011-09-01 21:44:24667#if defined(OS_MACOSX)
668 if (options.synchronize) {
669 // The "write" side of the synchronization pipe belongs to the parent.
670 synchronization_write_fd.reset(); // closes synchronization_pipe_fds[1]
671 }
672#endif // defined(OS_MACOSX)
673
[email protected]ef73044e2010-03-11 15:25:54674#if 0
675 // When debugging it can be helpful to check that we really aren't making
676 // any hidden calls to malloc.
677 void *malloc_thunk =
678 reinterpret_cast<void*>(reinterpret_cast<intptr_t>(malloc) & ~4095);
679 mprotect(malloc_thunk, 4096, PROT_READ | PROT_WRITE | PROT_EXEC);
680 memset(reinterpret_cast<void*>(malloc), 0xff, 8);
[email protected]84b2d1d2011-09-01 21:44:24681#endif // 0
[email protected]ef73044e2010-03-11 15:25:54682
683 // DANGER: no calls to malloc are allowed from now on:
684 // http://crbug.com/36678
685
[email protected]927054d2012-01-21 01:48:25686#if defined(OS_CHROMEOS)
687 if (options.ctrl_terminal_fd >= 0) {
688 // Set process' controlling terminal.
689 if (HANDLE_EINTR(setsid()) != -1) {
690 if (HANDLE_EINTR(
691 ioctl(options.ctrl_terminal_fd, TIOCSCTTY, NULL)) == -1) {
692 RAW_LOG(WARNING, "ioctl(TIOCSCTTY), ctrl terminal not set");
693 }
694 } else {
695 RAW_LOG(WARNING, "setsid failed, ctrl terminal not set");
696 }
697 }
698#endif // defined(OS_CHROMEOS)
699
[email protected]898a81a2011-06-30 22:56:15700 if (options.fds_to_remap) {
[email protected]a82af392012-02-24 04:40:20701 for (FileHandleMappingVector::const_iterator
[email protected]898a81a2011-06-30 22:56:15702 it = options.fds_to_remap->begin();
703 it != options.fds_to_remap->end(); ++it) {
704 fd_shuffle1.push_back(InjectionArc(it->first, it->second, false));
705 fd_shuffle2.push_back(InjectionArc(it->first, it->second, false));
706 }
[email protected]e6572302009-08-21 17:05:54707 }
[email protected]2aea9e092009-08-06 20:03:01708
[email protected]84b2d1d2011-09-01 21:44:24709#if defined(OS_MACOSX)
710 if (options.synchronize) {
711 // Remap the read side of the synchronization pipe back onto itself,
712 // ensuring that it won't be closed by CloseSuperfluousFds.
713 int keep_fd = *synchronization_read_fd.get();
714 fd_shuffle1.push_back(InjectionArc(keep_fd, keep_fd, false));
715 fd_shuffle2.push_back(InjectionArc(keep_fd, keep_fd, false));
716 }
717#endif // defined(OS_MACOSX)
718
[email protected]898a81a2011-06-30 22:56:15719 if (options.environ)
720 SetEnvironment(new_environ.get());
[email protected]2aea9e092009-08-06 20:03:01721
[email protected]ef73044e2010-03-11 15:25:54722 // fd_shuffle1 is mutated by this call because it cannot malloc.
723 if (!ShuffleFileDescriptors(&fd_shuffle1))
[email protected]2aea9e092009-08-06 20:03:01724 _exit(127);
725
[email protected]ef73044e2010-03-11 15:25:54726 CloseSuperfluousFds(fd_shuffle2);
[email protected]e6572302009-08-21 17:05:54727
[email protected]84b2d1d2011-09-01 21:44:24728#if defined(OS_MACOSX)
729 if (options.synchronize) {
730 // Do a blocking read to wait until the parent says it's OK to proceed.
731 // The byte that's read here is written by LaunchSynchronize.
732 char read_char;
733 int read_result =
734 HANDLE_EINTR(read(*synchronization_read_fd.get(), &read_char, 1));
735 if (read_result != 1) {
736 RAW_LOG(ERROR, "LaunchProcess: synchronization read: error");
737 _exit(127);
738 }
739
740 // The pipe is no longer useful. Don't let it live on in the new process
741 // after exec.
742 synchronization_read_fd.reset(); // closes synchronization_pipe_fds[0]
743 }
744#endif // defined(OS_MACOSX)
745
[email protected]e6572302009-08-21 17:05:54746 for (size_t i = 0; i < argv.size(); i++)
747 argv_cstr[i] = const_cast<char*>(argv[i].c_str());
748 argv_cstr[argv.size()] = NULL;
[email protected]2aea9e092009-08-06 20:03:01749 execvp(argv_cstr[0], argv_cstr.get());
[email protected]84b2d1d2011-09-01 21:44:24750
[email protected]075fb932011-07-19 16:31:28751 RAW_LOG(ERROR, "LaunchProcess: failed to execvp:");
[email protected]ef73044e2010-03-11 15:25:54752 RAW_LOG(ERROR, argv_cstr[0]);
[email protected]2aea9e092009-08-06 20:03:01753 _exit(127);
754 } else {
755 // Parent process
[email protected]898a81a2011-06-30 22:56:15756 if (options.wait) {
[email protected]b42c4652010-12-04 03:23:53757 // While this isn't strictly disk IO, waiting for another process to
758 // finish is the sort of thing ThreadRestrictions is trying to prevent.
759 base::ThreadRestrictions::AssertIOAllowed();
[email protected]cabe39c2010-02-02 02:28:16760 pid_t ret = HANDLE_EINTR(waitpid(pid, 0, 0));
761 DPCHECK(ret > 0);
762 }
[email protected]2aea9e092009-08-06 20:03:01763
[email protected]e5992182011-07-15 16:47:02764 if (process_handle)
765 *process_handle = pid;
[email protected]84b2d1d2011-09-01 21:44:24766
767#if defined(OS_MACOSX)
768 if (options.synchronize) {
769 // The "read" side of the synchronization pipe belongs to the child.
770 synchronization_read_fd.reset(); // closes synchronization_pipe_fds[0]
771 *options.synchronize = new int(*synchronization_write_fd.release());
772 }
773#endif // defined(OS_MACOSX)
[email protected]2aea9e092009-08-06 20:03:01774 }
775
776 return true;
777}
778
[email protected]84b2d1d2011-09-01 21:44:24779
[email protected]898a81a2011-06-30 22:56:15780bool LaunchProcess(const CommandLine& cmdline,
[email protected]e5992182011-07-15 16:47:02781 const LaunchOptions& options,
782 ProcessHandle* process_handle) {
783 return LaunchProcess(cmdline.argv(), options, process_handle);
[email protected]2aea9e092009-08-06 20:03:01784}
785
[email protected]84b2d1d2011-09-01 21:44:24786#if defined(OS_MACOSX)
787void LaunchSynchronize(LaunchSynchronizationHandle handle) {
788 int synchronization_fd = *handle;
789 file_util::ScopedFD synchronization_fd_closer(&synchronization_fd);
790 delete handle;
791
792 // Write a '\0' character to the pipe.
793 if (HANDLE_EINTR(write(synchronization_fd, "", 1)) != 1) {
[email protected]a42d4632011-10-26 21:48:00794 DPLOG(ERROR) << "write";
[email protected]84b2d1d2011-09-01 21:44:24795 }
796}
797#endif // defined(OS_MACOSX)
798
[email protected]0b100bc82008-10-14 20:49:16799ProcessMetrics::~ProcessMetrics() { }
800
[email protected]d6fc9fd2009-10-27 18:03:47801bool EnableInProcessStackDumping() {
802 // When running in an application, our code typically expects SIGPIPE
803 // to be ignored. Therefore, when testing that same code, it should run
804 // with SIGPIPE ignored as well.
805 struct sigaction action;
[email protected]2db7a1e52012-03-30 22:19:32806 memset(&action, 0, sizeof(action));
[email protected]d6fc9fd2009-10-27 18:03:47807 action.sa_handler = SIG_IGN;
[email protected]d6fc9fd2009-10-27 18:03:47808 sigemptyset(&action.sa_mask);
809 bool success = (sigaction(SIGPIPE, &action, NULL) == 0);
810
[email protected]1e932112011-06-29 20:53:22811 // Android has built-in crash handling, so no need to hook the signals.
812#if !defined(OS_ANDROID)
[email protected]7e3edc22010-11-22 22:31:00813 sig_t handler = reinterpret_cast<sig_t>(&StackDumpSignalHandler);
814 success &= (signal(SIGILL, handler) != SIG_ERR);
815 success &= (signal(SIGABRT, handler) != SIG_ERR);
816 success &= (signal(SIGFPE, handler) != SIG_ERR);
817 success &= (signal(SIGBUS, handler) != SIG_ERR);
818 success &= (signal(SIGSEGV, handler) != SIG_ERR);
819 success &= (signal(SIGSYS, handler) != SIG_ERR);
[email protected]1e932112011-06-29 20:53:22820#endif
[email protected]7e868c962010-04-30 06:24:37821
[email protected]d6fc9fd2009-10-27 18:03:47822 return success;
823}
824
[email protected]3d5617e2008-08-27 14:36:19825void RaiseProcessToHighPriority() {
826 // On POSIX, we don't actually do anything here. We could try to nice() or
827 // setpriority() or sched_getscheduler, but these all require extra rights.
828}
829
[email protected]443b80e2010-12-14 00:42:23830TerminationStatus GetTerminationStatus(ProcessHandle handle, int* exit_code) {
831 int status = 0;
[email protected]eaec38c2010-11-29 19:30:23832 const pid_t result = HANDLE_EINTR(waitpid(handle, &status, WNOHANG));
833 if (result == -1) {
[email protected]a42d4632011-10-26 21:48:00834 DPLOG(ERROR) << "waitpid(" << handle << ")";
[email protected]443b80e2010-12-14 00:42:23835 if (exit_code)
836 *exit_code = 0;
837 return TERMINATION_STATUS_NORMAL_TERMINATION;
[email protected]eaec38c2010-11-29 19:30:23838 } else if (result == 0) {
839 // the child hasn't exited yet.
[email protected]443b80e2010-12-14 00:42:23840 if (exit_code)
841 *exit_code = 0;
842 return TERMINATION_STATUS_STILL_RUNNING;
[email protected]9c19aa12009-01-21 13:50:11843 }
844
[email protected]443b80e2010-12-14 00:42:23845 if (exit_code)
846 *exit_code = status;
[email protected]140a7cd2009-04-28 01:37:23847
[email protected]9c19aa12009-01-21 13:50:11848 if (WIFSIGNALED(status)) {
[email protected]2fdc86a2010-01-26 23:08:02849 switch (WTERMSIG(status)) {
[email protected]22b61ba2010-10-19 18:25:47850 case SIGABRT:
[email protected]443b80e2010-12-14 00:42:23851 case SIGBUS:
[email protected]22b61ba2010-10-19 18:25:47852 case SIGFPE:
[email protected]443b80e2010-12-14 00:42:23853 case SIGILL:
854 case SIGSEGV:
855 return TERMINATION_STATUS_PROCESS_CRASHED;
856 case SIGINT:
857 case SIGKILL:
858 case SIGTERM:
859 return TERMINATION_STATUS_PROCESS_WAS_KILLED;
[email protected]9c19aa12009-01-21 13:50:11860 default:
[email protected]443b80e2010-12-14 00:42:23861 break;
[email protected]9c19aa12009-01-21 13:50:11862 }
863 }
864
[email protected]443b80e2010-12-14 00:42:23865 if (WIFEXITED(status) && WEXITSTATUS(status) != 0)
866 return TERMINATION_STATUS_ABNORMAL_TERMINATION;
[email protected]9c19aa12009-01-21 13:50:11867
[email protected]443b80e2010-12-14 00:42:23868 return TERMINATION_STATUS_NORMAL_TERMINATION;
[email protected]9c19aa12009-01-21 13:50:11869}
870
[email protected]c7856632009-01-13 17:38:49871bool WaitForExitCode(ProcessHandle handle, int* exit_code) {
872 int status;
[email protected]157c61b2009-05-01 21:37:31873 if (HANDLE_EINTR(waitpid(handle, &status, 0)) == -1) {
874 NOTREACHED();
875 return false;
[email protected]c7856632009-01-13 17:38:49876 }
877
878 if (WIFEXITED(status)) {
879 *exit_code = WEXITSTATUS(status);
880 return true;
881 }
882
883 // If it didn't exit cleanly, it must have been signaled.
884 DCHECK(WIFSIGNALED(status));
885 return false;
886}
887
[email protected]8004e682010-03-16 07:41:22888bool WaitForExitCodeWithTimeout(ProcessHandle handle, int* exit_code,
[email protected]6a1eea82012-07-26 23:41:41889 base::TimeDelta timeout) {
[email protected]eaec38c2010-11-29 19:30:23890 bool waitpid_success = false;
[email protected]6a1eea82012-07-26 23:41:41891 int status = WaitpidWithTimeout(handle, timeout.InMilliseconds(),
[email protected]eaec38c2010-11-29 19:30:23892 &waitpid_success);
893 if (status == -1)
894 return false;
895 if (!waitpid_success)
[email protected]8004e682010-03-16 07:41:22896 return false;
[email protected]8004e682010-03-16 07:41:22897 if (WIFSIGNALED(status)) {
898 *exit_code = -1;
899 return true;
900 }
[email protected]40bbe592011-04-06 12:18:20901 if (WIFEXITED(status)) {
902 *exit_code = WEXITSTATUS(status);
903 return true;
904 }
905 return false;
[email protected]8004e682010-03-16 07:41:22906}
907
[email protected]56f0f262011-02-24 17:14:36908#if defined(OS_MACOSX)
909// Using kqueue on Mac so that we can wait on non-child processes.
910// We can't use kqueues on child processes because we need to reap
911// our own children using wait.
912static bool WaitForSingleNonChildProcess(ProcessHandle handle,
[email protected]7e1117c2012-03-31 20:42:41913 base::TimeDelta wait) {
[email protected]6d780fd52011-08-22 23:27:11914 DCHECK_GT(handle, 0);
[email protected]7e1117c2012-03-31 20:42:41915 DCHECK(wait.InMilliseconds() == base::kNoTimeout || wait > base::TimeDelta());
[email protected]6d780fd52011-08-22 23:27:11916
[email protected]56f0f262011-02-24 17:14:36917 int kq = kqueue();
918 if (kq == -1) {
[email protected]a42d4632011-10-26 21:48:00919 DPLOG(ERROR) << "kqueue";
[email protected]56f0f262011-02-24 17:14:36920 return false;
921 }
[email protected]6d780fd52011-08-22 23:27:11922 file_util::ScopedFD kq_closer(&kq);
[email protected]56f0f262011-02-24 17:14:36923
[email protected]6d780fd52011-08-22 23:27:11924 struct kevent change = {0};
[email protected]56f0f262011-02-24 17:14:36925 EV_SET(&change, handle, EVFILT_PROC, EV_ADD, NOTE_EXIT, 0, NULL);
[email protected]6d780fd52011-08-22 23:27:11926 int result = HANDLE_EINTR(kevent(kq, &change, 1, NULL, 0, NULL));
927 if (result == -1) {
928 if (errno == ESRCH) {
929 // If the process wasn't found, it must be dead.
930 return true;
931 }
[email protected]56f0f262011-02-24 17:14:36932
[email protected]a42d4632011-10-26 21:48:00933 DPLOG(ERROR) << "kevent (setup " << handle << ")";
[email protected]6d780fd52011-08-22 23:27:11934 return false;
[email protected]56f0f262011-02-24 17:14:36935 }
936
[email protected]6d780fd52011-08-22 23:27:11937 // Keep track of the elapsed time to be able to restart kevent if it's
938 // interrupted.
[email protected]7e1117c2012-03-31 20:42:41939 bool wait_forever = wait.InMilliseconds() == base::kNoTimeout;
[email protected]6d780fd52011-08-22 23:27:11940 base::TimeDelta remaining_delta;
941 base::Time deadline;
942 if (!wait_forever) {
[email protected]7e1117c2012-03-31 20:42:41943 remaining_delta = wait;
[email protected]6d780fd52011-08-22 23:27:11944 deadline = base::Time::Now() + remaining_delta;
945 }
946
947 result = -1;
948 struct kevent event = {0};
949
[email protected]7e1117c2012-03-31 20:42:41950 while (wait_forever || remaining_delta > base::TimeDelta()) {
[email protected]6d780fd52011-08-22 23:27:11951 struct timespec remaining_timespec;
952 struct timespec* remaining_timespec_ptr;
953 if (wait_forever) {
954 remaining_timespec_ptr = NULL;
[email protected]56f0f262011-02-24 17:14:36955 } else {
[email protected]6d780fd52011-08-22 23:27:11956 remaining_timespec = remaining_delta.ToTimeSpec();
957 remaining_timespec_ptr = &remaining_timespec;
958 }
959
960 result = kevent(kq, NULL, 0, &event, 1, remaining_timespec_ptr);
961
962 if (result == -1 && errno == EINTR) {
963 if (!wait_forever) {
964 remaining_delta = deadline - base::Time::Now();
965 }
966 result = 0;
967 } else {
968 break;
[email protected]56f0f262011-02-24 17:14:36969 }
970 }
[email protected]6d780fd52011-08-22 23:27:11971
972 if (result < 0) {
[email protected]a42d4632011-10-26 21:48:00973 DPLOG(ERROR) << "kevent (wait " << handle << ")";
[email protected]6d780fd52011-08-22 23:27:11974 return false;
975 } else if (result > 1) {
[email protected]a42d4632011-10-26 21:48:00976 DLOG(ERROR) << "kevent (wait " << handle << "): unexpected result "
977 << result;
[email protected]6d780fd52011-08-22 23:27:11978 return false;
979 } else if (result == 0) {
980 // Timed out.
981 return false;
982 }
983
984 DCHECK_EQ(result, 1);
985
986 if (event.filter != EVFILT_PROC ||
987 (event.fflags & NOTE_EXIT) == 0 ||
988 event.ident != static_cast<uintptr_t>(handle)) {
[email protected]a42d4632011-10-26 21:48:00989 DLOG(ERROR) << "kevent (wait " << handle
990 << "): unexpected event: filter=" << event.filter
991 << ", fflags=" << event.fflags
992 << ", ident=" << event.ident;
[email protected]6d780fd52011-08-22 23:27:11993 return false;
994 }
995
996 return true;
[email protected]56f0f262011-02-24 17:14:36997}
998#endif // OS_MACOSX
999
[email protected]7e1117c2012-03-31 20:42:411000bool WaitForSingleProcess(ProcessHandle handle, base::TimeDelta wait) {
[email protected]56f0f262011-02-24 17:14:361001 ProcessHandle parent_pid = GetParentProcessId(handle);
1002 ProcessHandle our_pid = Process::Current().handle();
1003 if (parent_pid != our_pid) {
1004#if defined(OS_MACOSX)
1005 // On Mac we can wait on non child processes.
[email protected]7e1117c2012-03-31 20:42:411006 return WaitForSingleNonChildProcess(handle, wait);
[email protected]56f0f262011-02-24 17:14:361007#else
1008 // Currently on Linux we can't handle non child processes.
1009 NOTIMPLEMENTED();
1010#endif // OS_MACOSX
1011 }
[email protected]6d780fd52011-08-22 23:27:111012
[email protected]eaec38c2010-11-29 19:30:231013 bool waitpid_success;
[email protected]6d780fd52011-08-22 23:27:111014 int status = -1;
[email protected]7e1117c2012-03-31 20:42:411015 if (wait.InMilliseconds() == base::kNoTimeout) {
[email protected]eaec38c2010-11-29 19:30:231016 waitpid_success = (HANDLE_EINTR(waitpid(handle, &status, 0)) != -1);
[email protected]7e1117c2012-03-31 20:42:411017 } else {
1018 status = WaitpidWithTimeout(
1019 handle, wait.InMilliseconds(), &waitpid_success);
1020 }
[email protected]6d780fd52011-08-22 23:27:111021
[email protected]eaec38c2010-11-29 19:30:231022 if (status != -1) {
1023 DCHECK(waitpid_success);
1024 return WIFEXITED(status);
[email protected]ef0279272009-03-06 09:24:381025 } else {
[email protected]774f2202010-11-29 18:56:191026 return false;
[email protected]eaec38c2010-11-29 19:30:231027 }
[email protected]076bf0b62009-03-04 20:57:581028}
1029
[email protected]0d83c732008-12-02 16:50:471030int64 TimeValToMicroseconds(const struct timeval& tv) {
[email protected]2d9bb0222010-04-02 08:24:011031 static const int kMicrosecondsPerSecond = 1000000;
1032 int64 ret = tv.tv_sec; // Avoid (int * int) integer overflow.
1033 ret *= kMicrosecondsPerSecond;
1034 ret += tv.tv_usec;
1035 return ret;
[email protected]0d83c732008-12-02 16:50:471036}
1037
[email protected]d03b05c2011-07-06 06:14:481038// Return value used by GetAppOutputInternal to encapsulate the various exit
1039// scenarios from the function.
1040enum GetAppOutputInternalResult {
1041 EXECUTE_FAILURE,
1042 EXECUTE_SUCCESS,
1043 GOT_MAX_OUTPUT,
1044};
1045
[email protected]1a6ec692012-04-26 20:24:371046// Executes the application specified by |argv| and wait for it to exit. Stores
[email protected]3b9f5aa2010-07-28 04:02:341047// the output (stdout) in |output|. If |do_search_path| is set, it searches the
[email protected]f164cea2009-11-05 23:37:401048// path for the application; in that case, |envp| must be null, and it will use
[email protected]1a6ec692012-04-26 20:24:371049// the current environment. If |do_search_path| is false, |argv[0]| should fully
[email protected]f164cea2009-11-05 23:37:401050// specify the path of the application, and |envp| will be used as the
[email protected]d03b05c2011-07-06 06:14:481051// environment. Redirects stderr to /dev/null.
1052// If we successfully start the application and get all requested output, we
1053// return GOT_MAX_OUTPUT, or if there is a problem starting or exiting
1054// the application we return RUN_FAILURE. Otherwise we return EXECUTE_SUCCESS.
1055// The GOT_MAX_OUTPUT return value exists so a caller that asks for limited
1056// output can treat this as a success, despite having an exit code of SIG_PIPE
1057// due to us closing the output pipe.
1058// In the case of EXECUTE_SUCCESS, the application exit code will be returned
1059// in |*exit_code|, which should be checked to determine if the application
1060// ran successfully.
[email protected]1a6ec692012-04-26 20:24:371061static GetAppOutputInternalResult GetAppOutputInternal(
1062 const std::vector<std::string>& argv,
1063 char* const envp[],
1064 std::string* output,
1065 size_t max_output,
1066 bool do_search_path,
1067 int* exit_code) {
[email protected]b42c4652010-12-04 03:23:531068 // Doing a blocking wait for another command to finish counts as IO.
1069 base::ThreadRestrictions::AssertIOAllowed();
[email protected]d03b05c2011-07-06 06:14:481070 // exit_code must be supplied so calling function can determine success.
1071 DCHECK(exit_code);
1072 *exit_code = EXIT_FAILURE;
[email protected]b42c4652010-12-04 03:23:531073
[email protected]c0b210ee2009-04-17 09:57:521074 int pipe_fd[2];
1075 pid_t pid;
[email protected]ef73044e2010-03-11 15:25:541076 InjectiveMultimap fd_shuffle1, fd_shuffle2;
[email protected]ef73044e2010-03-11 15:25:541077 scoped_array<char*> argv_cstr(new char*[argv.size() + 1]);
1078
1079 fd_shuffle1.reserve(3);
1080 fd_shuffle2.reserve(3);
[email protected]c0b210ee2009-04-17 09:57:521081
[email protected]f164cea2009-11-05 23:37:401082 // Either |do_search_path| should be false or |envp| should be null, but not
1083 // both.
1084 DCHECK(!do_search_path ^ !envp);
1085
[email protected]c0b210ee2009-04-17 09:57:521086 if (pipe(pipe_fd) < 0)
[email protected]d03b05c2011-07-06 06:14:481087 return EXECUTE_FAILURE;
[email protected]c0b210ee2009-04-17 09:57:521088
1089 switch (pid = fork()) {
1090 case -1: // error
1091 close(pipe_fd[0]);
1092 close(pipe_fd[1]);
[email protected]d03b05c2011-07-06 06:14:481093 return EXECUTE_FAILURE;
[email protected]c0b210ee2009-04-17 09:57:521094 case 0: // child
1095 {
[email protected]e9a8c19f2009-09-03 21:27:361096#if defined(OS_MACOSX)
1097 RestoreDefaultExceptionHandler();
1098#endif
[email protected]ef73044e2010-03-11 15:25:541099 // DANGER: no calls to malloc are allowed from now on:
1100 // http://crbug.com/36678
[email protected]e9a8c19f2009-09-03 21:27:361101
[email protected]afa82472009-07-23 19:11:481102 // Obscure fork() rule: in the child, if you don't end up doing exec*(),
1103 // you call _exit() instead of exit(). This is because _exit() does not
1104 // call any previously-registered (in the parent) exit handlers, which
1105 // might do things like block waiting for threads that don't even exist
1106 // in the child.
[email protected]1912cfe2009-04-21 08:09:301107 int dev_null = open("/dev/null", O_WRONLY);
1108 if (dev_null < 0)
[email protected]7a97d292009-07-22 18:21:271109 _exit(127);
[email protected]1912cfe2009-04-21 08:09:301110
[email protected]ef73044e2010-03-11 15:25:541111 fd_shuffle1.push_back(InjectionArc(pipe_fd[1], STDOUT_FILENO, true));
1112 fd_shuffle1.push_back(InjectionArc(dev_null, STDERR_FILENO, true));
1113 fd_shuffle1.push_back(InjectionArc(dev_null, STDIN_FILENO, true));
[email protected]3b9f5aa2010-07-28 04:02:341114 // Adding another element here? Remeber to increase the argument to
[email protected]ef73044e2010-03-11 15:25:541115 // reserve(), above.
[email protected]3f04f2b2009-04-30 19:40:031116
[email protected]ef73044e2010-03-11 15:25:541117 std::copy(fd_shuffle1.begin(), fd_shuffle1.end(),
1118 std::back_inserter(fd_shuffle2));
1119
1120 if (!ShuffleFileDescriptors(&fd_shuffle1))
[email protected]7a97d292009-07-22 18:21:271121 _exit(127);
[email protected]3f04f2b2009-04-30 19:40:031122
[email protected]ef73044e2010-03-11 15:25:541123 CloseSuperfluousFds(fd_shuffle2);
[email protected]c0b210ee2009-04-17 09:57:521124
[email protected]c0b210ee2009-04-17 09:57:521125 for (size_t i = 0; i < argv.size(); i++)
1126 argv_cstr[i] = const_cast<char*>(argv[i].c_str());
1127 argv_cstr[argv.size()] = NULL;
[email protected]f164cea2009-11-05 23:37:401128 if (do_search_path)
1129 execvp(argv_cstr[0], argv_cstr.get());
1130 else
1131 execve(argv_cstr[0], argv_cstr.get(), envp);
[email protected]7a97d292009-07-22 18:21:271132 _exit(127);
[email protected]c0b210ee2009-04-17 09:57:521133 }
1134 default: // parent
1135 {
1136 // Close our writing end of pipe now. Otherwise later read would not
1137 // be able to detect end of child's output (in theory we could still
1138 // write to the pipe).
1139 close(pipe_fd[1]);
1140
[email protected]96878a212010-06-10 18:26:331141 output->clear();
[email protected]c0b210ee2009-04-17 09:57:521142 char buffer[256];
[email protected]983ef7f2010-01-04 16:17:131143 size_t output_buf_left = max_output;
[email protected]f164cea2009-11-05 23:37:401144 ssize_t bytes_read = 1; // A lie to properly handle |max_output == 0|
1145 // case in the logic below.
[email protected]c0b210ee2009-04-17 09:57:521146
[email protected]983ef7f2010-01-04 16:17:131147 while (output_buf_left > 0) {
[email protected]f164cea2009-11-05 23:37:401148 bytes_read = HANDLE_EINTR(read(pipe_fd[0], buffer,
[email protected]983ef7f2010-01-04 16:17:131149 std::min(output_buf_left, sizeof(buffer))));
[email protected]157c61b2009-05-01 21:37:311150 if (bytes_read <= 0)
[email protected]c0b210ee2009-04-17 09:57:521151 break;
[email protected]96878a212010-06-10 18:26:331152 output->append(buffer, bytes_read);
[email protected]983ef7f2010-01-04 16:17:131153 output_buf_left -= static_cast<size_t>(bytes_read);
[email protected]c0b210ee2009-04-17 09:57:521154 }
[email protected]c0b210ee2009-04-17 09:57:521155 close(pipe_fd[0]);
[email protected]affb1842009-06-10 16:56:311156
[email protected]d03b05c2011-07-06 06:14:481157 // Always wait for exit code (even if we know we'll declare
1158 // GOT_MAX_OUTPUT).
1159 bool success = WaitForExitCode(pid, exit_code);
[email protected]983ef7f2010-01-04 16:17:131160
[email protected]d03b05c2011-07-06 06:14:481161 // If we stopped because we read as much as we wanted, we return
1162 // GOT_MAX_OUTPUT (because the child may exit due to |SIGPIPE|).
1163 if (!output_buf_left && bytes_read > 0)
1164 return GOT_MAX_OUTPUT;
1165 else if (success)
1166 return EXECUTE_SUCCESS;
1167 return EXECUTE_FAILURE;
[email protected]c0b210ee2009-04-17 09:57:521168 }
1169 }
1170}
1171
[email protected]f164cea2009-11-05 23:37:401172bool GetAppOutput(const CommandLine& cl, std::string* output) {
[email protected]1a6ec692012-04-26 20:24:371173 return GetAppOutput(cl.argv(), output);
1174}
1175
1176bool GetAppOutput(const std::vector<std::string>& argv, std::string* output) {
[email protected]f164cea2009-11-05 23:37:401177 // Run |execve()| with the current environment and store "unlimited" data.
[email protected]d03b05c2011-07-06 06:14:481178 int exit_code;
1179 GetAppOutputInternalResult result = GetAppOutputInternal(
[email protected]1a6ec692012-04-26 20:24:371180 argv, NULL, output, std::numeric_limits<std::size_t>::max(), true,
[email protected]d03b05c2011-07-06 06:14:481181 &exit_code);
1182 return result == EXECUTE_SUCCESS && exit_code == EXIT_SUCCESS;
[email protected]f164cea2009-11-05 23:37:401183}
1184
[email protected]3b9f5aa2010-07-28 04:02:341185// TODO(viettrungluu): Conceivably, we should have a timeout as well, so we
1186// don't hang if what we're calling hangs.
[email protected]f164cea2009-11-05 23:37:401187bool GetAppOutputRestricted(const CommandLine& cl,
1188 std::string* output, size_t max_output) {
1189 // Run |execve()| with the empty environment.
1190 char* const empty_environ = NULL;
[email protected]d03b05c2011-07-06 06:14:481191 int exit_code;
[email protected]1a6ec692012-04-26 20:24:371192 GetAppOutputInternalResult result = GetAppOutputInternal(
1193 cl.argv(), &empty_environ, output, max_output, false, &exit_code);
[email protected]d03b05c2011-07-06 06:14:481194 return result == GOT_MAX_OUTPUT || (result == EXECUTE_SUCCESS &&
1195 exit_code == EXIT_SUCCESS);
1196}
1197
1198bool GetAppOutputWithExitCode(const CommandLine& cl,
1199 std::string* output,
1200 int* exit_code) {
1201 // Run |execve()| with the current environment and store "unlimited" data.
1202 GetAppOutputInternalResult result = GetAppOutputInternal(
[email protected]1a6ec692012-04-26 20:24:371203 cl.argv(), NULL, output, std::numeric_limits<std::size_t>::max(), true,
[email protected]d03b05c2011-07-06 06:14:481204 exit_code);
1205 return result == EXECUTE_SUCCESS;
[email protected]f164cea2009-11-05 23:37:401206}
1207
[email protected]4f260d02010-12-23 18:35:421208bool WaitForProcessesToExit(const FilePath::StringType& executable_name,
[email protected]6a1eea82012-07-26 23:41:411209 base::TimeDelta wait,
[email protected]962dd312009-02-05 21:44:131210 const ProcessFilter* filter) {
1211 bool result = false;
1212
1213 // TODO(port): This is inefficient, but works if there are multiple procs.
1214 // TODO(port): use waitpid to avoid leaving zombies around
1215
[email protected]6a1eea82012-07-26 23:41:411216 base::Time end_time = base::Time::Now() + wait;
[email protected]962dd312009-02-05 21:44:131217 do {
1218 NamedProcessIterator iter(executable_name, filter);
1219 if (!iter.NextProcessEntry()) {
1220 result = true;
1221 break;
1222 }
[email protected]a1b75b942011-12-31 22:53:511223 base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(100));
[email protected]1e932112011-06-29 20:53:221224 } while ((end_time - base::Time::Now()) > base::TimeDelta());
[email protected]962dd312009-02-05 21:44:131225
1226 return result;
1227}
1228
[email protected]4f260d02010-12-23 18:35:421229bool CleanupProcesses(const FilePath::StringType& executable_name,
[email protected]743ace42009-06-17 17:23:511230 int64 wait_milliseconds,
[email protected]962dd312009-02-05 21:44:131231 int exit_code,
1232 const ProcessFilter* filter) {
1233 bool exited_cleanly =
[email protected]2a0f1e82012-07-11 21:38:541234 WaitForProcessesToExit(
1235 executable_name,
1236 base::TimeDelta::FromMilliseconds(wait_milliseconds),
1237 filter);
[email protected]962dd312009-02-05 21:44:131238 if (!exited_cleanly)
1239 KillProcesses(executable_name, exit_code, filter);
1240 return exited_cleanly;
1241}
1242
[email protected]eaac71592011-11-23 18:32:001243#if !defined(OS_MACOSX)
1244
1245namespace {
1246
1247// Return true if the given child is dead. This will also reap the process.
1248// Doesn't block.
1249static bool IsChildDead(pid_t child) {
1250 const pid_t result = HANDLE_EINTR(waitpid(child, NULL, WNOHANG));
1251 if (result == -1) {
1252 DPLOG(ERROR) << "waitpid(" << child << ")";
1253 NOTREACHED();
1254 } else if (result > 0) {
1255 // The child has died.
1256 return true;
1257 }
1258
1259 return false;
1260}
1261
1262// A thread class which waits for the given child to exit and reaps it.
1263// If the child doesn't exit within a couple of seconds, kill it.
1264class BackgroundReaper : public PlatformThread::Delegate {
1265 public:
1266 BackgroundReaper(pid_t child, unsigned timeout)
1267 : child_(child),
1268 timeout_(timeout) {
1269 }
1270
1271 void ThreadMain() {
1272 WaitForChildToDie();
1273 delete this;
1274 }
1275
1276 void WaitForChildToDie() {
1277 // Wait forever case.
1278 if (timeout_ == 0) {
1279 pid_t r = HANDLE_EINTR(waitpid(child_, NULL, 0));
1280 if (r != child_) {
1281 DPLOG(ERROR) << "While waiting for " << child_
1282 << " to terminate, we got the following result: " << r;
1283 }
1284 return;
1285 }
1286
1287 // There's no good way to wait for a specific child to exit in a timed
1288 // fashion. (No kqueue on Linux), so we just loop and sleep.
1289
1290 // Wait for 2 * timeout_ 500 milliseconds intervals.
1291 for (unsigned i = 0; i < 2 * timeout_; ++i) {
[email protected]a1b75b942011-12-31 22:53:511292 PlatformThread::Sleep(TimeDelta::FromMilliseconds(500));
[email protected]eaac71592011-11-23 18:32:001293 if (IsChildDead(child_))
1294 return;
1295 }
1296
1297 if (kill(child_, SIGKILL) == 0) {
1298 // SIGKILL is uncatchable. Since the signal was delivered, we can
1299 // just wait for the process to die now in a blocking manner.
1300 if (HANDLE_EINTR(waitpid(child_, NULL, 0)) < 0)
1301 DPLOG(WARNING) << "waitpid";
1302 } else {
1303 DLOG(ERROR) << "While waiting for " << child_ << " to terminate we"
1304 << " failed to deliver a SIGKILL signal (" << errno << ").";
1305 }
1306 }
1307
1308 private:
1309 const pid_t child_;
1310 // Number of seconds to wait, if 0 then wait forever and do not attempt to
1311 // kill |child_|.
1312 const unsigned timeout_;
1313
1314 DISALLOW_COPY_AND_ASSIGN(BackgroundReaper);
1315};
1316
1317} // namespace
1318
1319void EnsureProcessTerminated(ProcessHandle process) {
1320 // If the child is already dead, then there's nothing to do.
1321 if (IsChildDead(process))
1322 return;
1323
1324 const unsigned timeout = 2; // seconds
1325 BackgroundReaper* reaper = new BackgroundReaper(process, timeout);
1326 PlatformThread::CreateNonJoinable(0, reaper);
1327}
1328
1329void EnsureProcessGetsReaped(ProcessHandle process) {
1330 // If the child is already dead, then there's nothing to do.
1331 if (IsChildDead(process))
1332 return;
1333
1334 BackgroundReaper* reaper = new BackgroundReaper(process, 0);
1335 PlatformThread::CreateNonJoinable(0, reaper);
1336}
1337
1338#endif // !defined(OS_MACOSX)
1339
[email protected]aa660752008-11-14 03:39:461340} // namespace base