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