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