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

Side by Side Diff: runtime/bin/process_linux.cc

Issue 2480793002: clang-format runtime/bin (Closed)
Patch Set: Created 4 years, 1 month 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 | « runtime/bin/process_fuchsia.cc ('k') | runtime/bin/process_macos.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 Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 #if !defined(DART_IO_DISABLED) 5 #if !defined(DART_IO_DISABLED)
6 6
7 #include "platform/globals.h" 7 #include "platform/globals.h"
8 #if defined(TARGET_OS_LINUX) 8 #if defined(TARGET_OS_LINUX)
9 9
10 #include "bin/process.h" 10 #include "bin/process.h"
11 11
12 #include <errno.h> // NOLINT 12 #include <errno.h> // NOLINT
13 #include <fcntl.h> // NOLINT 13 #include <fcntl.h> // NOLINT
14 #include <poll.h> // NOLINT 14 #include <poll.h> // NOLINT
15 #include <stdio.h> // NOLINT 15 #include <stdio.h> // NOLINT
16 #include <stdlib.h> // NOLINT 16 #include <stdlib.h> // NOLINT
17 #include <string.h> // NOLINT 17 #include <string.h> // NOLINT
18 #include <sys/wait.h> // NOLINT 18 #include <sys/wait.h> // NOLINT
19 #include <unistd.h> // NOLINT 19 #include <unistd.h> // NOLINT
20 20
21 #include "bin/dartutils.h" 21 #include "bin/dartutils.h"
22 #include "bin/fdutils.h" 22 #include "bin/fdutils.h"
23 #include "bin/lockers.h" 23 #include "bin/lockers.h"
24 #include "bin/log.h" 24 #include "bin/log.h"
25 #include "bin/thread.h" 25 #include "bin/thread.h"
26 26
27 #include "platform/signal_blocker.h" 27 #include "platform/signal_blocker.h"
28 #include "platform/utils.h" 28 #include "platform/utils.h"
29 29
30 extern char **environ; 30 extern char** environ;
31 31
32 namespace dart { 32 namespace dart {
33 namespace bin { 33 namespace bin {
34 34
35 int Process::global_exit_code_ = 0; 35 int Process::global_exit_code_ = 0;
36 Mutex* Process::global_exit_code_mutex_ = new Mutex(); 36 Mutex* Process::global_exit_code_mutex_ = new Mutex();
37 Process::ExitHook Process::exit_hook_ = NULL; 37 Process::ExitHook Process::exit_hook_ = NULL;
38 38
39 // ProcessInfo is used to map a process id to the file descriptor for 39 // ProcessInfo is used to map a process id to the file descriptor for
40 // the pipe used to communicate the exit code of the process to Dart. 40 // the pipe used to communicate the exit code of the process to Dart.
41 // ProcessInfo objects are kept in the static singly-linked 41 // ProcessInfo objects are kept in the static singly-linked
42 // ProcessInfoList. 42 // ProcessInfoList.
43 class ProcessInfo { 43 class ProcessInfo {
44 public: 44 public:
45 ProcessInfo(pid_t pid, intptr_t fd) : pid_(pid), fd_(fd) { } 45 ProcessInfo(pid_t pid, intptr_t fd) : pid_(pid), fd_(fd) {}
46 ~ProcessInfo() { 46 ~ProcessInfo() {
47 int closed = TEMP_FAILURE_RETRY(close(fd_)); 47 int closed = TEMP_FAILURE_RETRY(close(fd_));
48 if (closed != 0) { 48 if (closed != 0) {
49 FATAL("Failed to close process exit code pipe"); 49 FATAL("Failed to close process exit code pipe");
50 } 50 }
51 } 51 }
52 pid_t pid() { return pid_; } 52 pid_t pid() { return pid_; }
53 intptr_t fd() { return fd_; } 53 intptr_t fd() { return fd_; }
54 ProcessInfo* next() { return next_; } 54 ProcessInfo* next() { return next_; }
55 void set_next(ProcessInfo* info) { next_ = info; } 55 void set_next(ProcessInfo* info) { next_ = info; }
(...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after
199 int negative = 0; 199 int negative = 0;
200 if (WIFEXITED(status)) { 200 if (WIFEXITED(status)) {
201 exit_code = WEXITSTATUS(status); 201 exit_code = WEXITSTATUS(status);
202 } 202 }
203 if (WIFSIGNALED(status)) { 203 if (WIFSIGNALED(status)) {
204 exit_code = WTERMSIG(status); 204 exit_code = WTERMSIG(status);
205 negative = 1; 205 negative = 1;
206 } 206 }
207 intptr_t exit_code_fd = ProcessInfoList::LookupProcessExitFd(pid); 207 intptr_t exit_code_fd = ProcessInfoList::LookupProcessExitFd(pid);
208 if (exit_code_fd != 0) { 208 if (exit_code_fd != 0) {
209 int message[2] = { exit_code, negative }; 209 int message[2] = {exit_code, negative};
210 ssize_t result = 210 ssize_t result =
211 FDUtils::WriteToBlocking(exit_code_fd, &message, sizeof(message)); 211 FDUtils::WriteToBlocking(exit_code_fd, &message, sizeof(message));
212 // If the process has been closed, the read end of the exit 212 // If the process has been closed, the read end of the exit
213 // pipe has been closed. It is therefore not a problem that 213 // pipe has been closed. It is therefore not a problem that
214 // write fails with a broken pipe error. Other errors should 214 // write fails with a broken pipe error. Other errors should
215 // not happen. 215 // not happen.
216 if ((result != -1) && (result != sizeof(message))) { 216 if ((result != -1) && (result != sizeof(message))) {
217 FATAL("Failed to write entire process exit message"); 217 FATAL("Failed to write entire process exit message");
218 } else if ((result == -1) && (errno != EPIPE)) { 218 } else if ((result == -1) && (errno != EPIPE)) {
219 FATAL1("Failed to write exit code: %d", errno); 219 FATAL1("Failed to write exit code: %d", errno);
(...skipping 319 matching lines...) Expand 10 before | Expand all | Expand 10 after
539 return 0; 539 return 0;
540 } 540 }
541 541
542 542
543 int ReadExecResult() { 543 int ReadExecResult() {
544 int child_errno; 544 int child_errno;
545 int bytes_read = -1; 545 int bytes_read = -1;
546 // Read exec result from child. If no data is returned the exec was 546 // Read exec result from child. If no data is returned the exec was
547 // successful and the exec call closed the pipe. Otherwise the errno 547 // successful and the exec call closed the pipe. Otherwise the errno
548 // is written to the pipe. 548 // is written to the pipe.
549 bytes_read = FDUtils::ReadFromBlocking( 549 bytes_read = FDUtils::ReadFromBlocking(exec_control_[0], &child_errno,
550 exec_control_[0], &child_errno, sizeof(child_errno)); 550 sizeof(child_errno));
551 if (bytes_read == sizeof(child_errno)) { 551 if (bytes_read == sizeof(child_errno)) {
552 ReadChildError(); 552 ReadChildError();
553 return child_errno; 553 return child_errno;
554 } else if (bytes_read == -1) { 554 } else if (bytes_read == -1) {
555 return errno; 555 return errno;
556 } 556 }
557 return 0; 557 return 0;
558 } 558 }
559 559
560 560
561 int ReadDetachedExecResult(pid_t *pid) { 561 int ReadDetachedExecResult(pid_t* pid) {
562 int child_errno; 562 int child_errno;
563 int bytes_read = -1; 563 int bytes_read = -1;
564 // Read exec result from child. If only pid data is returned the exec was 564 // Read exec result from child. If only pid data is returned the exec was
565 // successful and the exec call closed the pipe. Otherwise the errno 565 // successful and the exec call closed the pipe. Otherwise the errno
566 // is written to the pipe as well. 566 // is written to the pipe as well.
567 int result[2]; 567 int result[2];
568 bytes_read = 568 bytes_read =
569 FDUtils::ReadFromBlocking(exec_control_[0], result, sizeof(result)); 569 FDUtils::ReadFromBlocking(exec_control_[0], result, sizeof(result));
570 if (bytes_read == sizeof(int)) { 570 if (bytes_read == sizeof(int)) {
571 *pid = result[0]; 571 *pid = result[0];
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
614 614
615 void SetupDetachedWithStdio() { 615 void SetupDetachedWithStdio() {
616 // Close all open file descriptors except for 616 // Close all open file descriptors except for
617 // exec_control_[1], write_out_[0], read_in_[1] and 617 // exec_control_[1], write_out_[0], read_in_[1] and
618 // read_err_[1]. 618 // read_err_[1].
619 int max_fds = sysconf(_SC_OPEN_MAX); 619 int max_fds = sysconf(_SC_OPEN_MAX);
620 if (max_fds == -1) { 620 if (max_fds == -1) {
621 max_fds = _POSIX_OPEN_MAX; 621 max_fds = _POSIX_OPEN_MAX;
622 } 622 }
623 for (int fd = 0; fd < max_fds; fd++) { 623 for (int fd = 0; fd < max_fds; fd++) {
624 if ((fd != exec_control_[1]) && 624 if ((fd != exec_control_[1]) && (fd != write_out_[0]) &&
625 (fd != write_out_[0]) && 625 (fd != read_in_[1]) && (fd != read_err_[1])) {
626 (fd != read_in_[1]) &&
627 (fd != read_err_[1])) {
628 VOID_TEMP_FAILURE_RETRY(close(fd)); 626 VOID_TEMP_FAILURE_RETRY(close(fd));
629 } 627 }
630 } 628 }
631 629
632 if (TEMP_FAILURE_RETRY(dup2(write_out_[0], STDIN_FILENO)) == -1) { 630 if (TEMP_FAILURE_RETRY(dup2(write_out_[0], STDIN_FILENO)) == -1) {
633 ReportChildError(); 631 ReportChildError();
634 } 632 }
635 VOID_TEMP_FAILURE_RETRY(close(write_out_[0])); 633 VOID_TEMP_FAILURE_RETRY(close(write_out_[0]));
636 634
637 if (TEMP_FAILURE_RETRY(dup2(read_in_[1], STDOUT_FILENO)) == -1) { 635 if (TEMP_FAILURE_RETRY(dup2(read_in_[1], STDOUT_FILENO)) == -1) {
(...skipping 29 matching lines...) Expand all
667 } 665 }
668 666
669 667
670 void ReportChildError() { 668 void ReportChildError() {
671 // In the case of failure in the child process write the errno and 669 // In the case of failure in the child process write the errno and
672 // the OS error message to the exec control pipe and exit. 670 // the OS error message to the exec control pipe and exit.
673 int child_errno = errno; 671 int child_errno = errno;
674 const int kBufferSize = 1024; 672 const int kBufferSize = 1024;
675 char error_buf[kBufferSize]; 673 char error_buf[kBufferSize];
676 char* os_error_message = Utils::StrError(errno, error_buf, kBufferSize); 674 char* os_error_message = Utils::StrError(errno, error_buf, kBufferSize);
677 int bytes_written = FDUtils::WriteToBlocking( 675 int bytes_written = FDUtils::WriteToBlocking(exec_control_[1], &child_errno,
678 exec_control_[1], &child_errno, sizeof(child_errno)); 676 sizeof(child_errno));
679 if (bytes_written == sizeof(child_errno)) { 677 if (bytes_written == sizeof(child_errno)) {
680 FDUtils::WriteToBlocking( 678 FDUtils::WriteToBlocking(exec_control_[1], os_error_message,
681 exec_control_[1], os_error_message, strlen(os_error_message) + 1); 679 strlen(os_error_message) + 1);
682 } 680 }
683 VOID_TEMP_FAILURE_RETRY(close(exec_control_[1])); 681 VOID_TEMP_FAILURE_RETRY(close(exec_control_[1]));
684 exit(1); 682 exit(1);
685 } 683 }
686 684
687 685
688 void ReportPid(int pid) { 686 void ReportPid(int pid) {
689 // In the case of starting a detached process the actual pid of that process 687 // In the case of starting a detached process the actual pid of that process
690 // is communicated using the exec control pipe. 688 // is communicated using the exec control pipe.
691 int bytes_written = 689 int bytes_written =
(...skipping 28 matching lines...) Expand all
720 718
721 719
722 void CloseAllPipes() { 720 void CloseAllPipes() {
723 ClosePipe(exec_control_); 721 ClosePipe(exec_control_);
724 ClosePipe(read_in_); 722 ClosePipe(read_in_);
725 ClosePipe(read_err_); 723 ClosePipe(read_err_);
726 ClosePipe(write_out_); 724 ClosePipe(write_out_);
727 } 725 }
728 726
729 727
730 int read_in_[2]; // Pipe for stdout to child process. 728 int read_in_[2]; // Pipe for stdout to child process.
731 int read_err_[2]; // Pipe for stderr to child process. 729 int read_err_[2]; // Pipe for stderr to child process.
732 int write_out_[2]; // Pipe for stdin to child process. 730 int write_out_[2]; // Pipe for stdin to child process.
733 int exec_control_[2]; // Pipe to get the result from exec. 731 int exec_control_[2]; // Pipe to get the result from exec.
734 732
735 char** program_arguments_; 733 char** program_arguments_;
736 char** program_environment_; 734 char** program_environment_;
737 735
738 const char* path_; 736 const char* path_;
739 const char* working_directory_; 737 const char* working_directory_;
740 ProcessStartMode mode_; 738 ProcessStartMode mode_;
741 intptr_t* in_; 739 intptr_t* in_;
742 intptr_t* out_; 740 intptr_t* out_;
(...skipping 13 matching lines...) Expand all
756 const char* working_directory, 754 const char* working_directory,
757 char* environment[], 755 char* environment[],
758 intptr_t environment_length, 756 intptr_t environment_length,
759 ProcessStartMode mode, 757 ProcessStartMode mode,
760 intptr_t* in, 758 intptr_t* in,
761 intptr_t* out, 759 intptr_t* out,
762 intptr_t* err, 760 intptr_t* err,
763 intptr_t* id, 761 intptr_t* id,
764 intptr_t* exit_event, 762 intptr_t* exit_event,
765 char** os_error_message) { 763 char** os_error_message) {
766 ProcessStarter starter(path, 764 ProcessStarter starter(path, arguments, arguments_length, working_directory,
767 arguments, 765 environment, environment_length, mode, in, out, err,
768 arguments_length, 766 id, exit_event, os_error_message);
769 working_directory,
770 environment,
771 environment_length,
772 mode,
773 in,
774 out,
775 err,
776 id,
777 exit_event,
778 os_error_message);
779 return starter.Start(); 767 return starter.Start();
780 } 768 }
781 769
782 770
783 class BufferList: public BufferListBase { 771 class BufferList : public BufferListBase {
784 public: 772 public:
785 BufferList() {} 773 BufferList() {}
786 774
787 bool Read(int fd, intptr_t available) { 775 bool Read(int fd, intptr_t available) {
788 // Read all available bytes. 776 // Read all available bytes.
789 while (available > 0) { 777 while (available > 0) {
790 if (free_size_ == 0) { 778 if (free_size_ == 0) {
791 Allocate(); 779 Allocate();
792 } 780 }
793 ASSERT(free_size_ > 0); 781 ASSERT(free_size_ > 0);
794 ASSERT(free_size_ <= kBufferSize); 782 ASSERT(free_size_ <= kBufferSize);
795 intptr_t block_size = dart::Utils::Minimum(free_size_, available); 783 intptr_t block_size = dart::Utils::Minimum(free_size_, available);
796 intptr_t bytes = TEMP_FAILURE_RETRY(read( 784 intptr_t bytes = TEMP_FAILURE_RETRY(
797 fd, 785 read(fd, reinterpret_cast<void*>(FreeSpaceAddress()), block_size));
798 reinterpret_cast<void*>(FreeSpaceAddress()),
799 block_size));
800 if (bytes < 0) { 786 if (bytes < 0) {
801 return false; 787 return false;
802 } 788 }
803 data_size_ += bytes; 789 data_size_ += bytes;
804 free_size_ -= bytes; 790 free_size_ -= bytes;
805 available -= bytes; 791 available -= bytes;
806 } 792 }
807 return true; 793 return true;
808 } 794 }
809 795
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
865 if (fds[i].fd == out) { 851 if (fds[i].fd == out) {
866 if (!out_data.Read(out, avail)) { 852 if (!out_data.Read(out, avail)) {
867 return CloseProcessBuffers(fds); 853 return CloseProcessBuffers(fds);
868 } 854 }
869 } else if (fds[i].fd == err) { 855 } else if (fds[i].fd == err) {
870 if (!err_data.Read(err, avail)) { 856 if (!err_data.Read(err, avail)) {
871 return CloseProcessBuffers(fds); 857 return CloseProcessBuffers(fds);
872 } 858 }
873 } else if (fds[i].fd == exit_event) { 859 } else if (fds[i].fd == exit_event) {
874 if (avail == 8) { 860 if (avail == 8) {
875 intptr_t b = TEMP_FAILURE_RETRY(read(exit_event, 861 intptr_t b =
876 exit_code_data.bytes, 8)); 862 TEMP_FAILURE_RETRY(read(exit_event, exit_code_data.bytes, 8));
877 if (b != 8) { 863 if (b != 8) {
878 return CloseProcessBuffers(fds); 864 return CloseProcessBuffers(fds);
879 } 865 }
880 } 866 }
881 } else { 867 } else {
882 UNREACHABLE(); 868 UNREACHABLE();
883 } 869 }
884 } 870 }
885 if ((fds[i].revents & POLLHUP) != 0) { 871 if ((fds[i].revents & POLLHUP) != 0) {
886 VOID_TEMP_FAILURE_RETRY(close(fds[i].fd)); 872 VOID_TEMP_FAILURE_RETRY(close(fds[i].fd));
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
920 906
921 intptr_t Process::CurrentProcessId() { 907 intptr_t Process::CurrentProcessId() {
922 return static_cast<intptr_t>(getpid()); 908 return static_cast<intptr_t>(getpid());
923 } 909 }
924 910
925 911
926 static Mutex* signal_mutex = new Mutex(); 912 static Mutex* signal_mutex = new Mutex();
927 static SignalInfo* signal_handlers = NULL; 913 static SignalInfo* signal_handlers = NULL;
928 static const int kSignalsCount = 7; 914 static const int kSignalsCount = 7;
929 static const int kSignals[kSignalsCount] = { 915 static const int kSignals[kSignalsCount] = {
930 SIGHUP, 916 SIGHUP, SIGINT, SIGTERM, SIGUSR1, SIGUSR2, SIGWINCH,
931 SIGINT, 917 SIGQUIT // Allow VMService to listen on SIGQUIT.
932 SIGTERM,
933 SIGUSR1,
934 SIGUSR2,
935 SIGWINCH,
936 SIGQUIT // Allow VMService to listen on SIGQUIT.
937 }; 918 };
938 919
939 920
940 SignalInfo::~SignalInfo() { 921 SignalInfo::~SignalInfo() {
941 VOID_TEMP_FAILURE_RETRY(close(fd_)); 922 VOID_TEMP_FAILURE_RETRY(close(fd_));
942 } 923 }
943 924
944 925
945 static void SignalHandler(int signal) { 926 static void SignalHandler(int signal) {
946 MutexLocker lock(signal_mutex); 927 MutexLocker lock(signal_mutex);
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after
1034 sigaction(signal, &act, NULL); 1015 sigaction(signal, &act, NULL);
1035 } 1016 }
1036 } 1017 }
1037 1018
1038 } // namespace bin 1019 } // namespace bin
1039 } // namespace dart 1020 } // namespace dart
1040 1021
1041 #endif // defined(TARGET_OS_LINUX) 1022 #endif // defined(TARGET_OS_LINUX)
1042 1023
1043 #endif // !defined(DART_IO_DISABLED) 1024 #endif // !defined(DART_IO_DISABLED)
OLDNEW
« no previous file with comments | « runtime/bin/process_fuchsia.cc ('k') | runtime/bin/process_macos.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698