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

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: Remove max_output 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 493 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 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
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]; 608 char buffer[256];
624 size_t output_buf_left = max_output; 609 ssize_t bytes_read = 0;
Lei Zhang 2016/07/04 20:33:04 This can be declared in the while loop now.
benwells 2016/07/05 03:48:38 Done.
625 ssize_t bytes_read = 1; // A lie to properly handle |max_output == 0|
626 // case in the logic below.
627 610
628 while (output_buf_left > 0) { 611 while (true) {
629 bytes_read = HANDLE_EINTR(read(pipe_fd[0], buffer, 612 bytes_read = HANDLE_EINTR(read(pipe_fd[0], buffer, sizeof(buffer)));
630 std::min(output_buf_left, 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 bool success = process.WaitForExit(exit_code);
Lei Zhang 2016/07/04 20:33:04 No need for a success variable. Just return.
benwells 2016/07/05 03:48:38 Done.
642 623
643 // If we stopped because we read as much as we wanted, we return 624 if (success)
644 // GOT_MAX_OUTPUT (because the child may exit due to |SIGPIPE|). 625 return true;
645 if (!output_buf_left && bytes_read > 0) 626 return false;
646 return GOT_MAX_OUTPUT;
647 else if (success)
648 return EXECUTE_SUCCESS;
649 return EXECUTE_FAILURE;
650 } 627 }
651 } 628 }
652 } 629 }
653 630
654 bool GetAppOutput(const CommandLine& cl, std::string* output) { 631 bool GetAppOutput(const CommandLine& cl, std::string* output) {
655 return GetAppOutput(cl.argv(), output); 632 return GetAppOutput(cl.argv(), output);
656 } 633 }
657 634
658 bool GetAppOutput(const std::vector<std::string>& argv, std::string* output) { 635 bool GetAppOutput(const std::vector<std::string>& argv, std::string* output) {
659 // Run |execve()| with the current environment and store "unlimited" data. 636 // Run |execve()| with the current environment and store "unlimited" data.
660 int exit_code; 637 int exit_code;
661 GetAppOutputInternalResult result = GetAppOutputInternal( 638 bool result =
662 argv, NULL, false, output, std::numeric_limits<std::size_t>::max(), true, 639 GetAppOutputInternal(argv, NULL, false, output, true, &exit_code);
Lei Zhang 2016/07/04 20:33:04 Might as well s/NULL/nullptr/ while we are here.
benwells 2016/07/05 03:48:38 Done.
663 &exit_code); 640 return result && exit_code == EXIT_SUCCESS;
664 return result == EXECUTE_SUCCESS && exit_code == EXIT_SUCCESS;
665 } 641 }
666 642
667 bool GetAppOutputAndError(const CommandLine& cl, std::string* output) { 643 bool GetAppOutputAndError(const CommandLine& cl, std::string* output) {
668 // Run |execve()| with the current environment and store "unlimited" data. 644 // Run |execve()| with the current environment and store "unlimited" data.
669 int exit_code; 645 int exit_code;
670 GetAppOutputInternalResult result = GetAppOutputInternal( 646 bool result =
671 cl.argv(), NULL, true, output, std::numeric_limits<std::size_t>::max(), 647 GetAppOutputInternal(cl.argv(), NULL, true, output, true, &exit_code);
672 true, &exit_code); 648 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 } 649 }
688 650
689 bool GetAppOutputWithExitCode(const CommandLine& cl, 651 bool GetAppOutputWithExitCode(const CommandLine& cl,
690 std::string* output, 652 std::string* output,
691 int* exit_code) { 653 int* exit_code) {
692 // Run |execve()| with the current environment and store "unlimited" data. 654 // Run |execve()| with the current environment and store "unlimited" data.
693 GetAppOutputInternalResult result = GetAppOutputInternal( 655 return GetAppOutputInternal(cl.argv(), NULL, false, output, true, exit_code);
694 cl.argv(), NULL, false, output, std::numeric_limits<std::size_t>::max(),
695 true, exit_code);
696 return result == EXECUTE_SUCCESS;
697 } 656 }
698 657
699 #endif // !defined(OS_NACL_NONSFI) 658 #endif // !defined(OS_NACL_NONSFI)
700 659
701 #if defined(OS_LINUX) || defined(OS_NACL_NONSFI) 660 #if defined(OS_LINUX) || defined(OS_NACL_NONSFI)
702 namespace { 661 namespace {
703 662
704 bool IsRunningOnValgrind() { 663 bool IsRunningOnValgrind() {
705 return RUNNING_ON_VALGRIND; 664 return RUNNING_ON_VALGRIND;
706 } 665 }
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after
783 jmp_buf env; 742 jmp_buf env;
784 if (setjmp(env) == 0) { 743 if (setjmp(env) == 0) {
785 return CloneAndLongjmpInChild(flags, ptid, ctid, &env); 744 return CloneAndLongjmpInChild(flags, ptid, ctid, &env);
786 } 745 }
787 746
788 return 0; 747 return 0;
789 } 748 }
790 #endif // defined(OS_LINUX) || defined(OS_NACL_NONSFI) 749 #endif // defined(OS_LINUX) || defined(OS_NACL_NONSFI)
791 750
792 } // namespace base 751 } // 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