Home | History | Annotate | Download | only in process
      1 // Copyright (c) 2012 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 "base/process/launch.h"
      6 
      7 #include <dirent.h>
      8 #include <errno.h>
      9 #include <fcntl.h>
     10 #include <signal.h>
     11 #include <stdlib.h>
     12 #include <sys/resource.h>
     13 #include <sys/time.h>
     14 #include <sys/types.h>
     15 #include <sys/wait.h>
     16 #include <unistd.h>
     17 
     18 #include <iterator>
     19 #include <limits>
     20 #include <set>
     21 
     22 #include "base/allocator/type_profiler_control.h"
     23 #include "base/command_line.h"
     24 #include "base/compiler_specific.h"
     25 #include "base/debug/debugger.h"
     26 #include "base/debug/stack_trace.h"
     27 #include "base/files/dir_reader_posix.h"
     28 #include "base/files/file_util.h"
     29 #include "base/files/scoped_file.h"
     30 #include "base/logging.h"
     31 #include "base/memory/scoped_ptr.h"
     32 #include "base/posix/eintr_wrapper.h"
     33 #include "base/process/kill.h"
     34 #include "base/process/process_metrics.h"
     35 #include "base/strings/stringprintf.h"
     36 #include "base/synchronization/waitable_event.h"
     37 #include "base/third_party/dynamic_annotations/dynamic_annotations.h"
     38 #include "base/threading/platform_thread.h"
     39 #include "base/threading/thread_restrictions.h"
     40 
     41 #if defined(OS_LINUX)
     42 #include <sys/prctl.h>
     43 #endif
     44 
     45 #if defined(OS_CHROMEOS)
     46 #include <sys/ioctl.h>
     47 #endif
     48 
     49 #if defined(OS_FREEBSD)
     50 #include <sys/event.h>
     51 #include <sys/ucontext.h>
     52 #endif
     53 
     54 #if defined(OS_MACOSX)
     55 #include <crt_externs.h>
     56 #include <sys/event.h>
     57 #else
     58 extern char** environ;
     59 #endif
     60 
     61 namespace base {
     62 
     63 namespace {
     64 
     65 // Get the process's "environment" (i.e. the thing that setenv/getenv
     66 // work with).
     67 char** GetEnvironment() {
     68 #if defined(OS_MACOSX)
     69   return *_NSGetEnviron();
     70 #else
     71   return environ;
     72 #endif
     73 }
     74 
     75 // Set the process's "environment" (i.e. the thing that setenv/getenv
     76 // work with).
     77 void SetEnvironment(char** env) {
     78 #if defined(OS_MACOSX)
     79   *_NSGetEnviron() = env;
     80 #else
     81   environ = env;
     82 #endif
     83 }
     84 
     85 // Set the calling thread's signal mask to new_sigmask and return
     86 // the previous signal mask.
     87 sigset_t SetSignalMask(const sigset_t& new_sigmask) {
     88   sigset_t old_sigmask;
     89 #if defined(OS_ANDROID)
     90   // POSIX says pthread_sigmask() must be used in multi-threaded processes,
     91   // but Android's pthread_sigmask() was broken until 4.1:
     92   // https://code.google.com/p/android/issues/detail?id=15337
     93   // http://stackoverflow.com/questions/13777109/pthread-sigmask-on-android-not-working
     94   RAW_CHECK(sigprocmask(SIG_SETMASK, &new_sigmask, &old_sigmask) == 0);
     95 #else
     96   RAW_CHECK(pthread_sigmask(SIG_SETMASK, &new_sigmask, &old_sigmask) == 0);
     97 #endif
     98   return old_sigmask;
     99 }
    100 
    101 #if !defined(OS_LINUX) || \
    102     (!defined(__i386__) && !defined(__x86_64__) && !defined(__arm__))
    103 void ResetChildSignalHandlersToDefaults() {
    104   // The previous signal handlers are likely to be meaningless in the child's
    105   // context so we reset them to the defaults for now. http://crbug.com/44953
    106   // These signal handlers are set up at least in browser_main_posix.cc:
    107   // BrowserMainPartsPosix::PreEarlyInitialization and stack_trace_posix.cc:
    108   // EnableInProcessStackDumping.
    109   signal(SIGHUP, SIG_DFL);
    110   signal(SIGINT, SIG_DFL);
    111   signal(SIGILL, SIG_DFL);
    112   signal(SIGABRT, SIG_DFL);
    113   signal(SIGFPE, SIG_DFL);
    114   signal(SIGBUS, SIG_DFL);
    115   signal(SIGSEGV, SIG_DFL);
    116   signal(SIGSYS, SIG_DFL);
    117   signal(SIGTERM, SIG_DFL);
    118 }
    119 
    120 #else
    121 
    122 // TODO(jln): remove the Linux special case once kernels are fixed.
    123 
    124 // Internally the kernel makes sigset_t an array of long large enough to have
    125 // one bit per signal.
    126 typedef uint64_t kernel_sigset_t;
    127 
    128 // This is what struct sigaction looks like to the kernel at least on X86 and
    129 // ARM. MIPS, for instance, is very different.
    130 struct kernel_sigaction {
    131   void* k_sa_handler;  // For this usage it only needs to be a generic pointer.
    132   unsigned long k_sa_flags;
    133   void* k_sa_restorer;  // For this usage it only needs to be a generic pointer.
    134   kernel_sigset_t k_sa_mask;
    135 };
    136 
    137 // glibc's sigaction() will prevent access to sa_restorer, so we need to roll
    138 // our own.
    139 int sys_rt_sigaction(int sig, const struct kernel_sigaction* act,
    140                      struct kernel_sigaction* oact) {
    141   return syscall(SYS_rt_sigaction, sig, act, oact, sizeof(kernel_sigset_t));
    142 }
    143 
    144 // This function is intended to be used in between fork() and execve() and will
    145 // reset all signal handlers to the default.
    146 // The motivation for going through all of them is that sa_restorer can leak
    147 // from parents and help defeat ASLR on buggy kernels.  We reset it to NULL.
    148 // See crbug.com/177956.
    149 void ResetChildSignalHandlersToDefaults(void) {
    150   for (int signum = 1; ; ++signum) {
    151     struct kernel_sigaction act = {0};
    152     int sigaction_get_ret = sys_rt_sigaction(signum, NULL, &act);
    153     if (sigaction_get_ret && errno == EINVAL) {
    154 #if !defined(NDEBUG)
    155       // Linux supports 32 real-time signals from 33 to 64.
    156       // If the number of signals in the Linux kernel changes, someone should
    157       // look at this code.
    158       const int kNumberOfSignals = 64;
    159       RAW_CHECK(signum == kNumberOfSignals + 1);
    160 #endif  // !defined(NDEBUG)
    161       break;
    162     }
    163     // All other failures are fatal.
    164     if (sigaction_get_ret) {
    165       RAW_LOG(FATAL, "sigaction (get) failed.");
    166     }
    167 
    168     // The kernel won't allow to re-set SIGKILL or SIGSTOP.
    169     if (signum != SIGSTOP && signum != SIGKILL) {
    170       act.k_sa_handler = reinterpret_cast<void*>(SIG_DFL);
    171       act.k_sa_restorer = NULL;
    172       if (sys_rt_sigaction(signum, &act, NULL)) {
    173         RAW_LOG(FATAL, "sigaction (set) failed.");
    174       }
    175     }
    176 #if !defined(NDEBUG)
    177     // Now ask the kernel again and check that no restorer will leak.
    178     if (sys_rt_sigaction(signum, NULL, &act) || act.k_sa_restorer) {
    179       RAW_LOG(FATAL, "Cound not fix sa_restorer.");
    180     }
    181 #endif  // !defined(NDEBUG)
    182   }
    183 }
    184 #endif  // !defined(OS_LINUX) ||
    185         // (!defined(__i386__) && !defined(__x86_64__) && !defined(__arm__))
    186 
    187 }  // anonymous namespace
    188 
    189 // Functor for |ScopedDIR| (below).
    190 struct ScopedDIRClose {
    191   inline void operator()(DIR* x) const {
    192     if (x)
    193       closedir(x);
    194   }
    195 };
    196 
    197 // Automatically closes |DIR*|s.
    198 typedef scoped_ptr<DIR, ScopedDIRClose> ScopedDIR;
    199 
    200 #if defined(OS_LINUX)
    201 static const char kFDDir[] = "/proc/self/fd";
    202 #elif defined(OS_MACOSX)
    203 static const char kFDDir[] = "/dev/fd";
    204 #elif defined(OS_SOLARIS)
    205 static const char kFDDir[] = "/dev/fd";
    206 #elif defined(OS_FREEBSD)
    207 static const char kFDDir[] = "/dev/fd";
    208 #elif defined(OS_OPENBSD)
    209 static const char kFDDir[] = "/dev/fd";
    210 #elif defined(OS_ANDROID)
    211 static const char kFDDir[] = "/proc/self/fd";
    212 #endif
    213 
    214 void CloseSuperfluousFds(const base::InjectiveMultimap& saved_mapping) {
    215   // DANGER: no calls to malloc or locks are allowed from now on:
    216   // http://crbug.com/36678
    217 
    218   // Get the maximum number of FDs possible.
    219   size_t max_fds = GetMaxFds();
    220 
    221   DirReaderPosix fd_dir(kFDDir);
    222   if (!fd_dir.IsValid()) {
    223     // Fallback case: Try every possible fd.
    224     for (size_t i = 0; i < max_fds; ++i) {
    225       const int fd = static_cast<int>(i);
    226       if (fd == STDIN_FILENO || fd == STDOUT_FILENO || fd == STDERR_FILENO)
    227         continue;
    228       // Cannot use STL iterators here, since debug iterators use locks.
    229       size_t j;
    230       for (j = 0; j < saved_mapping.size(); j++) {
    231         if (fd == saved_mapping[j].dest)
    232           break;
    233       }
    234       if (j < saved_mapping.size())
    235         continue;
    236 
    237       // Since we're just trying to close anything we can find,
    238       // ignore any error return values of close().
    239       close(fd);
    240     }
    241     return;
    242   }
    243 
    244   const int dir_fd = fd_dir.fd();
    245 
    246   for ( ; fd_dir.Next(); ) {
    247     // Skip . and .. entries.
    248     if (fd_dir.name()[0] == '.')
    249       continue;
    250 
    251     char *endptr;
    252     errno = 0;
    253     const long int fd = strtol(fd_dir.name(), &endptr, 10);
    254     if (fd_dir.name()[0] == 0 || *endptr || fd < 0 || errno)
    255       continue;
    256     if (fd == STDIN_FILENO || fd == STDOUT_FILENO || fd == STDERR_FILENO)
    257       continue;
    258     // Cannot use STL iterators here, since debug iterators use locks.
    259     size_t i;
    260     for (i = 0; i < saved_mapping.size(); i++) {
    261       if (fd == saved_mapping[i].dest)
    262         break;
    263     }
    264     if (i < saved_mapping.size())
    265       continue;
    266     if (fd == dir_fd)
    267       continue;
    268 
    269     // When running under Valgrind, Valgrind opens several FDs for its
    270     // own use and will complain if we try to close them.  All of
    271     // these FDs are >= |max_fds|, so we can check against that here
    272     // before closing.  See https://bugs.kde.org/show_bug.cgi?id=191758
    273     if (fd < static_cast<int>(max_fds)) {
    274       int ret = IGNORE_EINTR(close(fd));
    275       DPCHECK(ret == 0);
    276     }
    277   }
    278 }
    279 
    280 bool LaunchProcess(const std::vector<std::string>& argv,
    281                    const LaunchOptions& options,
    282                    ProcessHandle* process_handle) {
    283   size_t fd_shuffle_size = 0;
    284   if (options.fds_to_remap) {
    285     fd_shuffle_size = options.fds_to_remap->size();
    286   }
    287 
    288   InjectiveMultimap fd_shuffle1;
    289   InjectiveMultimap fd_shuffle2;
    290   fd_shuffle1.reserve(fd_shuffle_size);
    291   fd_shuffle2.reserve(fd_shuffle_size);
    292 
    293   scoped_ptr<char*[]> argv_cstr(new char*[argv.size() + 1]);
    294   scoped_ptr<char*[]> new_environ;
    295   char* const empty_environ = NULL;
    296   char* const* old_environ = GetEnvironment();
    297   if (options.clear_environ)
    298     old_environ = &empty_environ;
    299   if (!options.environ.empty())
    300     new_environ = AlterEnvironment(old_environ, options.environ);
    301 
    302   sigset_t full_sigset;
    303   sigfillset(&full_sigset);
    304   const sigset_t orig_sigmask = SetSignalMask(full_sigset);
    305 
    306   pid_t pid;
    307 #if defined(OS_LINUX)
    308   if (options.clone_flags) {
    309     // Signal handling in this function assumes the creation of a new
    310     // process, so we check that a thread is not being created by mistake
    311     // and that signal handling follows the process-creation rules.
    312     RAW_CHECK(
    313         !(options.clone_flags & (CLONE_SIGHAND | CLONE_THREAD | CLONE_VM)));
    314     pid = syscall(__NR_clone, options.clone_flags, 0, 0, 0);
    315   } else
    316 #endif
    317   {
    318     pid = fork();
    319   }
    320 
    321   // Always restore the original signal mask in the parent.
    322   if (pid != 0) {
    323     SetSignalMask(orig_sigmask);
    324   }
    325 
    326   if (pid < 0) {
    327     DPLOG(ERROR) << "fork";
    328     return false;
    329   } else if (pid == 0) {
    330     // Child process
    331 
    332     // DANGER: no calls to malloc or locks are allowed from now on:
    333     // http://crbug.com/36678
    334 
    335     // DANGER: fork() rule: in the child, if you don't end up doing exec*(),
    336     // you call _exit() instead of exit(). This is because _exit() does not
    337     // call any previously-registered (in the parent) exit handlers, which
    338     // might do things like block waiting for threads that don't even exist
    339     // in the child.
    340 
    341     // If a child process uses the readline library, the process block forever.
    342     // In BSD like OSes including OS X it is safe to assign /dev/null as stdin.
    343     // See http://crbug.com/56596.
    344     base::ScopedFD null_fd(HANDLE_EINTR(open("/dev/null", O_RDONLY)));
    345     if (!null_fd.is_valid()) {
    346       RAW_LOG(ERROR, "Failed to open /dev/null");
    347       _exit(127);
    348     }
    349 
    350     int new_fd = HANDLE_EINTR(dup2(null_fd.get(), STDIN_FILENO));
    351     if (new_fd != STDIN_FILENO) {
    352       RAW_LOG(ERROR, "Failed to dup /dev/null for stdin");
    353       _exit(127);
    354     }
    355 
    356     if (options.new_process_group) {
    357       // Instead of inheriting the process group ID of the parent, the child
    358       // starts off a new process group with pgid equal to its process ID.
    359       if (setpgid(0, 0) < 0) {
    360         RAW_LOG(ERROR, "setpgid failed");
    361         _exit(127);
    362       }
    363     }
    364 
    365     // Stop type-profiler.
    366     // The profiler should be stopped between fork and exec since it inserts
    367     // locks at new/delete expressions.  See http://crbug.com/36678.
    368     base::type_profiler::Controller::Stop();
    369 
    370     if (options.maximize_rlimits) {
    371       // Some resource limits need to be maximal in this child.
    372       for (size_t i = 0; i < options.maximize_rlimits->size(); ++i) {
    373         const int resource = (*options.maximize_rlimits)[i];
    374         struct rlimit limit;
    375         if (getrlimit(resource, &limit) < 0) {
    376           RAW_LOG(WARNING, "getrlimit failed");
    377         } else if (limit.rlim_cur < limit.rlim_max) {
    378           limit.rlim_cur = limit.rlim_max;
    379           if (setrlimit(resource, &limit) < 0) {
    380             RAW_LOG(WARNING, "setrlimit failed");
    381           }
    382         }
    383       }
    384     }
    385 
    386 #if defined(OS_MACOSX)
    387     RestoreDefaultExceptionHandler();
    388     if (!options.replacement_bootstrap_name.empty())
    389       ReplaceBootstrapPort(options.replacement_bootstrap_name);
    390 #endif  // defined(OS_MACOSX)
    391 
    392     ResetChildSignalHandlersToDefaults();
    393     SetSignalMask(orig_sigmask);
    394 
    395 #if 0
    396     // When debugging it can be helpful to check that we really aren't making
    397     // any hidden calls to malloc.
    398     void *malloc_thunk =
    399         reinterpret_cast<void*>(reinterpret_cast<intptr_t>(malloc) & ~4095);
    400     mprotect(malloc_thunk, 4096, PROT_READ | PROT_WRITE | PROT_EXEC);
    401     memset(reinterpret_cast<void*>(malloc), 0xff, 8);
    402 #endif  // 0
    403 
    404 #if defined(OS_CHROMEOS)
    405     if (options.ctrl_terminal_fd >= 0) {
    406       // Set process' controlling terminal.
    407       if (HANDLE_EINTR(setsid()) != -1) {
    408         if (HANDLE_EINTR(
    409                 ioctl(options.ctrl_terminal_fd, TIOCSCTTY, NULL)) == -1) {
    410           RAW_LOG(WARNING, "ioctl(TIOCSCTTY), ctrl terminal not set");
    411         }
    412       } else {
    413         RAW_LOG(WARNING, "setsid failed, ctrl terminal not set");
    414       }
    415     }
    416 #endif  // defined(OS_CHROMEOS)
    417 
    418     if (options.fds_to_remap) {
    419       // Cannot use STL iterators here, since debug iterators use locks.
    420       for (size_t i = 0; i < options.fds_to_remap->size(); ++i) {
    421         const FileHandleMappingVector::value_type& value =
    422             (*options.fds_to_remap)[i];
    423         fd_shuffle1.push_back(InjectionArc(value.first, value.second, false));
    424         fd_shuffle2.push_back(InjectionArc(value.first, value.second, false));
    425       }
    426     }
    427 
    428     if (!options.environ.empty() || options.clear_environ)
    429       SetEnvironment(new_environ.get());
    430 
    431     // fd_shuffle1 is mutated by this call because it cannot malloc.
    432     if (!ShuffleFileDescriptors(&fd_shuffle1))
    433       _exit(127);
    434 
    435     CloseSuperfluousFds(fd_shuffle2);
    436 
    437     // Set NO_NEW_PRIVS by default. Since NO_NEW_PRIVS only exists in kernel
    438     // 3.5+, do not check the return value of prctl here.
    439 #if defined(OS_LINUX)
    440 #ifndef PR_SET_NO_NEW_PRIVS
    441 #define PR_SET_NO_NEW_PRIVS 38
    442 #endif
    443     if (!options.allow_new_privs) {
    444       if (prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0) && errno != EINVAL) {
    445         // Only log if the error is not EINVAL (i.e. not supported).
    446         RAW_LOG(FATAL, "prctl(PR_SET_NO_NEW_PRIVS) failed");
    447       }
    448     }
    449 #endif
    450 
    451     for (size_t i = 0; i < argv.size(); i++)
    452       argv_cstr[i] = const_cast<char*>(argv[i].c_str());
    453     argv_cstr[argv.size()] = NULL;
    454     execvp(argv_cstr[0], argv_cstr.get());
    455 
    456     RAW_LOG(ERROR, "LaunchProcess: failed to execvp:");
    457     RAW_LOG(ERROR, argv_cstr[0]);
    458     _exit(127);
    459   } else {
    460     // Parent process
    461     if (options.wait) {
    462       // While this isn't strictly disk IO, waiting for another process to
    463       // finish is the sort of thing ThreadRestrictions is trying to prevent.
    464       base::ThreadRestrictions::AssertIOAllowed();
    465       pid_t ret = HANDLE_EINTR(waitpid(pid, 0, 0));
    466       DPCHECK(ret > 0);
    467     }
    468 
    469     if (process_handle)
    470       *process_handle = pid;
    471   }
    472 
    473   return true;
    474 }
    475 
    476 
    477 bool LaunchProcess(const CommandLine& cmdline,
    478                    const LaunchOptions& options,
    479                    ProcessHandle* process_handle) {
    480   return LaunchProcess(cmdline.argv(), options, process_handle);
    481 }
    482 
    483 void RaiseProcessToHighPriority() {
    484   // On POSIX, we don't actually do anything here.  We could try to nice() or
    485   // setpriority() or sched_getscheduler, but these all require extra rights.
    486 }
    487 
    488 // Return value used by GetAppOutputInternal to encapsulate the various exit
    489 // scenarios from the function.
    490 enum GetAppOutputInternalResult {
    491   EXECUTE_FAILURE,
    492   EXECUTE_SUCCESS,
    493   GOT_MAX_OUTPUT,
    494 };
    495 
    496 // Executes the application specified by |argv| and wait for it to exit. Stores
    497 // the output (stdout) in |output|. If |do_search_path| is set, it searches the
    498 // path for the application; in that case, |envp| must be null, and it will use
    499 // the current environment. If |do_search_path| is false, |argv[0]| should fully
    500 // specify the path of the application, and |envp| will be used as the
    501 // environment. Redirects stderr to /dev/null.
    502 // If we successfully start the application and get all requested output, we
    503 // return GOT_MAX_OUTPUT, or if there is a problem starting or exiting
    504 // the application we return RUN_FAILURE. Otherwise we return EXECUTE_SUCCESS.
    505 // The GOT_MAX_OUTPUT return value exists so a caller that asks for limited
    506 // output can treat this as a success, despite having an exit code of SIG_PIPE
    507 // due to us closing the output pipe.
    508 // In the case of EXECUTE_SUCCESS, the application exit code will be returned
    509 // in |*exit_code|, which should be checked to determine if the application
    510 // ran successfully.
    511 static GetAppOutputInternalResult GetAppOutputInternal(
    512     const std::vector<std::string>& argv,
    513     char* const envp[],
    514     std::string* output,
    515     size_t max_output,
    516     bool do_search_path,
    517     int* exit_code) {
    518   // Doing a blocking wait for another command to finish counts as IO.
    519   base::ThreadRestrictions::AssertIOAllowed();
    520   // exit_code must be supplied so calling function can determine success.
    521   DCHECK(exit_code);
    522   *exit_code = EXIT_FAILURE;
    523 
    524   int pipe_fd[2];
    525   pid_t pid;
    526   InjectiveMultimap fd_shuffle1, fd_shuffle2;
    527   scoped_ptr<char*[]> argv_cstr(new char*[argv.size() + 1]);
    528 
    529   fd_shuffle1.reserve(3);
    530   fd_shuffle2.reserve(3);
    531 
    532   // Either |do_search_path| should be false or |envp| should be null, but not
    533   // both.
    534   DCHECK(!do_search_path ^ !envp);
    535 
    536   if (pipe(pipe_fd) < 0)
    537     return EXECUTE_FAILURE;
    538 
    539   switch (pid = fork()) {
    540     case -1:  // error
    541       close(pipe_fd[0]);
    542       close(pipe_fd[1]);
    543       return EXECUTE_FAILURE;
    544     case 0:  // child
    545       {
    546         // DANGER: no calls to malloc or locks are allowed from now on:
    547         // http://crbug.com/36678
    548 
    549 #if defined(OS_MACOSX)
    550         RestoreDefaultExceptionHandler();
    551 #endif
    552 
    553         // Obscure fork() rule: in the child, if you don't end up doing exec*(),
    554         // you call _exit() instead of exit(). This is because _exit() does not
    555         // call any previously-registered (in the parent) exit handlers, which
    556         // might do things like block waiting for threads that don't even exist
    557         // in the child.
    558         int dev_null = open("/dev/null", O_WRONLY);
    559         if (dev_null < 0)
    560           _exit(127);
    561 
    562         // Stop type-profiler.
    563         // The profiler should be stopped between fork and exec since it inserts
    564         // locks at new/delete expressions.  See http://crbug.com/36678.
    565         base::type_profiler::Controller::Stop();
    566 
    567         fd_shuffle1.push_back(InjectionArc(pipe_fd[1], STDOUT_FILENO, true));
    568         fd_shuffle1.push_back(InjectionArc(dev_null, STDERR_FILENO, true));
    569         fd_shuffle1.push_back(InjectionArc(dev_null, STDIN_FILENO, true));
    570         // Adding another element here? Remeber to increase the argument to
    571         // reserve(), above.
    572 
    573         for (size_t i = 0; i < fd_shuffle1.size(); ++i)
    574           fd_shuffle2.push_back(fd_shuffle1[i]);
    575 
    576         if (!ShuffleFileDescriptors(&fd_shuffle1))
    577           _exit(127);
    578 
    579         CloseSuperfluousFds(fd_shuffle2);
    580 
    581         for (size_t i = 0; i < argv.size(); i++)
    582           argv_cstr[i] = const_cast<char*>(argv[i].c_str());
    583         argv_cstr[argv.size()] = NULL;
    584         if (do_search_path)
    585           execvp(argv_cstr[0], argv_cstr.get());
    586         else
    587           execve(argv_cstr[0], argv_cstr.get(), envp);
    588         _exit(127);
    589       }
    590     default:  // parent
    591       {
    592         // Close our writing end of pipe now. Otherwise later read would not
    593         // be able to detect end of child's output (in theory we could still
    594         // write to the pipe).
    595         close(pipe_fd[1]);
    596 
    597         output->clear();
    598         char buffer[256];
    599         size_t output_buf_left = max_output;
    600         ssize_t bytes_read = 1;  // A lie to properly handle |max_output == 0|
    601                                  // case in the logic below.
    602 
    603         while (output_buf_left > 0) {
    604           bytes_read = HANDLE_EINTR(read(pipe_fd[0], buffer,
    605                                     std::min(output_buf_left, sizeof(buffer))));
    606           if (bytes_read <= 0)
    607             break;
    608           output->append(buffer, bytes_read);
    609           output_buf_left -= static_cast<size_t>(bytes_read);
    610         }
    611         close(pipe_fd[0]);
    612 
    613         // Always wait for exit code (even if we know we'll declare
    614         // GOT_MAX_OUTPUT).
    615         bool success = WaitForExitCode(pid, exit_code);
    616 
    617         // If we stopped because we read as much as we wanted, we return
    618         // GOT_MAX_OUTPUT (because the child may exit due to |SIGPIPE|).
    619         if (!output_buf_left && bytes_read > 0)
    620           return GOT_MAX_OUTPUT;
    621         else if (success)
    622           return EXECUTE_SUCCESS;
    623         return EXECUTE_FAILURE;
    624       }
    625   }
    626 }
    627 
    628 bool GetAppOutput(const CommandLine& cl, std::string* output) {
    629   return GetAppOutput(cl.argv(), output);
    630 }
    631 
    632 bool GetAppOutput(const std::vector<std::string>& argv, std::string* output) {
    633   // Run |execve()| with the current environment and store "unlimited" data.
    634   int exit_code;
    635   GetAppOutputInternalResult result = GetAppOutputInternal(
    636       argv, NULL, output, std::numeric_limits<std::size_t>::max(), true,
    637       &exit_code);
    638   return result == EXECUTE_SUCCESS && exit_code == EXIT_SUCCESS;
    639 }
    640 
    641 // TODO(viettrungluu): Conceivably, we should have a timeout as well, so we
    642 // don't hang if what we're calling hangs.
    643 bool GetAppOutputRestricted(const CommandLine& cl,
    644                             std::string* output, size_t max_output) {
    645   // Run |execve()| with the empty environment.
    646   char* const empty_environ = NULL;
    647   int exit_code;
    648   GetAppOutputInternalResult result = GetAppOutputInternal(
    649       cl.argv(), &empty_environ, output, max_output, false, &exit_code);
    650   return result == GOT_MAX_OUTPUT || (result == EXECUTE_SUCCESS &&
    651                                       exit_code == EXIT_SUCCESS);
    652 }
    653 
    654 bool GetAppOutputWithExitCode(const CommandLine& cl,
    655                               std::string* output,
    656                               int* exit_code) {
    657   // Run |execve()| with the current environment and store "unlimited" data.
    658   GetAppOutputInternalResult result = GetAppOutputInternal(
    659       cl.argv(), NULL, output, std::numeric_limits<std::size_t>::max(), true,
    660       exit_code);
    661   return result == EXECUTE_SUCCESS;
    662 }
    663 
    664 }  // namespace base
    665