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