process_util_posix.cc revision dc0f95d653279beabeb9817299e2902918ba123e
1// Copyright (c) 2010 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include <dirent.h>
6#include <errno.h>
7#include <fcntl.h>
8#include <signal.h>
9#include <stdlib.h>
10#include <sys/resource.h>
11#include <sys/time.h>
12#include <sys/types.h>
13#include <sys/wait.h>
14#include <unistd.h>
15
16#include <limits>
17#include <set>
18
19#include "base/command_line.h"
20#include "base/compiler_specific.h"
21#include "base/debug/stack_trace.h"
22#include "base/dir_reader_posix.h"
23#include "base/eintr_wrapper.h"
24#include "base/logging.h"
25#include "base/process_util.h"
26#include "base/scoped_ptr.h"
27#include "base/stringprintf.h"
28#include "base/synchronization/waitable_event.h"
29#include "base/threading/platform_thread.h"
30#include "base/threading/thread_restrictions.h"
31#include "base/time.h"
32
33#if defined(OS_MACOSX)
34#include <crt_externs.h>
35#include <sys/event.h>
36#define environ (*_NSGetEnviron())
37#else
38extern char** environ;
39#endif
40
41#ifdef ANDROID
42// No ucontext.h on Android
43typedef void ucontext_t;
44#endif
45
46namespace base {
47
48namespace {
49
50int WaitpidWithTimeout(ProcessHandle handle, int64 wait_milliseconds,
51                       bool* success) {
52  // This POSIX version of this function only guarantees that we wait no less
53  // than |wait_milliseconds| for the process to exit.  The child process may
54  // exit sometime before the timeout has ended but we may still block for up
55  // to 256 milliseconds after the fact.
56  //
57  // waitpid() has no direct support on POSIX for specifying a timeout, you can
58  // either ask it to block indefinitely or return immediately (WNOHANG).
59  // When a child process terminates a SIGCHLD signal is sent to the parent.
60  // Catching this signal would involve installing a signal handler which may
61  // affect other parts of the application and would be difficult to debug.
62  //
63  // Our strategy is to call waitpid() once up front to check if the process
64  // has already exited, otherwise to loop for wait_milliseconds, sleeping for
65  // at most 256 milliseconds each time using usleep() and then calling
66  // waitpid().  The amount of time we sleep starts out at 1 milliseconds, and
67  // we double it every 4 sleep cycles.
68  //
69  // usleep() is speced to exit if a signal is received for which a handler
70  // has been installed.  This means that when a SIGCHLD is sent, it will exit
71  // depending on behavior external to this function.
72  //
73  // This function is used primarily for unit tests, if we want to use it in
74  // the application itself it would probably be best to examine other routes.
75  int status = -1;
76  pid_t ret_pid = HANDLE_EINTR(waitpid(handle, &status, WNOHANG));
77  static const int64 kMaxSleepInMicroseconds = 1 << 18;  // ~256 milliseconds.
78  int64 max_sleep_time_usecs = 1 << 10;  // ~1 milliseconds.
79  int64 double_sleep_time = 0;
80
81  // If the process hasn't exited yet, then sleep and try again.
82  Time wakeup_time = Time::Now() +
83      TimeDelta::FromMilliseconds(wait_milliseconds);
84  while (ret_pid == 0) {
85    Time now = Time::Now();
86    if (now > wakeup_time)
87      break;
88    // Guaranteed to be non-negative!
89    int64 sleep_time_usecs = (wakeup_time - now).InMicroseconds();
90    // Sleep for a bit while we wait for the process to finish.
91    if (sleep_time_usecs > max_sleep_time_usecs)
92      sleep_time_usecs = max_sleep_time_usecs;
93
94    // usleep() will return 0 and set errno to EINTR on receipt of a signal
95    // such as SIGCHLD.
96    usleep(sleep_time_usecs);
97    ret_pid = HANDLE_EINTR(waitpid(handle, &status, WNOHANG));
98
99    if ((max_sleep_time_usecs < kMaxSleepInMicroseconds) &&
100        (double_sleep_time++ % 4 == 0)) {
101      max_sleep_time_usecs *= 2;
102    }
103  }
104
105  if (success)
106    *success = (ret_pid != -1);
107
108  return status;
109}
110
111void StackDumpSignalHandler(int signal, siginfo_t* info, ucontext_t* context) {
112  LOG(ERROR) << "Received signal " << signal;
113  debug::StackTrace().PrintBacktrace();
114
115  // TODO(shess): Port to Linux.
116#if defined(OS_MACOSX)
117  // TODO(shess): Port to 64-bit.
118#if ARCH_CPU_32_BITS
119  char buf[1024];
120  size_t len;
121
122  // NOTE: Even |snprintf()| is not on the approved list for signal
123  // handlers, but buffered I/O is definitely not on the list due to
124  // potential for |malloc()|.
125  len = static_cast<size_t>(
126      snprintf(buf, sizeof(buf),
127               "ax: %x, bx: %x, cx: %x, dx: %x\n",
128               context->uc_mcontext->__ss.__eax,
129               context->uc_mcontext->__ss.__ebx,
130               context->uc_mcontext->__ss.__ecx,
131               context->uc_mcontext->__ss.__edx));
132  write(STDERR_FILENO, buf, std::min(len, sizeof(buf) - 1));
133
134  len = static_cast<size_t>(
135      snprintf(buf, sizeof(buf),
136               "di: %x, si: %x, bp: %x, sp: %x, ss: %x, flags: %x\n",
137               context->uc_mcontext->__ss.__edi,
138               context->uc_mcontext->__ss.__esi,
139               context->uc_mcontext->__ss.__ebp,
140               context->uc_mcontext->__ss.__esp,
141               context->uc_mcontext->__ss.__ss,
142               context->uc_mcontext->__ss.__eflags));
143  write(STDERR_FILENO, buf, std::min(len, sizeof(buf) - 1));
144
145  len = static_cast<size_t>(
146      snprintf(buf, sizeof(buf),
147               "ip: %x, cs: %x, ds: %x, es: %x, fs: %x, gs: %x\n",
148               context->uc_mcontext->__ss.__eip,
149               context->uc_mcontext->__ss.__cs,
150               context->uc_mcontext->__ss.__ds,
151               context->uc_mcontext->__ss.__es,
152               context->uc_mcontext->__ss.__fs,
153               context->uc_mcontext->__ss.__gs));
154  write(STDERR_FILENO, buf, std::min(len, sizeof(buf) - 1));
155#endif  // ARCH_CPU_32_BITS
156#endif  // defined(OS_MACOSX)
157  _exit(1);
158}
159
160void ResetChildSignalHandlersToDefaults() {
161  // The previous signal handlers are likely to be meaningless in the child's
162  // context so we reset them to the defaults for now. http://crbug.com/44953
163  // These signal handlers are setup in browser_main.cc:BrowserMain
164  signal(SIGTERM, SIG_DFL);
165  signal(SIGHUP, SIG_DFL);
166  signal(SIGINT, SIG_DFL);
167}
168
169}  // anonymous namespace
170
171ProcessId GetCurrentProcId() {
172  return getpid();
173}
174
175ProcessHandle GetCurrentProcessHandle() {
176  return GetCurrentProcId();
177}
178
179bool OpenProcessHandle(ProcessId pid, ProcessHandle* handle) {
180  // On Posix platforms, process handles are the same as PIDs, so we
181  // don't need to do anything.
182  *handle = pid;
183  return true;
184}
185
186bool OpenPrivilegedProcessHandle(ProcessId pid, ProcessHandle* handle) {
187  // On POSIX permissions are checked for each operation on process,
188  // not when opening a "handle".
189  return OpenProcessHandle(pid, handle);
190}
191
192bool OpenProcessHandleWithAccess(ProcessId pid,
193                                 uint32 access_flags,
194                                 ProcessHandle* handle) {
195  // On POSIX permissions are checked for each operation on process,
196  // not when opening a "handle".
197  return OpenProcessHandle(pid, handle);
198}
199
200void CloseProcessHandle(ProcessHandle process) {
201  // See OpenProcessHandle, nothing to do.
202  return;
203}
204
205ProcessId GetProcId(ProcessHandle process) {
206  return process;
207}
208
209// Attempts to kill the process identified by the given process
210// entry structure.  Ignores specified exit_code; posix can't force that.
211// Returns true if this is successful, false otherwise.
212bool KillProcess(ProcessHandle process_id, int exit_code, bool wait) {
213  DCHECK_GT(process_id, 1) << " tried to kill invalid process_id";
214  if (process_id <= 1)
215    return false;
216  static unsigned kMaxSleepMs = 1000;
217  unsigned sleep_ms = 4;
218
219  bool result = kill(process_id, SIGTERM) == 0;
220
221  if (result && wait) {
222    int tries = 60;
223    // The process may not end immediately due to pending I/O
224    bool exited = false;
225    while (tries-- > 0) {
226      pid_t pid = HANDLE_EINTR(waitpid(process_id, NULL, WNOHANG));
227      if (pid == process_id) {
228        exited = true;
229        break;
230      }
231      if (pid == -1) {
232        if (errno == ECHILD) {
233          // The wait may fail with ECHILD if another process also waited for
234          // the same pid, causing the process state to get cleaned up.
235          exited = true;
236          break;
237        }
238        DPLOG(ERROR) << "Error waiting for process " << process_id;
239      }
240
241      usleep(sleep_ms * 1000);
242      if (sleep_ms < kMaxSleepMs)
243        sleep_ms *= 2;
244    }
245
246    // If we're waiting and the child hasn't died by now, force it
247    // with a SIGKILL.
248    if (!exited)
249      result = kill(process_id, SIGKILL) == 0;
250  }
251
252  if (!result)
253    DPLOG(ERROR) << "Unable to terminate process " << process_id;
254
255  return result;
256}
257
258bool KillProcessGroup(ProcessHandle process_group_id) {
259  bool result = kill(-1 * process_group_id, SIGKILL) == 0;
260  if (!result)
261    PLOG(ERROR) << "Unable to terminate process group " << process_group_id;
262  return result;
263}
264
265// A class to handle auto-closing of DIR*'s.
266class ScopedDIRClose {
267 public:
268  inline void operator()(DIR* x) const {
269    if (x) {
270      closedir(x);
271    }
272  }
273};
274typedef scoped_ptr_malloc<DIR, ScopedDIRClose> ScopedDIR;
275
276#if defined(OS_LINUX)
277  static const rlim_t kSystemDefaultMaxFds = 8192;
278  static const char kFDDir[] = "/proc/self/fd";
279#elif defined(OS_MACOSX)
280  static const rlim_t kSystemDefaultMaxFds = 256;
281  static const char kFDDir[] = "/dev/fd";
282#elif defined(OS_SOLARIS)
283  static const rlim_t kSystemDefaultMaxFds = 8192;
284  static const char kFDDir[] = "/dev/fd";
285#elif defined(OS_FREEBSD)
286  static const rlim_t kSystemDefaultMaxFds = 8192;
287  static const char kFDDir[] = "/dev/fd";
288#elif defined(OS_OPENBSD)
289  static const rlim_t kSystemDefaultMaxFds = 256;
290  static const char kFDDir[] = "/dev/fd";
291#endif
292
293void CloseSuperfluousFds(const base::InjectiveMultimap& saved_mapping) {
294  // DANGER: no calls to malloc are allowed from now on:
295  // http://crbug.com/36678
296
297  // Get the maximum number of FDs possible.
298  struct rlimit nofile;
299  rlim_t max_fds;
300  if (getrlimit(RLIMIT_NOFILE, &nofile)) {
301    // getrlimit failed. Take a best guess.
302    max_fds = kSystemDefaultMaxFds;
303    DLOG(ERROR) << "getrlimit(RLIMIT_NOFILE) failed: " << errno;
304  } else {
305    max_fds = nofile.rlim_cur;
306  }
307
308  if (max_fds > INT_MAX)
309    max_fds = INT_MAX;
310
311  DirReaderPosix fd_dir(kFDDir);
312
313  if (!fd_dir.IsValid()) {
314    // Fallback case: Try every possible fd.
315    for (rlim_t i = 0; i < max_fds; ++i) {
316      const int fd = static_cast<int>(i);
317      if (fd == STDIN_FILENO || fd == STDOUT_FILENO || fd == STDERR_FILENO)
318        continue;
319      InjectiveMultimap::const_iterator j;
320      for (j = saved_mapping.begin(); j != saved_mapping.end(); j++) {
321        if (fd == j->dest)
322          break;
323      }
324      if (j != saved_mapping.end())
325        continue;
326
327      // Since we're just trying to close anything we can find,
328      // ignore any error return values of close().
329      int unused ALLOW_UNUSED = HANDLE_EINTR(close(fd));
330    }
331    return;
332  }
333
334  const int dir_fd = fd_dir.fd();
335
336  for ( ; fd_dir.Next(); ) {
337    // Skip . and .. entries.
338    if (fd_dir.name()[0] == '.')
339      continue;
340
341    char *endptr;
342    errno = 0;
343    const long int fd = strtol(fd_dir.name(), &endptr, 10);
344    if (fd_dir.name()[0] == 0 || *endptr || fd < 0 || errno)
345      continue;
346    if (fd == STDIN_FILENO || fd == STDOUT_FILENO || fd == STDERR_FILENO)
347      continue;
348    InjectiveMultimap::const_iterator i;
349    for (i = saved_mapping.begin(); i != saved_mapping.end(); i++) {
350      if (fd == i->dest)
351        break;
352    }
353    if (i != saved_mapping.end())
354      continue;
355    if (fd == dir_fd)
356      continue;
357
358    // When running under Valgrind, Valgrind opens several FDs for its
359    // own use and will complain if we try to close them.  All of
360    // these FDs are >= |max_fds|, so we can check against that here
361    // before closing.  See https://bugs.kde.org/show_bug.cgi?id=191758
362    if (fd < static_cast<int>(max_fds)) {
363      int ret = HANDLE_EINTR(close(fd));
364      DPCHECK(ret == 0);
365    }
366  }
367}
368
369char** AlterEnvironment(const environment_vector& changes,
370                        const char* const* const env) {
371  unsigned count = 0;
372  unsigned size = 0;
373
374  // First assume that all of the current environment will be included.
375  for (unsigned i = 0; env[i]; i++) {
376    const char *const pair = env[i];
377    count++;
378    size += strlen(pair) + 1 /* terminating NUL */;
379  }
380
381  for (environment_vector::const_iterator
382       j = changes.begin(); j != changes.end(); j++) {
383    bool found = false;
384    const char *pair;
385
386    for (unsigned i = 0; env[i]; i++) {
387      pair = env[i];
388      const char *const equals = strchr(pair, '=');
389      if (!equals)
390        continue;
391      const unsigned keylen = equals - pair;
392      if (keylen == j->first.size() &&
393          memcmp(pair, j->first.data(), keylen) == 0) {
394        found = true;
395        break;
396      }
397    }
398
399    // if found, we'll either be deleting or replacing this element.
400    if (found) {
401      count--;
402      size -= strlen(pair) + 1;
403      if (j->second.size())
404        found = false;
405    }
406
407    // if !found, then we have a new element to add.
408    if (!found && !j->second.empty()) {
409      count++;
410      size += j->first.size() + 1 /* '=' */ + j->second.size() + 1 /* NUL */;
411    }
412  }
413
414  count++;  // for the final NULL
415  uint8_t *buffer = new uint8_t[sizeof(char*) * count + size];
416  char **const ret = reinterpret_cast<char**>(buffer);
417  unsigned k = 0;
418  char *scratch = reinterpret_cast<char*>(buffer + sizeof(char*) * count);
419
420  for (unsigned i = 0; env[i]; i++) {
421    const char *const pair = env[i];
422    const char *const equals = strchr(pair, '=');
423    if (!equals) {
424      const unsigned len = strlen(pair);
425      ret[k++] = scratch;
426      memcpy(scratch, pair, len + 1);
427      scratch += len + 1;
428      continue;
429    }
430    const unsigned keylen = equals - pair;
431    bool handled = false;
432    for (environment_vector::const_iterator
433         j = changes.begin(); j != changes.end(); j++) {
434      if (j->first.size() == keylen &&
435          memcmp(j->first.data(), pair, keylen) == 0) {
436        if (!j->second.empty()) {
437          ret[k++] = scratch;
438          memcpy(scratch, pair, keylen + 1);
439          scratch += keylen + 1;
440          memcpy(scratch, j->second.c_str(), j->second.size() + 1);
441          scratch += j->second.size() + 1;
442        }
443        handled = true;
444        break;
445      }
446    }
447
448    if (!handled) {
449      const unsigned len = strlen(pair);
450      ret[k++] = scratch;
451      memcpy(scratch, pair, len + 1);
452      scratch += len + 1;
453    }
454  }
455
456  // Now handle new elements
457  for (environment_vector::const_iterator
458       j = changes.begin(); j != changes.end(); j++) {
459    if (j->second.empty())
460      continue;
461
462    bool found = false;
463    for (unsigned i = 0; env[i]; i++) {
464      const char *const pair = env[i];
465      const char *const equals = strchr(pair, '=');
466      if (!equals)
467        continue;
468      const unsigned keylen = equals - pair;
469      if (keylen == j->first.size() &&
470          memcmp(pair, j->first.data(), keylen) == 0) {
471        found = true;
472        break;
473      }
474    }
475
476    if (!found) {
477      ret[k++] = scratch;
478      memcpy(scratch, j->first.data(), j->first.size());
479      scratch += j->first.size();
480      *scratch++ = '=';
481      memcpy(scratch, j->second.c_str(), j->second.size() + 1);
482      scratch += j->second.size() + 1;
483     }
484  }
485
486  ret[k] = NULL;
487  return ret;
488}
489
490bool LaunchAppImpl(
491    const std::vector<std::string>& argv,
492    const environment_vector& env_changes,
493    const file_handle_mapping_vector& fds_to_remap,
494    bool wait,
495    ProcessHandle* process_handle,
496    bool start_new_process_group) {
497  pid_t pid;
498  InjectiveMultimap fd_shuffle1, fd_shuffle2;
499  fd_shuffle1.reserve(fds_to_remap.size());
500  fd_shuffle2.reserve(fds_to_remap.size());
501  scoped_array<char*> argv_cstr(new char*[argv.size() + 1]);
502  scoped_array<char*> new_environ(AlterEnvironment(env_changes, environ));
503
504  pid = fork();
505  if (pid < 0) {
506    PLOG(ERROR) << "fork";
507    return false;
508  }
509  if (pid == 0) {
510    // Child process
511
512    if (start_new_process_group) {
513      // Instead of inheriting the process group ID of the parent, the child
514      // starts off a new process group with pgid equal to its process ID.
515      if (setpgid(0, 0) < 0) {
516        PLOG(ERROR) << "setpgid";
517        return false;
518      }
519    }
520#if defined(OS_MACOSX)
521    RestoreDefaultExceptionHandler();
522#endif
523
524    ResetChildSignalHandlersToDefaults();
525
526#if 0
527    // When debugging it can be helpful to check that we really aren't making
528    // any hidden calls to malloc.
529    void *malloc_thunk =
530        reinterpret_cast<void*>(reinterpret_cast<intptr_t>(malloc) & ~4095);
531    mprotect(malloc_thunk, 4096, PROT_READ | PROT_WRITE | PROT_EXEC);
532    memset(reinterpret_cast<void*>(malloc), 0xff, 8);
533#endif
534
535    // DANGER: no calls to malloc are allowed from now on:
536    // http://crbug.com/36678
537
538    for (file_handle_mapping_vector::const_iterator
539        it = fds_to_remap.begin(); it != fds_to_remap.end(); ++it) {
540      fd_shuffle1.push_back(InjectionArc(it->first, it->second, false));
541      fd_shuffle2.push_back(InjectionArc(it->first, it->second, false));
542    }
543
544    environ = new_environ.get();
545
546    // Obscure fork() rule: in the child, if you don't end up doing exec*(),
547    // you call _exit() instead of exit(). This is because _exit() does not
548    // call any previously-registered (in the parent) exit handlers, which
549    // might do things like block waiting for threads that don't even exist
550    // in the child.
551
552    // fd_shuffle1 is mutated by this call because it cannot malloc.
553    if (!ShuffleFileDescriptors(&fd_shuffle1))
554      _exit(127);
555
556    CloseSuperfluousFds(fd_shuffle2);
557
558    for (size_t i = 0; i < argv.size(); i++)
559      argv_cstr[i] = const_cast<char*>(argv[i].c_str());
560    argv_cstr[argv.size()] = NULL;
561    execvp(argv_cstr[0], argv_cstr.get());
562    RAW_LOG(ERROR, "LaunchApp: failed to execvp:");
563    RAW_LOG(ERROR, argv_cstr[0]);
564    _exit(127);
565  } else {
566    // Parent process
567    if (wait) {
568      // While this isn't strictly disk IO, waiting for another process to
569      // finish is the sort of thing ThreadRestrictions is trying to prevent.
570      base::ThreadRestrictions::AssertIOAllowed();
571      pid_t ret = HANDLE_EINTR(waitpid(pid, 0, 0));
572      DPCHECK(ret > 0);
573    }
574
575    if (process_handle)
576      *process_handle = pid;
577  }
578
579  return true;
580}
581
582bool LaunchApp(
583    const std::vector<std::string>& argv,
584    const environment_vector& env_changes,
585    const file_handle_mapping_vector& fds_to_remap,
586    bool wait,
587    ProcessHandle* process_handle) {
588  return LaunchAppImpl(argv, env_changes, fds_to_remap,
589                       wait, process_handle, false);
590}
591
592bool LaunchAppInNewProcessGroup(
593    const std::vector<std::string>& argv,
594    const environment_vector& env_changes,
595    const file_handle_mapping_vector& fds_to_remap,
596    bool wait,
597    ProcessHandle* process_handle) {
598  return LaunchAppImpl(argv, env_changes, fds_to_remap, wait,
599                       process_handle, true);
600}
601
602bool LaunchApp(const std::vector<std::string>& argv,
603               const file_handle_mapping_vector& fds_to_remap,
604               bool wait, ProcessHandle* process_handle) {
605  base::environment_vector no_env;
606  return LaunchApp(argv, no_env, fds_to_remap, wait, process_handle);
607}
608
609bool LaunchApp(const CommandLine& cl,
610               bool wait, bool start_hidden,
611               ProcessHandle* process_handle) {
612  file_handle_mapping_vector no_files;
613  return LaunchApp(cl.argv(), no_files, wait, process_handle);
614}
615
616ProcessMetrics::~ProcessMetrics() { }
617
618void EnableTerminationOnHeapCorruption() {
619  // On POSIX, there nothing to do AFAIK.
620}
621
622bool EnableInProcessStackDumping() {
623  // When running in an application, our code typically expects SIGPIPE
624  // to be ignored.  Therefore, when testing that same code, it should run
625  // with SIGPIPE ignored as well.
626  struct sigaction action;
627  action.sa_handler = SIG_IGN;
628  action.sa_flags = 0;
629  sigemptyset(&action.sa_mask);
630  bool success = (sigaction(SIGPIPE, &action, NULL) == 0);
631
632  sig_t handler = reinterpret_cast<sig_t>(&StackDumpSignalHandler);
633  success &= (signal(SIGILL, handler) != SIG_ERR);
634  success &= (signal(SIGABRT, handler) != SIG_ERR);
635  success &= (signal(SIGFPE, handler) != SIG_ERR);
636  success &= (signal(SIGBUS, handler) != SIG_ERR);
637  success &= (signal(SIGSEGV, handler) != SIG_ERR);
638  success &= (signal(SIGSYS, handler) != SIG_ERR);
639
640  return success;
641}
642
643void RaiseProcessToHighPriority() {
644  // On POSIX, we don't actually do anything here.  We could try to nice() or
645  // setpriority() or sched_getscheduler, but these all require extra rights.
646}
647
648TerminationStatus GetTerminationStatus(ProcessHandle handle, int* exit_code) {
649  int status = 0;
650  const pid_t result = HANDLE_EINTR(waitpid(handle, &status, WNOHANG));
651  if (result == -1) {
652    PLOG(ERROR) << "waitpid(" << handle << ")";
653    if (exit_code)
654      *exit_code = 0;
655    return TERMINATION_STATUS_NORMAL_TERMINATION;
656  } else if (result == 0) {
657    // the child hasn't exited yet.
658    if (exit_code)
659      *exit_code = 0;
660    return TERMINATION_STATUS_STILL_RUNNING;
661  }
662
663  if (exit_code)
664    *exit_code = status;
665
666  if (WIFSIGNALED(status)) {
667    switch (WTERMSIG(status)) {
668      case SIGABRT:
669      case SIGBUS:
670      case SIGFPE:
671      case SIGILL:
672      case SIGSEGV:
673        return TERMINATION_STATUS_PROCESS_CRASHED;
674      case SIGINT:
675      case SIGKILL:
676      case SIGTERM:
677        return TERMINATION_STATUS_PROCESS_WAS_KILLED;
678      default:
679        break;
680    }
681  }
682
683  if (WIFEXITED(status) && WEXITSTATUS(status) != 0)
684    return TERMINATION_STATUS_ABNORMAL_TERMINATION;
685
686  return TERMINATION_STATUS_NORMAL_TERMINATION;
687}
688
689bool WaitForExitCode(ProcessHandle handle, int* exit_code) {
690  int status;
691  if (HANDLE_EINTR(waitpid(handle, &status, 0)) == -1) {
692    NOTREACHED();
693    return false;
694  }
695
696  if (WIFEXITED(status)) {
697    *exit_code = WEXITSTATUS(status);
698    return true;
699  }
700
701  // If it didn't exit cleanly, it must have been signaled.
702  DCHECK(WIFSIGNALED(status));
703  return false;
704}
705
706bool WaitForExitCodeWithTimeout(ProcessHandle handle, int* exit_code,
707                                int64 timeout_milliseconds) {
708  bool waitpid_success = false;
709  int status = WaitpidWithTimeout(handle, timeout_milliseconds,
710                                  &waitpid_success);
711  if (status == -1)
712    return false;
713  if (!waitpid_success)
714    return false;
715  if (!WIFEXITED(status))
716    return false;
717  if (WIFSIGNALED(status)) {
718    *exit_code = -1;
719    return true;
720  }
721  *exit_code = WEXITSTATUS(status);
722  return true;
723}
724
725#if defined(OS_MACOSX)
726// Using kqueue on Mac so that we can wait on non-child processes.
727// We can't use kqueues on child processes because we need to reap
728// our own children using wait.
729static bool WaitForSingleNonChildProcess(ProcessHandle handle,
730                                         int64 wait_milliseconds) {
731  int kq = kqueue();
732  if (kq == -1) {
733    PLOG(ERROR) << "kqueue";
734    return false;
735  }
736
737  struct kevent change = { 0 };
738  EV_SET(&change, handle, EVFILT_PROC, EV_ADD, NOTE_EXIT, 0, NULL);
739
740  struct timespec spec;
741  struct timespec *spec_ptr;
742  if (wait_milliseconds != base::kNoTimeout) {
743    time_t sec = static_cast<time_t>(wait_milliseconds / 1000);
744    wait_milliseconds = wait_milliseconds - (sec * 1000);
745    spec.tv_sec = sec;
746    spec.tv_nsec = wait_milliseconds * 1000000L;
747    spec_ptr = &spec;
748  } else {
749    spec_ptr = NULL;
750  }
751
752  while(true) {
753    struct kevent event = { 0 };
754    int event_count = HANDLE_EINTR(kevent(kq, &change, 1, &event, 1, spec_ptr));
755    if (close(kq) != 0) {
756      PLOG(ERROR) << "close";
757    }
758    if (event_count < 0) {
759      PLOG(ERROR) << "kevent";
760      return false;
761    } else if (event_count == 0) {
762      if (wait_milliseconds != base::kNoTimeout) {
763        // Timed out.
764        return false;
765      }
766    } else if ((event_count == 1) &&
767               (handle == static_cast<pid_t>(event.ident)) &&
768               (event.filter == EVFILT_PROC)) {
769      if (event.fflags == NOTE_EXIT) {
770        return true;
771      } else if (event.flags == EV_ERROR) {
772        LOG(ERROR) << "kevent error " << event.data;
773        return false;
774      } else {
775        NOTREACHED();
776        return false;
777      }
778    } else {
779      NOTREACHED();
780      return false;
781    }
782  }
783}
784#endif  // OS_MACOSX
785
786bool WaitForSingleProcess(ProcessHandle handle, int64 wait_milliseconds) {
787  ProcessHandle parent_pid = GetParentProcessId(handle);
788  ProcessHandle our_pid = Process::Current().handle();
789  if (parent_pid != our_pid) {
790#if defined(OS_MACOSX)
791    // On Mac we can wait on non child processes.
792    return WaitForSingleNonChildProcess(handle, wait_milliseconds);
793#else
794    // Currently on Linux we can't handle non child processes.
795    NOTIMPLEMENTED();
796#endif  // OS_MACOSX
797  }
798  bool waitpid_success;
799  int status;
800  if (wait_milliseconds == base::kNoTimeout)
801    waitpid_success = (HANDLE_EINTR(waitpid(handle, &status, 0)) != -1);
802  else
803    status = WaitpidWithTimeout(handle, wait_milliseconds, &waitpid_success);
804  if (status != -1) {
805    DCHECK(waitpid_success);
806    return WIFEXITED(status);
807  } else {
808    return false;
809  }
810}
811
812bool CrashAwareSleep(ProcessHandle handle, int64 wait_milliseconds) {
813  bool waitpid_success;
814  int status = WaitpidWithTimeout(handle, wait_milliseconds, &waitpid_success);
815  if (status != -1) {
816    DCHECK(waitpid_success);
817    return !(WIFEXITED(status) || WIFSIGNALED(status));
818  } else {
819    // If waitpid returned with an error, then the process doesn't exist
820    // (which most probably means it didn't exist before our call).
821    return waitpid_success;
822  }
823}
824
825int64 TimeValToMicroseconds(const struct timeval& tv) {
826  static const int kMicrosecondsPerSecond = 1000000;
827  int64 ret = tv.tv_sec;  // Avoid (int * int) integer overflow.
828  ret *= kMicrosecondsPerSecond;
829  ret += tv.tv_usec;
830  return ret;
831}
832
833// Executes the application specified by |cl| and wait for it to exit. Stores
834// the output (stdout) in |output|. If |do_search_path| is set, it searches the
835// path for the application; in that case, |envp| must be null, and it will use
836// the current environment. If |do_search_path| is false, |cl| should fully
837// specify the path of the application, and |envp| will be used as the
838// environment. Redirects stderr to /dev/null. Returns true on success
839// (application launched and exited cleanly, with exit code indicating success).
840static bool GetAppOutputInternal(const CommandLine& cl, char* const envp[],
841                                 std::string* output, size_t max_output,
842                                 bool do_search_path) {
843  // Doing a blocking wait for another command to finish counts as IO.
844  base::ThreadRestrictions::AssertIOAllowed();
845
846  int pipe_fd[2];
847  pid_t pid;
848  InjectiveMultimap fd_shuffle1, fd_shuffle2;
849  const std::vector<std::string>& argv = cl.argv();
850  scoped_array<char*> argv_cstr(new char*[argv.size() + 1]);
851
852  fd_shuffle1.reserve(3);
853  fd_shuffle2.reserve(3);
854
855  // Either |do_search_path| should be false or |envp| should be null, but not
856  // both.
857  DCHECK(!do_search_path ^ !envp);
858
859  if (pipe(pipe_fd) < 0)
860    return false;
861
862  switch (pid = fork()) {
863    case -1:  // error
864      close(pipe_fd[0]);
865      close(pipe_fd[1]);
866      return false;
867    case 0:  // child
868      {
869#if defined(OS_MACOSX)
870        RestoreDefaultExceptionHandler();
871#endif
872        // DANGER: no calls to malloc are allowed from now on:
873        // http://crbug.com/36678
874
875        // Obscure fork() rule: in the child, if you don't end up doing exec*(),
876        // you call _exit() instead of exit(). This is because _exit() does not
877        // call any previously-registered (in the parent) exit handlers, which
878        // might do things like block waiting for threads that don't even exist
879        // in the child.
880        int dev_null = open("/dev/null", O_WRONLY);
881        if (dev_null < 0)
882          _exit(127);
883
884        fd_shuffle1.push_back(InjectionArc(pipe_fd[1], STDOUT_FILENO, true));
885        fd_shuffle1.push_back(InjectionArc(dev_null, STDERR_FILENO, true));
886        fd_shuffle1.push_back(InjectionArc(dev_null, STDIN_FILENO, true));
887        // Adding another element here? Remeber to increase the argument to
888        // reserve(), above.
889
890        std::copy(fd_shuffle1.begin(), fd_shuffle1.end(),
891                  std::back_inserter(fd_shuffle2));
892
893        if (!ShuffleFileDescriptors(&fd_shuffle1))
894          _exit(127);
895
896        CloseSuperfluousFds(fd_shuffle2);
897
898        for (size_t i = 0; i < argv.size(); i++)
899          argv_cstr[i] = const_cast<char*>(argv[i].c_str());
900        argv_cstr[argv.size()] = NULL;
901        if (do_search_path)
902          execvp(argv_cstr[0], argv_cstr.get());
903        else
904          execve(argv_cstr[0], argv_cstr.get(), envp);
905        _exit(127);
906      }
907    default:  // parent
908      {
909        // Close our writing end of pipe now. Otherwise later read would not
910        // be able to detect end of child's output (in theory we could still
911        // write to the pipe).
912        close(pipe_fd[1]);
913
914        output->clear();
915        char buffer[256];
916        size_t output_buf_left = max_output;
917        ssize_t bytes_read = 1;  // A lie to properly handle |max_output == 0|
918                                 // case in the logic below.
919
920        while (output_buf_left > 0) {
921          bytes_read = HANDLE_EINTR(read(pipe_fd[0], buffer,
922                                    std::min(output_buf_left, sizeof(buffer))));
923          if (bytes_read <= 0)
924            break;
925          output->append(buffer, bytes_read);
926          output_buf_left -= static_cast<size_t>(bytes_read);
927        }
928        close(pipe_fd[0]);
929
930        // Always wait for exit code (even if we know we'll declare success).
931        int exit_code = EXIT_FAILURE;
932        bool success = WaitForExitCode(pid, &exit_code);
933
934        // If we stopped because we read as much as we wanted, we always declare
935        // success (because the child may exit due to |SIGPIPE|).
936        if (output_buf_left || bytes_read <= 0) {
937          if (!success || exit_code != EXIT_SUCCESS)
938            return false;
939        }
940
941        return true;
942      }
943  }
944}
945
946bool GetAppOutput(const CommandLine& cl, std::string* output) {
947  // Run |execve()| with the current environment and store "unlimited" data.
948  return GetAppOutputInternal(cl, NULL, output,
949                              std::numeric_limits<std::size_t>::max(), true);
950}
951
952// TODO(viettrungluu): Conceivably, we should have a timeout as well, so we
953// don't hang if what we're calling hangs.
954bool GetAppOutputRestricted(const CommandLine& cl,
955                            std::string* output, size_t max_output) {
956  // Run |execve()| with the empty environment.
957  char* const empty_environ = NULL;
958  return GetAppOutputInternal(cl, &empty_environ, output, max_output, false);
959}
960
961bool WaitForProcessesToExit(const FilePath::StringType& executable_name,
962                            int64 wait_milliseconds,
963                            const ProcessFilter* filter) {
964  bool result = false;
965
966  // TODO(port): This is inefficient, but works if there are multiple procs.
967  // TODO(port): use waitpid to avoid leaving zombies around
968
969  base::Time end_time = base::Time::Now() +
970      base::TimeDelta::FromMilliseconds(wait_milliseconds);
971  do {
972    NamedProcessIterator iter(executable_name, filter);
973    if (!iter.NextProcessEntry()) {
974      result = true;
975      break;
976    }
977    base::PlatformThread::Sleep(100);
978  } while ((base::Time::Now() - end_time) > base::TimeDelta());
979
980  return result;
981}
982
983bool CleanupProcesses(const FilePath::StringType& executable_name,
984                      int64 wait_milliseconds,
985                      int exit_code,
986                      const ProcessFilter* filter) {
987  bool exited_cleanly =
988      WaitForProcessesToExit(executable_name, wait_milliseconds,
989                             filter);
990  if (!exited_cleanly)
991    KillProcesses(executable_name, exit_code, filter);
992  return exited_cleanly;
993}
994
995}  // namespace base
996