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.
10 #include <sys/resource.h>
12 #include <sys/types.h>
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"
34 #if defined(OS_MACOSX)
35 #include <crt_externs.h>
36 #include <sys/event.h>
37 #define environ (*_NSGetEnviron())
39 extern char** environ
;
46 int WaitpidWithTimeout(ProcessHandle handle
, int64 wait_milliseconds
,
48 // This POSIX version of this function only guarantees that we wait no less
49 // than |wait_milliseconds| for the process to exit. The child process may
50 // exit sometime before the timeout has ended but we may still block for up
51 // to 256 milliseconds after the fact.
53 // waitpid() has no direct support on POSIX for specifying a timeout, you can
54 // either ask it to block indefinitely or return immediately (WNOHANG).
55 // When a child process terminates a SIGCHLD signal is sent to the parent.
56 // Catching this signal would involve installing a signal handler which may
57 // affect other parts of the application and would be difficult to debug.
59 // Our strategy is to call waitpid() once up front to check if the process
60 // has already exited, otherwise to loop for wait_milliseconds, sleeping for
61 // at most 256 milliseconds each time using usleep() and then calling
62 // waitpid(). The amount of time we sleep starts out at 1 milliseconds, and
63 // we double it every 4 sleep cycles.
65 // usleep() is speced to exit if a signal is received for which a handler
66 // has been installed. This means that when a SIGCHLD is sent, it will exit
67 // depending on behavior external to this function.
69 // This function is used primarily for unit tests, if we want to use it in
70 // the application itself it would probably be best to examine other routes.
72 pid_t ret_pid
= HANDLE_EINTR(waitpid(handle
, &status
, WNOHANG
));
73 static const int64 kMaxSleepInMicroseconds
= 1 << 18; // ~256 milliseconds.
74 int64 max_sleep_time_usecs
= 1 << 10; // ~1 milliseconds.
75 int64 double_sleep_time
= 0;
77 // If the process hasn't exited yet, then sleep and try again.
78 Time wakeup_time
= Time::Now() +
79 TimeDelta::FromMilliseconds(wait_milliseconds
);
80 while (ret_pid
== 0) {
81 Time now
= Time::Now();
82 if (now
> wakeup_time
)
84 // Guaranteed to be non-negative!
85 int64 sleep_time_usecs
= (wakeup_time
- now
).InMicroseconds();
86 // Sleep for a bit while we wait for the process to finish.
87 if (sleep_time_usecs
> max_sleep_time_usecs
)
88 sleep_time_usecs
= max_sleep_time_usecs
;
90 // usleep() will return 0 and set errno to EINTR on receipt of a signal
92 usleep(sleep_time_usecs
);
93 ret_pid
= HANDLE_EINTR(waitpid(handle
, &status
, WNOHANG
));
95 if ((max_sleep_time_usecs
< kMaxSleepInMicroseconds
) &&
96 (double_sleep_time
++ % 4 == 0)) {
97 max_sleep_time_usecs
*= 2;
102 *success
= (ret_pid
!= -1);
107 void StackDumpSignalHandler(int signal
, siginfo_t
* info
, ucontext_t
* context
) {
108 LOG(ERROR
) << "Received signal " << signal
;
109 debug::StackTrace().PrintBacktrace();
111 // TODO(shess): Port to Linux.
112 #if defined(OS_MACOSX)
113 // TODO(shess): Port to 64-bit.
118 // NOTE: Even |snprintf()| is not on the approved list for signal
119 // handlers, but buffered I/O is definitely not on the list due to
120 // potential for |malloc()|.
121 len
= static_cast<size_t>(
122 snprintf(buf
, sizeof(buf
),
123 "ax: %x, bx: %x, cx: %x, dx: %x\n",
124 context
->uc_mcontext
->__ss
.__eax
,
125 context
->uc_mcontext
->__ss
.__ebx
,
126 context
->uc_mcontext
->__ss
.__ecx
,
127 context
->uc_mcontext
->__ss
.__edx
));
128 write(STDERR_FILENO
, buf
, std::min(len
, sizeof(buf
) - 1));
130 len
= static_cast<size_t>(
131 snprintf(buf
, sizeof(buf
),
132 "di: %x, si: %x, bp: %x, sp: %x, ss: %x, flags: %x\n",
133 context
->uc_mcontext
->__ss
.__edi
,
134 context
->uc_mcontext
->__ss
.__esi
,
135 context
->uc_mcontext
->__ss
.__ebp
,
136 context
->uc_mcontext
->__ss
.__esp
,
137 context
->uc_mcontext
->__ss
.__ss
,
138 context
->uc_mcontext
->__ss
.__eflags
));
139 write(STDERR_FILENO
, buf
, std::min(len
, sizeof(buf
) - 1));
141 len
= static_cast<size_t>(
142 snprintf(buf
, sizeof(buf
),
143 "ip: %x, cs: %x, ds: %x, es: %x, fs: %x, gs: %x\n",
144 context
->uc_mcontext
->__ss
.__eip
,
145 context
->uc_mcontext
->__ss
.__cs
,
146 context
->uc_mcontext
->__ss
.__ds
,
147 context
->uc_mcontext
->__ss
.__es
,
148 context
->uc_mcontext
->__ss
.__fs
,
149 context
->uc_mcontext
->__ss
.__gs
));
150 write(STDERR_FILENO
, buf
, std::min(len
, sizeof(buf
) - 1));
151 #endif // ARCH_CPU_32_BITS
152 #endif // defined(OS_MACOSX)
156 void ResetChildSignalHandlersToDefaults() {
157 // The previous signal handlers are likely to be meaningless in the child's
158 // context so we reset them to the defaults for now. http://crbug.com/44953
159 // These signal handlers are set up at least in browser_main.cc:BrowserMain
160 // and process_util_posix.cc:EnableInProcessStackDumping.
161 signal(SIGHUP
, SIG_DFL
);
162 signal(SIGINT
, SIG_DFL
);
163 signal(SIGILL
, SIG_DFL
);
164 signal(SIGABRT
, SIG_DFL
);
165 signal(SIGFPE
, SIG_DFL
);
166 signal(SIGBUS
, SIG_DFL
);
167 signal(SIGSEGV
, SIG_DFL
);
168 signal(SIGSYS
, SIG_DFL
);
169 signal(SIGTERM
, SIG_DFL
);
172 } // anonymous namespace
174 ProcessId
GetCurrentProcId() {
178 ProcessHandle
GetCurrentProcessHandle() {
179 return GetCurrentProcId();
182 bool OpenProcessHandle(ProcessId pid
, ProcessHandle
* handle
) {
183 // On Posix platforms, process handles are the same as PIDs, so we
184 // don't need to do anything.
189 bool OpenPrivilegedProcessHandle(ProcessId pid
, ProcessHandle
* handle
) {
190 // On POSIX permissions are checked for each operation on process,
191 // not when opening a "handle".
192 return OpenProcessHandle(pid
, handle
);
195 bool OpenProcessHandleWithAccess(ProcessId pid
,
197 ProcessHandle
* handle
) {
198 // On POSIX permissions are checked for each operation on process,
199 // not when opening a "handle".
200 return OpenProcessHandle(pid
, handle
);
203 void CloseProcessHandle(ProcessHandle process
) {
204 // See OpenProcessHandle, nothing to do.
208 ProcessId
GetProcId(ProcessHandle process
) {
212 // Attempts to kill the process identified by the given process
213 // entry structure. Ignores specified exit_code; posix can't force that.
214 // Returns true if this is successful, false otherwise.
215 bool KillProcess(ProcessHandle process_id
, int exit_code
, bool wait
) {
216 DCHECK_GT(process_id
, 1) << " tried to kill invalid process_id";
219 static unsigned kMaxSleepMs
= 1000;
220 unsigned sleep_ms
= 4;
222 bool result
= kill(process_id
, SIGTERM
) == 0;
224 if (result
&& wait
) {
226 // The process may not end immediately due to pending I/O
228 while (tries
-- > 0) {
229 pid_t pid
= HANDLE_EINTR(waitpid(process_id
, NULL
, WNOHANG
));
230 if (pid
== process_id
) {
235 if (errno
== ECHILD
) {
236 // The wait may fail with ECHILD if another process also waited for
237 // the same pid, causing the process state to get cleaned up.
241 DPLOG(ERROR
) << "Error waiting for process " << process_id
;
244 usleep(sleep_ms
* 1000);
245 if (sleep_ms
< kMaxSleepMs
)
249 // If we're waiting and the child hasn't died by now, force it
252 result
= kill(process_id
, SIGKILL
) == 0;
256 DPLOG(ERROR
) << "Unable to terminate process " << process_id
;
261 bool KillProcessGroup(ProcessHandle process_group_id
) {
262 bool result
= kill(-1 * process_group_id
, SIGKILL
) == 0;
264 PLOG(ERROR
) << "Unable to terminate process group " << process_group_id
;
268 // A class to handle auto-closing of DIR*'s.
269 class ScopedDIRClose
{
271 inline void operator()(DIR* x
) const {
277 typedef scoped_ptr_malloc
<DIR, ScopedDIRClose
> ScopedDIR
;
279 #if defined(OS_LINUX)
280 static const rlim_t kSystemDefaultMaxFds
= 8192;
281 static const char kFDDir
[] = "/proc/self/fd";
282 #elif defined(OS_MACOSX)
283 static const rlim_t kSystemDefaultMaxFds
= 256;
284 static const char kFDDir
[] = "/dev/fd";
285 #elif defined(OS_SOLARIS)
286 static const rlim_t kSystemDefaultMaxFds
= 8192;
287 static const char kFDDir
[] = "/dev/fd";
288 #elif defined(OS_FREEBSD)
289 static const rlim_t kSystemDefaultMaxFds
= 8192;
290 static const char kFDDir
[] = "/dev/fd";
291 #elif defined(OS_OPENBSD)
292 static const rlim_t kSystemDefaultMaxFds
= 256;
293 static const char kFDDir
[] = "/dev/fd";
296 void CloseSuperfluousFds(const base::InjectiveMultimap
& saved_mapping
) {
297 // DANGER: no calls to malloc are allowed from now on:
298 // http://crbug.com/36678
300 // Get the maximum number of FDs possible.
301 struct rlimit nofile
;
303 if (getrlimit(RLIMIT_NOFILE
, &nofile
)) {
304 // getrlimit failed. Take a best guess.
305 max_fds
= kSystemDefaultMaxFds
;
306 RAW_LOG(ERROR
, "getrlimit(RLIMIT_NOFILE) failed");
308 max_fds
= nofile
.rlim_cur
;
311 if (max_fds
> INT_MAX
)
314 DirReaderPosix
fd_dir(kFDDir
);
316 if (!fd_dir
.IsValid()) {
317 // Fallback case: Try every possible fd.
318 for (rlim_t i
= 0; i
< max_fds
; ++i
) {
319 const int fd
= static_cast<int>(i
);
320 if (fd
== STDIN_FILENO
|| fd
== STDOUT_FILENO
|| fd
== STDERR_FILENO
)
322 InjectiveMultimap::const_iterator j
;
323 for (j
= saved_mapping
.begin(); j
!= saved_mapping
.end(); j
++) {
327 if (j
!= saved_mapping
.end())
330 // Since we're just trying to close anything we can find,
331 // ignore any error return values of close().
332 ignore_result(HANDLE_EINTR(close(fd
)));
337 const int dir_fd
= fd_dir
.fd();
339 for ( ; fd_dir
.Next(); ) {
340 // Skip . and .. entries.
341 if (fd_dir
.name()[0] == '.')
346 const long int fd
= strtol(fd_dir
.name(), &endptr
, 10);
347 if (fd_dir
.name()[0] == 0 || *endptr
|| fd
< 0 || errno
)
349 if (fd
== STDIN_FILENO
|| fd
== STDOUT_FILENO
|| fd
== STDERR_FILENO
)
351 InjectiveMultimap::const_iterator i
;
352 for (i
= saved_mapping
.begin(); i
!= saved_mapping
.end(); i
++) {
356 if (i
!= saved_mapping
.end())
361 // When running under Valgrind, Valgrind opens several FDs for its
362 // own use and will complain if we try to close them. All of
363 // these FDs are >= |max_fds|, so we can check against that here
364 // before closing. See https://bugs.kde.org/show_bug.cgi?id=191758
365 if (fd
< static_cast<int>(max_fds
)) {
366 int ret
= HANDLE_EINTR(close(fd
));
372 char** AlterEnvironment(const environment_vector
& changes
,
373 const char* const* const env
) {
377 // First assume that all of the current environment will be included.
378 for (unsigned i
= 0; env
[i
]; i
++) {
379 const char *const pair
= env
[i
];
381 size
+= strlen(pair
) + 1 /* terminating NUL */;
384 for (environment_vector::const_iterator
385 j
= changes
.begin(); j
!= changes
.end(); j
++) {
389 for (unsigned i
= 0; env
[i
]; i
++) {
391 const char *const equals
= strchr(pair
, '=');
394 const unsigned keylen
= equals
- pair
;
395 if (keylen
== j
->first
.size() &&
396 memcmp(pair
, j
->first
.data(), keylen
) == 0) {
402 // if found, we'll either be deleting or replacing this element.
405 size
-= strlen(pair
) + 1;
406 if (j
->second
.size())
410 // if !found, then we have a new element to add.
411 if (!found
&& !j
->second
.empty()) {
413 size
+= j
->first
.size() + 1 /* '=' */ + j
->second
.size() + 1 /* NUL */;
417 count
++; // for the final NULL
418 uint8_t *buffer
= new uint8_t[sizeof(char*) * count
+ size
];
419 char **const ret
= reinterpret_cast<char**>(buffer
);
421 char *scratch
= reinterpret_cast<char*>(buffer
+ sizeof(char*) * count
);
423 for (unsigned i
= 0; env
[i
]; i
++) {
424 const char *const pair
= env
[i
];
425 const char *const equals
= strchr(pair
, '=');
427 const unsigned len
= strlen(pair
);
429 memcpy(scratch
, pair
, len
+ 1);
433 const unsigned keylen
= equals
- pair
;
434 bool handled
= false;
435 for (environment_vector::const_iterator
436 j
= changes
.begin(); j
!= changes
.end(); j
++) {
437 if (j
->first
.size() == keylen
&&
438 memcmp(j
->first
.data(), pair
, keylen
) == 0) {
439 if (!j
->second
.empty()) {
441 memcpy(scratch
, pair
, keylen
+ 1);
442 scratch
+= keylen
+ 1;
443 memcpy(scratch
, j
->second
.c_str(), j
->second
.size() + 1);
444 scratch
+= j
->second
.size() + 1;
452 const unsigned len
= strlen(pair
);
454 memcpy(scratch
, pair
, len
+ 1);
459 // Now handle new elements
460 for (environment_vector::const_iterator
461 j
= changes
.begin(); j
!= changes
.end(); j
++) {
462 if (j
->second
.empty())
466 for (unsigned i
= 0; env
[i
]; i
++) {
467 const char *const pair
= env
[i
];
468 const char *const equals
= strchr(pair
, '=');
471 const unsigned keylen
= equals
- pair
;
472 if (keylen
== j
->first
.size() &&
473 memcmp(pair
, j
->first
.data(), keylen
) == 0) {
481 memcpy(scratch
, j
->first
.data(), j
->first
.size());
482 scratch
+= j
->first
.size();
484 memcpy(scratch
, j
->second
.c_str(), j
->second
.size() + 1);
485 scratch
+= j
->second
.size() + 1;
494 const std::vector
<std::string
>& argv
,
495 const environment_vector
& env_changes
,
496 const file_handle_mapping_vector
& fds_to_remap
,
498 ProcessHandle
* process_handle
,
499 bool start_new_process_group
) {
501 InjectiveMultimap fd_shuffle1
, fd_shuffle2
;
502 fd_shuffle1
.reserve(fds_to_remap
.size());
503 fd_shuffle2
.reserve(fds_to_remap
.size());
504 scoped_array
<char*> argv_cstr(new char*[argv
.size() + 1]);
505 scoped_array
<char*> new_environ(AlterEnvironment(env_changes
, environ
));
509 PLOG(ERROR
) << "fork";
515 // DANGER: fork() rule: in the child, if you don't end up doing exec*(),
516 // you call _exit() instead of exit(). This is because _exit() does not
517 // call any previously-registered (in the parent) exit handlers, which
518 // might do things like block waiting for threads that don't even exist
521 // If a child process uses the readline library, the process block forever.
522 // In BSD like OSes including OS X it is safe to assign /dev/null as stdin.
523 // See http://crbug.com/56596.
524 int null_fd
= HANDLE_EINTR(open("/dev/null", O_RDONLY
));
526 RAW_LOG(ERROR
, "Failed to open /dev/null");
530 file_util::ScopedFD
null_fd_closer(&null_fd
);
531 int new_fd
= HANDLE_EINTR(dup2(null_fd
, STDIN_FILENO
));
532 if (new_fd
!= STDIN_FILENO
) {
533 RAW_LOG(ERROR
, "Failed to dup /dev/null for stdin");
537 if (start_new_process_group
) {
538 // Instead of inheriting the process group ID of the parent, the child
539 // starts off a new process group with pgid equal to its process ID.
540 if (setpgid(0, 0) < 0) {
541 RAW_LOG(ERROR
, "setpgid failed");
545 #if defined(OS_MACOSX)
546 RestoreDefaultExceptionHandler();
549 ResetChildSignalHandlersToDefaults();
552 // When debugging it can be helpful to check that we really aren't making
553 // any hidden calls to malloc.
555 reinterpret_cast<void*>(reinterpret_cast<intptr_t>(malloc
) & ~4095);
556 mprotect(malloc_thunk
, 4096, PROT_READ
| PROT_WRITE
| PROT_EXEC
);
557 memset(reinterpret_cast<void*>(malloc
), 0xff, 8);
560 // DANGER: no calls to malloc are allowed from now on:
561 // http://crbug.com/36678
563 for (file_handle_mapping_vector::const_iterator
564 it
= fds_to_remap
.begin(); it
!= fds_to_remap
.end(); ++it
) {
565 fd_shuffle1
.push_back(InjectionArc(it
->first
, it
->second
, false));
566 fd_shuffle2
.push_back(InjectionArc(it
->first
, it
->second
, false));
569 environ
= new_environ
.get();
571 // fd_shuffle1 is mutated by this call because it cannot malloc.
572 if (!ShuffleFileDescriptors(&fd_shuffle1
))
575 CloseSuperfluousFds(fd_shuffle2
);
577 for (size_t i
= 0; i
< argv
.size(); i
++)
578 argv_cstr
[i
] = const_cast<char*>(argv
[i
].c_str());
579 argv_cstr
[argv
.size()] = NULL
;
580 execvp(argv_cstr
[0], argv_cstr
.get());
581 RAW_LOG(ERROR
, "LaunchApp: failed to execvp:");
582 RAW_LOG(ERROR
, argv_cstr
[0]);
587 // While this isn't strictly disk IO, waiting for another process to
588 // finish is the sort of thing ThreadRestrictions is trying to prevent.
589 base::ThreadRestrictions::AssertIOAllowed();
590 pid_t ret
= HANDLE_EINTR(waitpid(pid
, 0, 0));
595 *process_handle
= pid
;
602 const std::vector
<std::string
>& argv
,
603 const environment_vector
& env_changes
,
604 const file_handle_mapping_vector
& fds_to_remap
,
606 ProcessHandle
* process_handle
) {
607 return LaunchAppImpl(argv
, env_changes
, fds_to_remap
,
608 wait
, process_handle
, false);
611 bool LaunchAppInNewProcessGroup(
612 const std::vector
<std::string
>& argv
,
613 const environment_vector
& env_changes
,
614 const file_handle_mapping_vector
& fds_to_remap
,
616 ProcessHandle
* process_handle
) {
617 return LaunchAppImpl(argv
, env_changes
, fds_to_remap
, wait
,
618 process_handle
, true);
621 bool LaunchApp(const std::vector
<std::string
>& argv
,
622 const file_handle_mapping_vector
& fds_to_remap
,
623 bool wait
, ProcessHandle
* process_handle
) {
624 base::environment_vector no_env
;
625 return LaunchApp(argv
, no_env
, fds_to_remap
, wait
, process_handle
);
628 bool LaunchApp(const CommandLine
& cl
,
629 bool wait
, bool start_hidden
,
630 ProcessHandle
* process_handle
) {
631 file_handle_mapping_vector no_files
;
632 return LaunchApp(cl
.argv(), no_files
, wait
, process_handle
);
635 ProcessMetrics::~ProcessMetrics() { }
637 void EnableTerminationOnHeapCorruption() {
638 // On POSIX, there nothing to do AFAIK.
641 bool EnableInProcessStackDumping() {
642 // When running in an application, our code typically expects SIGPIPE
643 // to be ignored. Therefore, when testing that same code, it should run
644 // with SIGPIPE ignored as well.
645 struct sigaction action
;
646 action
.sa_handler
= SIG_IGN
;
648 sigemptyset(&action
.sa_mask
);
649 bool success
= (sigaction(SIGPIPE
, &action
, NULL
) == 0);
651 sig_t handler
= reinterpret_cast<sig_t
>(&StackDumpSignalHandler
);
652 success
&= (signal(SIGILL
, handler
) != SIG_ERR
);
653 success
&= (signal(SIGABRT
, handler
) != SIG_ERR
);
654 success
&= (signal(SIGFPE
, handler
) != SIG_ERR
);
655 success
&= (signal(SIGBUS
, handler
) != SIG_ERR
);
656 success
&= (signal(SIGSEGV
, handler
) != SIG_ERR
);
657 success
&= (signal(SIGSYS
, handler
) != SIG_ERR
);
662 void RaiseProcessToHighPriority() {
663 // On POSIX, we don't actually do anything here. We could try to nice() or
664 // setpriority() or sched_getscheduler, but these all require extra rights.
667 TerminationStatus
GetTerminationStatus(ProcessHandle handle
, int* exit_code
) {
669 const pid_t result
= HANDLE_EINTR(waitpid(handle
, &status
, WNOHANG
));
671 PLOG(ERROR
) << "waitpid(" << handle
<< ")";
674 return TERMINATION_STATUS_NORMAL_TERMINATION
;
675 } else if (result
== 0) {
676 // the child hasn't exited yet.
679 return TERMINATION_STATUS_STILL_RUNNING
;
685 if (WIFSIGNALED(status
)) {
686 switch (WTERMSIG(status
)) {
692 return TERMINATION_STATUS_PROCESS_CRASHED
;
696 return TERMINATION_STATUS_PROCESS_WAS_KILLED
;
702 if (WIFEXITED(status
) && WEXITSTATUS(status
) != 0)
703 return TERMINATION_STATUS_ABNORMAL_TERMINATION
;
705 return TERMINATION_STATUS_NORMAL_TERMINATION
;
708 bool WaitForExitCode(ProcessHandle handle
, int* exit_code
) {
710 if (HANDLE_EINTR(waitpid(handle
, &status
, 0)) == -1) {
715 if (WIFEXITED(status
)) {
716 *exit_code
= WEXITSTATUS(status
);
720 // If it didn't exit cleanly, it must have been signaled.
721 DCHECK(WIFSIGNALED(status
));
725 bool WaitForExitCodeWithTimeout(ProcessHandle handle
, int* exit_code
,
726 int64 timeout_milliseconds
) {
727 bool waitpid_success
= false;
728 int status
= WaitpidWithTimeout(handle
, timeout_milliseconds
,
732 if (!waitpid_success
)
734 if (WIFSIGNALED(status
)) {
738 if (WIFEXITED(status
)) {
739 *exit_code
= WEXITSTATUS(status
);
745 #if defined(OS_MACOSX)
746 // Using kqueue on Mac so that we can wait on non-child processes.
747 // We can't use kqueues on child processes because we need to reap
748 // our own children using wait.
749 static bool WaitForSingleNonChildProcess(ProcessHandle handle
,
750 int64 wait_milliseconds
) {
753 PLOG(ERROR
) << "kqueue";
757 struct kevent change
= { 0 };
758 EV_SET(&change
, handle
, EVFILT_PROC
, EV_ADD
, NOTE_EXIT
, 0, NULL
);
760 struct timespec spec
;
761 struct timespec
*spec_ptr
;
762 if (wait_milliseconds
!= base::kNoTimeout
) {
763 time_t sec
= static_cast<time_t>(wait_milliseconds
/ 1000);
764 wait_milliseconds
= wait_milliseconds
- (sec
* 1000);
766 spec
.tv_nsec
= wait_milliseconds
* 1000000L;
773 struct kevent event
= { 0 };
774 int event_count
= HANDLE_EINTR(kevent(kq
, &change
, 1, &event
, 1, spec_ptr
));
775 if (close(kq
) != 0) {
776 PLOG(ERROR
) << "close";
778 if (event_count
< 0) {
779 PLOG(ERROR
) << "kevent";
781 } else if (event_count
== 0) {
782 if (wait_milliseconds
!= base::kNoTimeout
) {
786 } else if ((event_count
== 1) &&
787 (handle
== static_cast<pid_t
>(event
.ident
)) &&
788 (event
.filter
== EVFILT_PROC
)) {
789 if (event
.fflags
== NOTE_EXIT
) {
791 } else if (event
.flags
== EV_ERROR
) {
792 LOG(ERROR
) << "kevent error " << event
.data
;
806 bool WaitForSingleProcess(ProcessHandle handle
, int64 wait_milliseconds
) {
807 ProcessHandle parent_pid
= GetParentProcessId(handle
);
808 ProcessHandle our_pid
= Process::Current().handle();
809 if (parent_pid
!= our_pid
) {
810 #if defined(OS_MACOSX)
811 // On Mac we can wait on non child processes.
812 return WaitForSingleNonChildProcess(handle
, wait_milliseconds
);
814 // Currently on Linux we can't handle non child processes.
818 bool waitpid_success
;
820 if (wait_milliseconds
== base::kNoTimeout
)
821 waitpid_success
= (HANDLE_EINTR(waitpid(handle
, &status
, 0)) != -1);
823 status
= WaitpidWithTimeout(handle
, wait_milliseconds
, &waitpid_success
);
825 DCHECK(waitpid_success
);
826 return WIFEXITED(status
);
832 int64
TimeValToMicroseconds(const struct timeval
& tv
) {
833 static const int kMicrosecondsPerSecond
= 1000000;
834 int64 ret
= tv
.tv_sec
; // Avoid (int * int) integer overflow.
835 ret
*= kMicrosecondsPerSecond
;
840 // Executes the application specified by |cl| and wait for it to exit. Stores
841 // the output (stdout) in |output|. If |do_search_path| is set, it searches the
842 // path for the application; in that case, |envp| must be null, and it will use
843 // the current environment. If |do_search_path| is false, |cl| should fully
844 // specify the path of the application, and |envp| will be used as the
845 // environment. Redirects stderr to /dev/null. Returns true on success
846 // (application launched and exited cleanly, with exit code indicating success).
847 static bool GetAppOutputInternal(const CommandLine
& cl
, char* const envp
[],
848 std::string
* output
, size_t max_output
,
849 bool do_search_path
) {
850 // Doing a blocking wait for another command to finish counts as IO.
851 base::ThreadRestrictions::AssertIOAllowed();
855 InjectiveMultimap fd_shuffle1
, fd_shuffle2
;
856 const std::vector
<std::string
>& argv
= cl
.argv();
857 scoped_array
<char*> argv_cstr(new char*[argv
.size() + 1]);
859 fd_shuffle1
.reserve(3);
860 fd_shuffle2
.reserve(3);
862 // Either |do_search_path| should be false or |envp| should be null, but not
864 DCHECK(!do_search_path
^ !envp
);
866 if (pipe(pipe_fd
) < 0)
869 switch (pid
= fork()) {
876 #if defined(OS_MACOSX)
877 RestoreDefaultExceptionHandler();
879 // DANGER: no calls to malloc are allowed from now on:
880 // http://crbug.com/36678
882 // Obscure fork() rule: in the child, if you don't end up doing exec*(),
883 // you call _exit() instead of exit(). This is because _exit() does not
884 // call any previously-registered (in the parent) exit handlers, which
885 // might do things like block waiting for threads that don't even exist
887 int dev_null
= open("/dev/null", O_WRONLY
);
891 fd_shuffle1
.push_back(InjectionArc(pipe_fd
[1], STDOUT_FILENO
, true));
892 fd_shuffle1
.push_back(InjectionArc(dev_null
, STDERR_FILENO
, true));
893 fd_shuffle1
.push_back(InjectionArc(dev_null
, STDIN_FILENO
, true));
894 // Adding another element here? Remeber to increase the argument to
897 std::copy(fd_shuffle1
.begin(), fd_shuffle1
.end(),
898 std::back_inserter(fd_shuffle2
));
900 if (!ShuffleFileDescriptors(&fd_shuffle1
))
903 CloseSuperfluousFds(fd_shuffle2
);
905 for (size_t i
= 0; i
< argv
.size(); i
++)
906 argv_cstr
[i
] = const_cast<char*>(argv
[i
].c_str());
907 argv_cstr
[argv
.size()] = NULL
;
909 execvp(argv_cstr
[0], argv_cstr
.get());
911 execve(argv_cstr
[0], argv_cstr
.get(), envp
);
916 // Close our writing end of pipe now. Otherwise later read would not
917 // be able to detect end of child's output (in theory we could still
918 // write to the pipe).
923 size_t output_buf_left
= max_output
;
924 ssize_t bytes_read
= 1; // A lie to properly handle |max_output == 0|
925 // case in the logic below.
927 while (output_buf_left
> 0) {
928 bytes_read
= HANDLE_EINTR(read(pipe_fd
[0], buffer
,
929 std::min(output_buf_left
, sizeof(buffer
))));
932 output
->append(buffer
, bytes_read
);
933 output_buf_left
-= static_cast<size_t>(bytes_read
);
937 // Always wait for exit code (even if we know we'll declare success).
938 int exit_code
= EXIT_FAILURE
;
939 bool success
= WaitForExitCode(pid
, &exit_code
);
941 // If we stopped because we read as much as we wanted, we always declare
942 // success (because the child may exit due to |SIGPIPE|).
943 if (output_buf_left
|| bytes_read
<= 0) {
944 if (!success
|| exit_code
!= EXIT_SUCCESS
)
953 bool GetAppOutput(const CommandLine
& cl
, std::string
* output
) {
954 // Run |execve()| with the current environment and store "unlimited" data.
955 return GetAppOutputInternal(cl
, NULL
, output
,
956 std::numeric_limits
<std::size_t>::max(), true);
959 // TODO(viettrungluu): Conceivably, we should have a timeout as well, so we
960 // don't hang if what we're calling hangs.
961 bool GetAppOutputRestricted(const CommandLine
& cl
,
962 std::string
* output
, size_t max_output
) {
963 // Run |execve()| with the empty environment.
964 char* const empty_environ
= NULL
;
965 return GetAppOutputInternal(cl
, &empty_environ
, output
, max_output
, false);
968 bool WaitForProcessesToExit(const FilePath::StringType
& executable_name
,
969 int64 wait_milliseconds
,
970 const ProcessFilter
* filter
) {
973 // TODO(port): This is inefficient, but works if there are multiple procs.
974 // TODO(port): use waitpid to avoid leaving zombies around
976 base::Time end_time
= base::Time::Now() +
977 base::TimeDelta::FromMilliseconds(wait_milliseconds
);
979 NamedProcessIterator
iter(executable_name
, filter
);
980 if (!iter
.NextProcessEntry()) {
984 base::PlatformThread::Sleep(100);
985 } while ((base::Time::Now() - end_time
) > base::TimeDelta());
990 bool CleanupProcesses(const FilePath::StringType
& executable_name
,
991 int64 wait_milliseconds
,
993 const ProcessFilter
* filter
) {
994 bool exited_cleanly
=
995 WaitForProcessesToExit(executable_name
, wait_milliseconds
,
998 KillProcesses(executable_name
, exit_code
, filter
);
999 return exited_cleanly
;