Home | History | Annotate | Download | only in base
      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
     39 extern char** environ;
     40 #endif
     41 
     42 #if defined(__ANDROID__) && !defined(__BIONIC_HAVE_UCONTEXT_T)
     43 // No ucontext.h on old Android C library headers
     44 typedef void ucontext_t;
     45 #endif
     46 
     47 namespace base {
     48 
     49 namespace {
     50 
     51 int 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 
    112 void 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 
    165 void 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 
    183 ProcessId GetCurrentProcId() {
    184   return getpid();
    185 }
    186 
    187 ProcessHandle GetCurrentProcessHandle() {
    188   return GetCurrentProcId();
    189 }
    190 
    191 bool 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 
    198 bool 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 
    204 bool 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 
    212 void CloseProcessHandle(ProcessHandle process) {
    213   // See OpenProcessHandle, nothing to do.
    214   return;
    215 }
    216 
    217 ProcessId 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.
    224 bool 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 
    270 bool 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.
    278 class ScopedDIRClose {
    279  public:
    280   inline void operator()(DIR* x) const {
    281     if (x) {
    282       closedir(x);
    283     }
    284   }
    285 };
    286 typedef 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 
    305 void 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 
    381 char** 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 
    502 bool 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 
    630 bool 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 
    640 bool 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 
    650 bool 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 
    657 bool 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 
    664 ProcessMetrics::~ProcessMetrics() { }
    665 
    666 void EnableTerminationOnHeapCorruption() {
    667   // On POSIX, there nothing to do AFAIK.
    668 }
    669 
    670 bool 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 
    691 void 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 
    696 TerminationStatus 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 
    737 bool 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 
    754 bool 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.
    778 static 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 
    835 bool 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 
    861 int64 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).
    876 static 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 
    994 bool 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.
   1002 bool 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 
   1009 bool 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 
   1031 bool 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