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