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