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