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

Side by Side Diff: base/process_util_posix.cc

Issue 7283019: base: refactor LaunchApp variants into a single function (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: desktop Created 9 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 | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 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 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 <dirent.h> 5 #include <dirent.h>
6 #include <errno.h> 6 #include <errno.h>
7 #include <fcntl.h> 7 #include <fcntl.h>
8 #include <signal.h> 8 #include <signal.h>
9 #include <stdlib.h> 9 #include <stdlib.h>
10 #include <sys/resource.h> 10 #include <sys/resource.h>
(...skipping 484 matching lines...) Expand 10 before | Expand all | Expand 10 after
495 *scratch++ = '='; 495 *scratch++ = '=';
496 memcpy(scratch, j->second.c_str(), j->second.size() + 1); 496 memcpy(scratch, j->second.c_str(), j->second.size() + 1);
497 scratch += j->second.size() + 1; 497 scratch += j->second.size() + 1;
498 } 498 }
499 } 499 }
500 500
501 ret[k] = NULL; 501 ret[k] = NULL;
502 return ret; 502 return ret;
503 } 503 }
504 504
505 bool LaunchAppImpl( 505 bool LaunchProcess(const std::vector<std::string>& argv,
506 const std::vector<std::string>& argv, 506 const LaunchOptions& options) {
507 const environment_vector& env_changes,
508 const file_handle_mapping_vector& fds_to_remap,
509 bool wait,
510 ProcessHandle* process_handle,
511 bool start_new_process_group) {
512 pid_t pid; 507 pid_t pid;
513 InjectiveMultimap fd_shuffle1, fd_shuffle2; 508 InjectiveMultimap fd_shuffle1, fd_shuffle2;
514 fd_shuffle1.reserve(fds_to_remap.size()); 509 if (options.fds_to_remap) {
515 fd_shuffle2.reserve(fds_to_remap.size()); 510 fd_shuffle1.reserve(options.fds_to_remap->size());
511 fd_shuffle2.reserve(options.fds_to_remap->size());
512 }
516 scoped_array<char*> argv_cstr(new char*[argv.size() + 1]); 513 scoped_array<char*> argv_cstr(new char*[argv.size() + 1]);
517 scoped_array<char*> new_environ(AlterEnvironment(env_changes, environ)); 514 scoped_array<char*> new_environ;
515 if (options.environ)
516 new_environ.reset(AlterEnvironment(*options.environ, environ));
518 517
519 pid = fork(); 518 pid = fork();
520 if (pid < 0) { 519 if (pid < 0) {
521 PLOG(ERROR) << "fork"; 520 PLOG(ERROR) << "fork";
522 return false; 521 return false;
523 } 522 }
524 if (pid == 0) { 523 if (pid == 0) {
525 // Child process 524 // Child process
526 525
527 // DANGER: fork() rule: in the child, if you don't end up doing exec*(), 526 // DANGER: fork() rule: in the child, if you don't end up doing exec*(),
(...skipping 11 matching lines...) Expand all
539 _exit(127); 538 _exit(127);
540 } 539 }
541 540
542 file_util::ScopedFD null_fd_closer(&null_fd); 541 file_util::ScopedFD null_fd_closer(&null_fd);
543 int new_fd = HANDLE_EINTR(dup2(null_fd, STDIN_FILENO)); 542 int new_fd = HANDLE_EINTR(dup2(null_fd, STDIN_FILENO));
544 if (new_fd != STDIN_FILENO) { 543 if (new_fd != STDIN_FILENO) {
545 RAW_LOG(ERROR, "Failed to dup /dev/null for stdin"); 544 RAW_LOG(ERROR, "Failed to dup /dev/null for stdin");
546 _exit(127); 545 _exit(127);
547 } 546 }
548 547
549 if (start_new_process_group) { 548 if (options.new_process_group) {
550 // Instead of inheriting the process group ID of the parent, the child 549 // Instead of inheriting the process group ID of the parent, the child
551 // starts off a new process group with pgid equal to its process ID. 550 // starts off a new process group with pgid equal to its process ID.
552 if (setpgid(0, 0) < 0) { 551 if (setpgid(0, 0) < 0) {
553 RAW_LOG(ERROR, "setpgid failed"); 552 RAW_LOG(ERROR, "setpgid failed");
554 _exit(127); 553 _exit(127);
555 } 554 }
556 } 555 }
557 #if defined(OS_MACOSX) 556 #if defined(OS_MACOSX)
558 RestoreDefaultExceptionHandler(); 557 RestoreDefaultExceptionHandler();
559 #endif 558 #endif
560 559
561 ResetChildSignalHandlersToDefaults(); 560 ResetChildSignalHandlersToDefaults();
562 561
563 #if 0 562 #if 0
564 // When debugging it can be helpful to check that we really aren't making 563 // When debugging it can be helpful to check that we really aren't making
565 // any hidden calls to malloc. 564 // any hidden calls to malloc.
566 void *malloc_thunk = 565 void *malloc_thunk =
567 reinterpret_cast<void*>(reinterpret_cast<intptr_t>(malloc) & ~4095); 566 reinterpret_cast<void*>(reinterpret_cast<intptr_t>(malloc) & ~4095);
568 mprotect(malloc_thunk, 4096, PROT_READ | PROT_WRITE | PROT_EXEC); 567 mprotect(malloc_thunk, 4096, PROT_READ | PROT_WRITE | PROT_EXEC);
569 memset(reinterpret_cast<void*>(malloc), 0xff, 8); 568 memset(reinterpret_cast<void*>(malloc), 0xff, 8);
570 #endif 569 #endif
571 570
572 // DANGER: no calls to malloc are allowed from now on: 571 // DANGER: no calls to malloc are allowed from now on:
573 // http://crbug.com/36678 572 // http://crbug.com/36678
574 573
575 for (file_handle_mapping_vector::const_iterator 574 if (options.fds_to_remap) {
576 it = fds_to_remap.begin(); it != fds_to_remap.end(); ++it) { 575 for (file_handle_mapping_vector::const_iterator
577 fd_shuffle1.push_back(InjectionArc(it->first, it->second, false)); 576 it = options.fds_to_remap->begin();
578 fd_shuffle2.push_back(InjectionArc(it->first, it->second, false)); 577 it != options.fds_to_remap->end(); ++it) {
578 fd_shuffle1.push_back(InjectionArc(it->first, it->second, false));
579 fd_shuffle2.push_back(InjectionArc(it->first, it->second, false));
580 }
579 } 581 }
580 582
581 environ = new_environ.get(); 583 if (options.environ)
584 environ = new_environ.get();
582 585
583 // fd_shuffle1 is mutated by this call because it cannot malloc. 586 // fd_shuffle1 is mutated by this call because it cannot malloc.
584 if (!ShuffleFileDescriptors(&fd_shuffle1)) 587 if (!ShuffleFileDescriptors(&fd_shuffle1))
585 _exit(127); 588 _exit(127);
586 589
587 CloseSuperfluousFds(fd_shuffle2); 590 CloseSuperfluousFds(fd_shuffle2);
588 591
589 for (size_t i = 0; i < argv.size(); i++) 592 for (size_t i = 0; i < argv.size(); i++)
590 argv_cstr[i] = const_cast<char*>(argv[i].c_str()); 593 argv_cstr[i] = const_cast<char*>(argv[i].c_str());
591 argv_cstr[argv.size()] = NULL; 594 argv_cstr[argv.size()] = NULL;
592 execvp(argv_cstr[0], argv_cstr.get()); 595 execvp(argv_cstr[0], argv_cstr.get());
593 RAW_LOG(ERROR, "LaunchApp: failed to execvp:"); 596 RAW_LOG(ERROR, "LaunchApp: failed to execvp:");
594 RAW_LOG(ERROR, argv_cstr[0]); 597 RAW_LOG(ERROR, argv_cstr[0]);
595 _exit(127); 598 _exit(127);
596 } else { 599 } else {
597 // Parent process 600 // Parent process
598 if (wait) { 601 if (options.wait) {
599 // While this isn't strictly disk IO, waiting for another process to 602 // While this isn't strictly disk IO, waiting for another process to
600 // finish is the sort of thing ThreadRestrictions is trying to prevent. 603 // finish is the sort of thing ThreadRestrictions is trying to prevent.
601 base::ThreadRestrictions::AssertIOAllowed(); 604 base::ThreadRestrictions::AssertIOAllowed();
602 pid_t ret = HANDLE_EINTR(waitpid(pid, 0, 0)); 605 pid_t ret = HANDLE_EINTR(waitpid(pid, 0, 0));
603 DPCHECK(ret > 0); 606 DPCHECK(ret > 0);
604 } 607 }
605 608
606 if (process_handle) 609 if (options.process_handle)
607 *process_handle = pid; 610 *options.process_handle = pid;
608 } 611 }
609 612
610 return true; 613 return true;
611 } 614 }
612 615
613 bool LaunchApp( 616 bool LaunchProcess(const CommandLine& cmdline,
614 const std::vector<std::string>& argv, 617 const LaunchOptions& options) {
615 const environment_vector& env_changes, 618 return LaunchProcess(cl.argv(), options);
616 const file_handle_mapping_vector& fds_to_remap,
617 bool wait,
618 ProcessHandle* process_handle) {
619 return LaunchAppImpl(argv, env_changes, fds_to_remap,
620 wait, process_handle, false);
621 }
622
623 bool LaunchAppInNewProcessGroup(
624 const std::vector<std::string>& argv,
625 const environment_vector& env_changes,
626 const file_handle_mapping_vector& fds_to_remap,
627 bool wait,
628 ProcessHandle* process_handle) {
629 return LaunchAppImpl(argv, env_changes, fds_to_remap, wait,
630 process_handle, true);
631 }
632
633 bool LaunchApp(const std::vector<std::string>& argv,
634 const file_handle_mapping_vector& fds_to_remap,
635 bool wait, ProcessHandle* process_handle) {
636 base::environment_vector no_env;
637 return LaunchApp(argv, no_env, fds_to_remap, wait, process_handle);
638 }
639
640 bool LaunchApp(const CommandLine& cl,
641 bool wait, bool start_hidden,
642 ProcessHandle* process_handle) {
643 file_handle_mapping_vector no_files;
644 return LaunchApp(cl.argv(), no_files, wait, process_handle);
645 } 619 }
646 620
647 ProcessMetrics::~ProcessMetrics() { } 621 ProcessMetrics::~ProcessMetrics() { }
648 622
649 void EnableTerminationOnHeapCorruption() { 623 void EnableTerminationOnHeapCorruption() {
650 // On POSIX, there nothing to do AFAIK. 624 // On POSIX, there nothing to do AFAIK.
651 } 625 }
652 626
653 bool EnableInProcessStackDumping() { 627 bool EnableInProcessStackDumping() {
654 // When running in an application, our code typically expects SIGPIPE 628 // When running in an application, our code typically expects SIGPIPE
(...skipping 350 matching lines...) Expand 10 before | Expand all | Expand 10 after
1005 const ProcessFilter* filter) { 979 const ProcessFilter* filter) {
1006 bool exited_cleanly = 980 bool exited_cleanly =
1007 WaitForProcessesToExit(executable_name, wait_milliseconds, 981 WaitForProcessesToExit(executable_name, wait_milliseconds,
1008 filter); 982 filter);
1009 if (!exited_cleanly) 983 if (!exited_cleanly)
1010 KillProcesses(executable_name, exit_code, filter); 984 KillProcesses(executable_name, exit_code, filter);
1011 return exited_cleanly; 985 return exited_cleanly;
1012 } 986 }
1013 987
1014 } // namespace base 988 } // namespace base
OLDNEW
« base/process_util.h ('K') | « base/process_util.h ('k') | base/process_util_win.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698