Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(187)

Side by Side Diff: base/process/launch_posix.cc

Issue 2118583004: Remove unused function from base/process (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Fix NULL Created 4 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « base/process/launch.h ('k') | base/process/process_util_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "base/process/launch.h" 5 #include "base/process/launch.h"
6 6
7 #include <dirent.h> 7 #include <dirent.h>
8 #include <errno.h> 8 #include <errno.h>
9 #include <fcntl.h> 9 #include <fcntl.h>
10 #include <sched.h> 10 #include <sched.h>
(...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after
145 // glibc's sigaction() will prevent access to sa_restorer, so we need to roll 145 // glibc's sigaction() will prevent access to sa_restorer, so we need to roll
146 // our own. 146 // our own.
147 int sys_rt_sigaction(int sig, const struct kernel_sigaction* act, 147 int sys_rt_sigaction(int sig, const struct kernel_sigaction* act,
148 struct kernel_sigaction* oact) { 148 struct kernel_sigaction* oact) {
149 return syscall(SYS_rt_sigaction, sig, act, oact, sizeof(kernel_sigset_t)); 149 return syscall(SYS_rt_sigaction, sig, act, oact, sizeof(kernel_sigset_t));
150 } 150 }
151 151
152 // This function is intended to be used in between fork() and execve() and will 152 // This function is intended to be used in between fork() and execve() and will
153 // reset all signal handlers to the default. 153 // reset all signal handlers to the default.
154 // The motivation for going through all of them is that sa_restorer can leak 154 // The motivation for going through all of them is that sa_restorer can leak
155 // from parents and help defeat ASLR on buggy kernels. We reset it to NULL. 155 // from parents and help defeat ASLR on buggy kernels. We reset it to null.
156 // See crbug.com/177956. 156 // See crbug.com/177956.
157 void ResetChildSignalHandlersToDefaults(void) { 157 void ResetChildSignalHandlersToDefaults(void) {
158 for (int signum = 1; ; ++signum) { 158 for (int signum = 1; ; ++signum) {
159 struct kernel_sigaction act = {0}; 159 struct kernel_sigaction act = {0};
160 int sigaction_get_ret = sys_rt_sigaction(signum, NULL, &act); 160 int sigaction_get_ret = sys_rt_sigaction(signum, nullptr, &act);
161 if (sigaction_get_ret && errno == EINVAL) { 161 if (sigaction_get_ret && errno == EINVAL) {
162 #if !defined(NDEBUG) 162 #if !defined(NDEBUG)
163 // Linux supports 32 real-time signals from 33 to 64. 163 // Linux supports 32 real-time signals from 33 to 64.
164 // If the number of signals in the Linux kernel changes, someone should 164 // If the number of signals in the Linux kernel changes, someone should
165 // look at this code. 165 // look at this code.
166 const int kNumberOfSignals = 64; 166 const int kNumberOfSignals = 64;
167 RAW_CHECK(signum == kNumberOfSignals + 1); 167 RAW_CHECK(signum == kNumberOfSignals + 1);
168 #endif // !defined(NDEBUG) 168 #endif // !defined(NDEBUG)
169 break; 169 break;
170 } 170 }
171 // All other failures are fatal. 171 // All other failures are fatal.
172 if (sigaction_get_ret) { 172 if (sigaction_get_ret) {
173 RAW_LOG(FATAL, "sigaction (get) failed."); 173 RAW_LOG(FATAL, "sigaction (get) failed.");
174 } 174 }
175 175
176 // The kernel won't allow to re-set SIGKILL or SIGSTOP. 176 // The kernel won't allow to re-set SIGKILL or SIGSTOP.
177 if (signum != SIGSTOP && signum != SIGKILL) { 177 if (signum != SIGSTOP && signum != SIGKILL) {
178 act.k_sa_handler = reinterpret_cast<void*>(SIG_DFL); 178 act.k_sa_handler = reinterpret_cast<void*>(SIG_DFL);
179 act.k_sa_restorer = NULL; 179 act.k_sa_restorer = nullptr;
180 if (sys_rt_sigaction(signum, &act, NULL)) { 180 if (sys_rt_sigaction(signum, &act, nullptr)) {
181 RAW_LOG(FATAL, "sigaction (set) failed."); 181 RAW_LOG(FATAL, "sigaction (set) failed.");
182 } 182 }
183 } 183 }
184 #if !defined(NDEBUG) 184 #if !defined(NDEBUG)
185 // Now ask the kernel again and check that no restorer will leak. 185 // Now ask the kernel again and check that no restorer will leak.
186 if (sys_rt_sigaction(signum, NULL, &act) || act.k_sa_restorer) { 186 if (sys_rt_sigaction(signum, nullptr, &act) || act.k_sa_restorer) {
187 RAW_LOG(FATAL, "Cound not fix sa_restorer."); 187 RAW_LOG(FATAL, "Cound not fix sa_restorer.");
188 } 188 }
189 #endif // !defined(NDEBUG) 189 #endif // !defined(NDEBUG)
190 } 190 }
191 } 191 }
192 #endif // !defined(OS_LINUX) || 192 #endif // !defined(OS_LINUX) ||
193 // (!defined(__i386__) && !defined(__x86_64__) && !defined(__arm__)) 193 // (!defined(__i386__) && !defined(__x86_64__) && !defined(__arm__))
194 } // anonymous namespace 194 } // anonymous namespace
195 195
196 // Functor for |ScopedDIR| (below). 196 // Functor for |ScopedDIR| (below).
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after
298 298
299 InjectiveMultimap fd_shuffle1; 299 InjectiveMultimap fd_shuffle1;
300 InjectiveMultimap fd_shuffle2; 300 InjectiveMultimap fd_shuffle2;
301 fd_shuffle1.reserve(fd_shuffle_size); 301 fd_shuffle1.reserve(fd_shuffle_size);
302 fd_shuffle2.reserve(fd_shuffle_size); 302 fd_shuffle2.reserve(fd_shuffle_size);
303 303
304 std::unique_ptr<char* []> argv_cstr(new char*[argv.size() + 1]); 304 std::unique_ptr<char* []> argv_cstr(new char*[argv.size() + 1]);
305 for (size_t i = 0; i < argv.size(); i++) { 305 for (size_t i = 0; i < argv.size(); i++) {
306 argv_cstr[i] = const_cast<char*>(argv[i].c_str()); 306 argv_cstr[i] = const_cast<char*>(argv[i].c_str());
307 } 307 }
308 argv_cstr[argv.size()] = NULL; 308 argv_cstr[argv.size()] = nullptr;
309 309
310 std::unique_ptr<char* []> new_environ; 310 std::unique_ptr<char* []> new_environ;
311 char* const empty_environ = NULL; 311 char* const empty_environ = nullptr;
312 char* const* old_environ = GetEnvironment(); 312 char* const* old_environ = GetEnvironment();
313 if (options.clear_environ) 313 if (options.clear_environ)
314 old_environ = &empty_environ; 314 old_environ = &empty_environ;
315 if (!options.environ.empty()) 315 if (!options.environ.empty())
316 new_environ = AlterEnvironment(old_environ, options.environ); 316 new_environ = AlterEnvironment(old_environ, options.environ);
317 317
318 sigset_t full_sigset; 318 sigset_t full_sigset;
319 sigfillset(&full_sigset); 319 sigfillset(&full_sigset);
320 const sigset_t orig_sigmask = SetSignalMask(full_sigset); 320 const sigset_t orig_sigmask = SetSignalMask(full_sigset);
321 321
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after
423 reinterpret_cast<void*>(reinterpret_cast<intptr_t>(malloc) & ~4095); 423 reinterpret_cast<void*>(reinterpret_cast<intptr_t>(malloc) & ~4095);
424 mprotect(malloc_thunk, 4096, PROT_READ | PROT_WRITE | PROT_EXEC); 424 mprotect(malloc_thunk, 4096, PROT_READ | PROT_WRITE | PROT_EXEC);
425 memset(reinterpret_cast<void*>(malloc), 0xff, 8); 425 memset(reinterpret_cast<void*>(malloc), 0xff, 8);
426 #endif // 0 426 #endif // 0
427 427
428 #if defined(OS_CHROMEOS) 428 #if defined(OS_CHROMEOS)
429 if (options.ctrl_terminal_fd >= 0) { 429 if (options.ctrl_terminal_fd >= 0) {
430 // Set process' controlling terminal. 430 // Set process' controlling terminal.
431 if (HANDLE_EINTR(setsid()) != -1) { 431 if (HANDLE_EINTR(setsid()) != -1) {
432 if (HANDLE_EINTR( 432 if (HANDLE_EINTR(
433 ioctl(options.ctrl_terminal_fd, TIOCSCTTY, NULL)) == -1) { 433 ioctl(options.ctrl_terminal_fd, TIOCSCTTY, nullptr)) == -1) {
434 RAW_LOG(WARNING, "ioctl(TIOCSCTTY), ctrl terminal not set"); 434 RAW_LOG(WARNING, "ioctl(TIOCSCTTY), ctrl terminal not set");
435 } 435 }
436 } else { 436 } else {
437 RAW_LOG(WARNING, "setsid failed, ctrl terminal not set"); 437 RAW_LOG(WARNING, "setsid failed, ctrl terminal not set");
438 } 438 }
439 } 439 }
440 #endif // defined(OS_CHROMEOS) 440 #endif // defined(OS_CHROMEOS)
441 441
442 if (options.fds_to_remap) { 442 if (options.fds_to_remap) {
443 // Cannot use STL iterators here, since debug iterators use locks. 443 // Cannot use STL iterators here, since debug iterators use locks.
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
504 } 504 }
505 505
506 return Process(pid); 506 return Process(pid);
507 } 507 }
508 508
509 void RaiseProcessToHighPriority() { 509 void RaiseProcessToHighPriority() {
510 // On POSIX, we don't actually do anything here. We could try to nice() or 510 // On POSIX, we don't actually do anything here. We could try to nice() or
511 // setpriority() or sched_getscheduler, but these all require extra rights. 511 // setpriority() or sched_getscheduler, but these all require extra rights.
512 } 512 }
513 513
514 // Return value used by GetAppOutputInternal to encapsulate the various exit
515 // scenarios from the function.
516 enum GetAppOutputInternalResult {
517 EXECUTE_FAILURE,
518 EXECUTE_SUCCESS,
519 GOT_MAX_OUTPUT,
520 };
521
522 // Executes the application specified by |argv| and wait for it to exit. Stores 514 // Executes the application specified by |argv| and wait for it to exit. Stores
523 // the output (stdout) in |output|. If |do_search_path| is set, it searches the 515 // the output (stdout) in |output|. If |do_search_path| is set, it searches the
524 // path for the application; in that case, |envp| must be null, and it will use 516 // path for the application; in that case, |envp| must be null, and it will use
525 // the current environment. If |do_search_path| is false, |argv[0]| should fully 517 // the current environment. If |do_search_path| is false, |argv[0]| should fully
526 // specify the path of the application, and |envp| will be used as the 518 // specify the path of the application, and |envp| will be used as the
527 // environment. If |include_stderr| is true, includes stderr otherwise redirects 519 // environment. If |include_stderr| is true, includes stderr otherwise redirects
528 // it to /dev/null. 520 // it to /dev/null.
529 // If we successfully start the application and get all requested output, we 521 // The return value of the function indicates success or failure. In the case of
530 // return GOT_MAX_OUTPUT, or if there is a problem starting or exiting 522 // success, the application exit code will be returned in |*exit_code|, which
531 // the application we return RUN_FAILURE. Otherwise we return EXECUTE_SUCCESS. 523 // should be checked to determine if the application ran successfully.
532 // The GOT_MAX_OUTPUT return value exists so a caller that asks for limited 524 static bool GetAppOutputInternal(
533 // output can treat this as a success, despite having an exit code of SIG_PIPE
534 // due to us closing the output pipe.
535 // In the case of EXECUTE_SUCCESS, the application exit code will be returned
536 // in |*exit_code|, which should be checked to determine if the application
537 // ran successfully.
538 static GetAppOutputInternalResult GetAppOutputInternal(
539 const std::vector<std::string>& argv, 525 const std::vector<std::string>& argv,
540 char* const envp[], 526 char* const envp[],
541 bool include_stderr, 527 bool include_stderr,
542 std::string* output, 528 std::string* output,
543 size_t max_output,
544 bool do_search_path, 529 bool do_search_path,
545 int* exit_code) { 530 int* exit_code) {
546 // Doing a blocking wait for another command to finish counts as IO. 531 // Doing a blocking wait for another command to finish counts as IO.
547 base::ThreadRestrictions::AssertIOAllowed(); 532 base::ThreadRestrictions::AssertIOAllowed();
548 // exit_code must be supplied so calling function can determine success. 533 // exit_code must be supplied so calling function can determine success.
549 DCHECK(exit_code); 534 DCHECK(exit_code);
550 *exit_code = EXIT_FAILURE; 535 *exit_code = EXIT_FAILURE;
551 536
552 int pipe_fd[2]; 537 int pipe_fd[2];
553 pid_t pid; 538 pid_t pid;
554 InjectiveMultimap fd_shuffle1, fd_shuffle2; 539 InjectiveMultimap fd_shuffle1, fd_shuffle2;
555 std::unique_ptr<char* []> argv_cstr(new char*[argv.size() + 1]); 540 std::unique_ptr<char* []> argv_cstr(new char*[argv.size() + 1]);
556 541
557 fd_shuffle1.reserve(3); 542 fd_shuffle1.reserve(3);
558 fd_shuffle2.reserve(3); 543 fd_shuffle2.reserve(3);
559 544
560 // Either |do_search_path| should be false or |envp| should be null, but not 545 // Either |do_search_path| should be false or |envp| should be null, but not
561 // both. 546 // both.
562 DCHECK(!do_search_path ^ !envp); 547 DCHECK(!do_search_path ^ !envp);
563 548
564 if (pipe(pipe_fd) < 0) 549 if (pipe(pipe_fd) < 0)
565 return EXECUTE_FAILURE; 550 return false;
566 551
567 switch (pid = fork()) { 552 switch (pid = fork()) {
568 case -1: // error 553 case -1: // error
569 close(pipe_fd[0]); 554 close(pipe_fd[0]);
570 close(pipe_fd[1]); 555 close(pipe_fd[1]);
571 return EXECUTE_FAILURE; 556 return false;
572 case 0: // child 557 case 0: // child
573 { 558 {
574 // DANGER: no calls to malloc or locks are allowed from now on: 559 // DANGER: no calls to malloc or locks are allowed from now on:
575 // http://crbug.com/36678 560 // http://crbug.com/36678
576 561
577 #if defined(OS_MACOSX) 562 #if defined(OS_MACOSX)
578 RestoreDefaultExceptionHandler(); 563 RestoreDefaultExceptionHandler();
579 #endif 564 #endif
580 565
581 // Obscure fork() rule: in the child, if you don't end up doing exec*(), 566 // Obscure fork() rule: in the child, if you don't end up doing exec*(),
(...skipping 16 matching lines...) Expand all
598 for (size_t i = 0; i < fd_shuffle1.size(); ++i) 583 for (size_t i = 0; i < fd_shuffle1.size(); ++i)
599 fd_shuffle2.push_back(fd_shuffle1[i]); 584 fd_shuffle2.push_back(fd_shuffle1[i]);
600 585
601 if (!ShuffleFileDescriptors(&fd_shuffle1)) 586 if (!ShuffleFileDescriptors(&fd_shuffle1))
602 _exit(127); 587 _exit(127);
603 588
604 CloseSuperfluousFds(fd_shuffle2); 589 CloseSuperfluousFds(fd_shuffle2);
605 590
606 for (size_t i = 0; i < argv.size(); i++) 591 for (size_t i = 0; i < argv.size(); i++)
607 argv_cstr[i] = const_cast<char*>(argv[i].c_str()); 592 argv_cstr[i] = const_cast<char*>(argv[i].c_str());
608 argv_cstr[argv.size()] = NULL; 593 argv_cstr[argv.size()] = nullptr;
609 if (do_search_path) 594 if (do_search_path)
610 execvp(argv_cstr[0], argv_cstr.get()); 595 execvp(argv_cstr[0], argv_cstr.get());
611 else 596 else
612 execve(argv_cstr[0], argv_cstr.get(), envp); 597 execve(argv_cstr[0], argv_cstr.get(), envp);
613 _exit(127); 598 _exit(127);
614 } 599 }
615 default: // parent 600 default: // parent
616 { 601 {
617 // Close our writing end of pipe now. Otherwise later read would not 602 // Close our writing end of pipe now. Otherwise later read would not
618 // be able to detect end of child's output (in theory we could still 603 // be able to detect end of child's output (in theory we could still
619 // write to the pipe). 604 // write to the pipe).
620 close(pipe_fd[1]); 605 close(pipe_fd[1]);
621 606
622 output->clear(); 607 output->clear();
623 char buffer[256];
624 size_t output_buf_left = max_output;
625 ssize_t bytes_read = 1; // A lie to properly handle |max_output == 0|
626 // case in the logic below.
627 608
628 while (output_buf_left > 0) { 609 while (true) {
629 bytes_read = HANDLE_EINTR(read(pipe_fd[0], buffer, 610 char buffer[256];
630 std::min(output_buf_left, sizeof(buffer)))); 611 ssize_t bytes_read =
612 HANDLE_EINTR(read(pipe_fd[0], buffer, sizeof(buffer)));
631 if (bytes_read <= 0) 613 if (bytes_read <= 0)
632 break; 614 break;
633 output->append(buffer, bytes_read); 615 output->append(buffer, bytes_read);
634 output_buf_left -= static_cast<size_t>(bytes_read);
635 } 616 }
636 close(pipe_fd[0]); 617 close(pipe_fd[0]);
637 618
638 // Always wait for exit code (even if we know we'll declare 619 // Always wait for exit code (even if we know we'll declare
639 // GOT_MAX_OUTPUT). 620 // GOT_MAX_OUTPUT).
640 Process process(pid); 621 Process process(pid);
641 bool success = process.WaitForExit(exit_code); 622 return process.WaitForExit(exit_code);
642
643 // If we stopped because we read as much as we wanted, we return
644 // GOT_MAX_OUTPUT (because the child may exit due to |SIGPIPE|).
645 if (!output_buf_left && bytes_read > 0)
646 return GOT_MAX_OUTPUT;
647 else if (success)
648 return EXECUTE_SUCCESS;
649 return EXECUTE_FAILURE;
650 } 623 }
651 } 624 }
652 } 625 }
653 626
654 bool GetAppOutput(const CommandLine& cl, std::string* output) { 627 bool GetAppOutput(const CommandLine& cl, std::string* output) {
655 return GetAppOutput(cl.argv(), output); 628 return GetAppOutput(cl.argv(), output);
656 } 629 }
657 630
658 bool GetAppOutput(const std::vector<std::string>& argv, std::string* output) { 631 bool GetAppOutput(const std::vector<std::string>& argv, std::string* output) {
659 // Run |execve()| with the current environment and store "unlimited" data. 632 // Run |execve()| with the current environment.
660 int exit_code; 633 int exit_code;
661 GetAppOutputInternalResult result = GetAppOutputInternal( 634 bool result =
662 argv, NULL, false, output, std::numeric_limits<std::size_t>::max(), true, 635 GetAppOutputInternal(argv, nullptr, false, output, true, &exit_code);
663 &exit_code); 636 return result && exit_code == EXIT_SUCCESS;
664 return result == EXECUTE_SUCCESS && exit_code == EXIT_SUCCESS;
665 } 637 }
666 638
667 bool GetAppOutputAndError(const CommandLine& cl, std::string* output) { 639 bool GetAppOutputAndError(const CommandLine& cl, std::string* output) {
668 // Run |execve()| with the current environment and store "unlimited" data. 640 // Run |execve()| with the current environment.
669 int exit_code; 641 int exit_code;
670 GetAppOutputInternalResult result = GetAppOutputInternal( 642 bool result =
671 cl.argv(), NULL, true, output, std::numeric_limits<std::size_t>::max(), 643 GetAppOutputInternal(cl.argv(), nullptr, true, output, true, &exit_code);
672 true, &exit_code); 644 return result && exit_code == EXIT_SUCCESS;
673 return result == EXECUTE_SUCCESS && exit_code == EXIT_SUCCESS;
674 }
675
676 // TODO(viettrungluu): Conceivably, we should have a timeout as well, so we
677 // don't hang if what we're calling hangs.
678 bool GetAppOutputRestricted(const CommandLine& cl,
679 std::string* output, size_t max_output) {
680 // Run |execve()| with the empty environment.
681 char* const empty_environ = NULL;
682 int exit_code;
683 GetAppOutputInternalResult result = GetAppOutputInternal(
684 cl.argv(), &empty_environ, false, output, max_output, false, &exit_code);
685 return result == GOT_MAX_OUTPUT || (result == EXECUTE_SUCCESS &&
686 exit_code == EXIT_SUCCESS);
687 } 645 }
688 646
689 bool GetAppOutputWithExitCode(const CommandLine& cl, 647 bool GetAppOutputWithExitCode(const CommandLine& cl,
690 std::string* output, 648 std::string* output,
691 int* exit_code) { 649 int* exit_code) {
692 // Run |execve()| with the current environment and store "unlimited" data. 650 // Run |execve()| with the current environment.
693 GetAppOutputInternalResult result = GetAppOutputInternal( 651 return GetAppOutputInternal(cl.argv(), nullptr, false, output, true,
694 cl.argv(), NULL, false, output, std::numeric_limits<std::size_t>::max(), 652 exit_code);
695 true, exit_code);
696 return result == EXECUTE_SUCCESS;
697 } 653 }
698 654
699 #endif // !defined(OS_NACL_NONSFI) 655 #endif // !defined(OS_NACL_NONSFI)
700 656
701 #if defined(OS_LINUX) || defined(OS_NACL_NONSFI) 657 #if defined(OS_LINUX) || defined(OS_NACL_NONSFI)
702 namespace { 658 namespace {
703 659
704 bool IsRunningOnValgrind() { 660 bool IsRunningOnValgrind() {
705 return RUNNING_ON_VALGRIND; 661 return RUNNING_ON_VALGRIND;
706 } 662 }
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after
783 jmp_buf env; 739 jmp_buf env;
784 if (setjmp(env) == 0) { 740 if (setjmp(env) == 0) {
785 return CloneAndLongjmpInChild(flags, ptid, ctid, &env); 741 return CloneAndLongjmpInChild(flags, ptid, ctid, &env);
786 } 742 }
787 743
788 return 0; 744 return 0;
789 } 745 }
790 #endif // defined(OS_LINUX) || defined(OS_NACL_NONSFI) 746 #endif // defined(OS_LINUX) || defined(OS_NACL_NONSFI)
791 747
792 } // namespace base 748 } // namespace base
OLDNEW
« no previous file with comments | « base/process/launch.h ('k') | base/process/process_util_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698