OLD | NEW |
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_MACOS) | 8 #if defined(TARGET_OS_MACOS) |
9 | 9 |
10 #include "bin/process.h" | 10 #include "bin/process.h" |
11 | 11 |
12 #if !TARGET_OS_IOS | 12 #if !TARGET_OS_IOS |
13 #include <crt_externs.h> // NOLINT | 13 #include <crt_externs.h> // NOLINT |
14 #endif | 14 #endif |
15 #include <errno.h> // NOLINT | 15 #include <errno.h> // NOLINT |
16 #include <fcntl.h> // NOLINT | 16 #include <fcntl.h> // NOLINT |
17 #include <poll.h> // NOLINT | 17 #include <poll.h> // NOLINT |
18 #include <signal.h> // NOLINT | 18 #include <signal.h> // NOLINT |
19 #include <stdio.h> // NOLINT | 19 #include <stdio.h> // NOLINT |
20 #include <stdlib.h> // NOLINT | 20 #include <stdlib.h> // NOLINT |
21 #include <string.h> // NOLINT | 21 #include <string.h> // NOLINT |
22 #include <unistd.h> // NOLINT | 22 #include <unistd.h> // NOLINT |
23 | 23 |
24 #include "bin/dartutils.h" | 24 #include "bin/dartutils.h" |
25 #include "bin/fdutils.h" | 25 #include "bin/fdutils.h" |
26 #include "bin/lockers.h" | 26 #include "bin/lockers.h" |
27 #include "bin/log.h" | 27 #include "bin/log.h" |
28 #include "bin/thread.h" | 28 #include "bin/thread.h" |
29 | 29 |
30 #include "platform/signal_blocker.h" | 30 #include "platform/signal_blocker.h" |
31 #include "platform/utils.h" | 31 #include "platform/utils.h" |
32 | 32 |
33 namespace dart { | 33 namespace dart { |
34 namespace bin { | 34 namespace bin { |
35 | 35 |
36 int Process::global_exit_code_ = 0; | 36 int Process::global_exit_code_ = 0; |
37 Mutex* Process::global_exit_code_mutex_ = new Mutex(); | 37 Mutex* Process::global_exit_code_mutex_ = new Mutex(); |
38 Process::ExitHook Process::exit_hook_ = NULL; | 38 Process::ExitHook Process::exit_hook_ = NULL; |
39 | 39 |
40 // ProcessInfo is used to map a process id to the file descriptor for | 40 // ProcessInfo is used to map a process id to the file descriptor for |
41 // the pipe used to communicate the exit code of the process to Dart. | 41 // the pipe used to communicate the exit code of the process to Dart. |
42 // ProcessInfo objects are kept in the static singly-linked | 42 // ProcessInfo objects are kept in the static singly-linked |
43 // ProcessInfoList. | 43 // ProcessInfoList. |
44 class ProcessInfo { | 44 class ProcessInfo { |
45 public: | 45 public: |
46 ProcessInfo(pid_t pid, intptr_t fd) : pid_(pid), fd_(fd) { } | 46 ProcessInfo(pid_t pid, intptr_t fd) : pid_(pid), fd_(fd) {} |
47 ~ProcessInfo() { | 47 ~ProcessInfo() { |
48 int closed = TEMP_FAILURE_RETRY(close(fd_)); | 48 int closed = TEMP_FAILURE_RETRY(close(fd_)); |
49 if (closed != 0) { | 49 if (closed != 0) { |
50 FATAL("Failed to close process exit code pipe"); | 50 FATAL("Failed to close process exit code pipe"); |
51 } | 51 } |
52 } | 52 } |
53 pid_t pid() { return pid_; } | 53 pid_t pid() { return pid_; } |
54 intptr_t fd() { return fd_; } | 54 intptr_t fd() { return fd_; } |
55 ProcessInfo* next() { return next_; } | 55 ProcessInfo* next() { return next_; } |
56 void set_next(ProcessInfo* info) { next_ = info; } | 56 void set_next(ProcessInfo* info) { next_ = info; } |
(...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
200 int negative = 0; | 200 int negative = 0; |
201 if (WIFEXITED(status)) { | 201 if (WIFEXITED(status)) { |
202 exit_code = WEXITSTATUS(status); | 202 exit_code = WEXITSTATUS(status); |
203 } | 203 } |
204 if (WIFSIGNALED(status)) { | 204 if (WIFSIGNALED(status)) { |
205 exit_code = WTERMSIG(status); | 205 exit_code = WTERMSIG(status); |
206 negative = 1; | 206 negative = 1; |
207 } | 207 } |
208 intptr_t exit_code_fd = ProcessInfoList::LookupProcessExitFd(pid); | 208 intptr_t exit_code_fd = ProcessInfoList::LookupProcessExitFd(pid); |
209 if (exit_code_fd != 0) { | 209 if (exit_code_fd != 0) { |
210 int message[2] = { exit_code, negative }; | 210 int message[2] = {exit_code, negative}; |
211 ssize_t result = | 211 ssize_t result = |
212 FDUtils::WriteToBlocking(exit_code_fd, &message, sizeof(message)); | 212 FDUtils::WriteToBlocking(exit_code_fd, &message, sizeof(message)); |
213 // If the process has been closed, the read end of the exit | 213 // If the process has been closed, the read end of the exit |
214 // pipe has been closed. It is therefore not a problem that | 214 // pipe has been closed. It is therefore not a problem that |
215 // write fails with a broken pipe error. Other errors should | 215 // write fails with a broken pipe error. Other errors should |
216 // not happen. | 216 // not happen. |
217 if ((result != -1) && (result != sizeof(message))) { | 217 if ((result != -1) && (result != sizeof(message))) { |
218 FATAL("Failed to write entire process exit message"); | 218 FATAL("Failed to write entire process exit message"); |
219 } else if ((result == -1) && (errno != EPIPE)) { | 219 } else if ((result == -1) && (errno != EPIPE)) { |
220 FATAL1("Failed to write exit code: %d", errno); | 220 FATAL1("Failed to write exit code: %d", errno); |
(...skipping 334 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
555 return 0; | 555 return 0; |
556 } | 556 } |
557 | 557 |
558 | 558 |
559 int ReadExecResult() { | 559 int ReadExecResult() { |
560 int child_errno; | 560 int child_errno; |
561 int bytes_read = -1; | 561 int bytes_read = -1; |
562 // Read exec result from child. If no data is returned the exec was | 562 // Read exec result from child. If no data is returned the exec was |
563 // successful and the exec call closed the pipe. Otherwise the errno | 563 // successful and the exec call closed the pipe. Otherwise the errno |
564 // is written to the pipe. | 564 // is written to the pipe. |
565 bytes_read = FDUtils::ReadFromBlocking( | 565 bytes_read = FDUtils::ReadFromBlocking(exec_control_[0], &child_errno, |
566 exec_control_[0], &child_errno, sizeof(child_errno)); | 566 sizeof(child_errno)); |
567 if (bytes_read == sizeof(child_errno)) { | 567 if (bytes_read == sizeof(child_errno)) { |
568 ReadChildError(); | 568 ReadChildError(); |
569 return child_errno; | 569 return child_errno; |
570 } else if (bytes_read == -1) { | 570 } else if (bytes_read == -1) { |
571 return errno; | 571 return errno; |
572 } | 572 } |
573 return 0; | 573 return 0; |
574 } | 574 } |
575 | 575 |
576 | 576 |
577 int ReadDetachedExecResult(pid_t *pid) { | 577 int ReadDetachedExecResult(pid_t* pid) { |
578 int child_errno; | 578 int child_errno; |
579 int bytes_read = -1; | 579 int bytes_read = -1; |
580 // Read exec result from child. If only pid data is returned the exec was | 580 // Read exec result from child. If only pid data is returned the exec was |
581 // successful and the exec call closed the pipe. Otherwise the errno | 581 // successful and the exec call closed the pipe. Otherwise the errno |
582 // is written to the pipe as well. | 582 // is written to the pipe as well. |
583 int result[2]; | 583 int result[2]; |
584 bytes_read = | 584 bytes_read = |
585 FDUtils::ReadFromBlocking(exec_control_[0], result, sizeof(result)); | 585 FDUtils::ReadFromBlocking(exec_control_[0], result, sizeof(result)); |
586 if (bytes_read == sizeof(int)) { | 586 if (bytes_read == sizeof(int)) { |
587 *pid = result[0]; | 587 *pid = result[0]; |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
630 | 630 |
631 void SetupDetachedWithStdio() { | 631 void SetupDetachedWithStdio() { |
632 // Close all open file descriptors except for | 632 // Close all open file descriptors except for |
633 // exec_control_[1], write_out_[0], read_in_[1] and | 633 // exec_control_[1], write_out_[0], read_in_[1] and |
634 // read_err_[1]. | 634 // read_err_[1]. |
635 int max_fds = sysconf(_SC_OPEN_MAX); | 635 int max_fds = sysconf(_SC_OPEN_MAX); |
636 if (max_fds == -1) { | 636 if (max_fds == -1) { |
637 max_fds = _POSIX_OPEN_MAX; | 637 max_fds = _POSIX_OPEN_MAX; |
638 } | 638 } |
639 for (int fd = 0; fd < max_fds; fd++) { | 639 for (int fd = 0; fd < max_fds; fd++) { |
640 if ((fd != exec_control_[1]) && | 640 if ((fd != exec_control_[1]) && (fd != write_out_[0]) && |
641 (fd != write_out_[0]) && | 641 (fd != read_in_[1]) && (fd != read_err_[1])) { |
642 (fd != read_in_[1]) && | |
643 (fd != read_err_[1])) { | |
644 VOID_TEMP_FAILURE_RETRY(close(fd)); | 642 VOID_TEMP_FAILURE_RETRY(close(fd)); |
645 } | 643 } |
646 } | 644 } |
647 | 645 |
648 if (TEMP_FAILURE_RETRY(dup2(write_out_[0], STDIN_FILENO)) == -1) { | 646 if (TEMP_FAILURE_RETRY(dup2(write_out_[0], STDIN_FILENO)) == -1) { |
649 ReportChildError(); | 647 ReportChildError(); |
650 } | 648 } |
651 VOID_TEMP_FAILURE_RETRY(close(write_out_[0])); | 649 VOID_TEMP_FAILURE_RETRY(close(write_out_[0])); |
652 | 650 |
653 if (TEMP_FAILURE_RETRY(dup2(read_in_[1], STDOUT_FILENO)) == -1) { | 651 if (TEMP_FAILURE_RETRY(dup2(read_in_[1], STDOUT_FILENO)) == -1) { |
(...skipping 29 matching lines...) Expand all Loading... |
683 } | 681 } |
684 | 682 |
685 | 683 |
686 void ReportChildError() { | 684 void ReportChildError() { |
687 // In the case of failure in the child process write the errno and | 685 // In the case of failure in the child process write the errno and |
688 // the OS error message to the exec control pipe and exit. | 686 // the OS error message to the exec control pipe and exit. |
689 int child_errno = errno; | 687 int child_errno = errno; |
690 const int kBufferSize = 1024; | 688 const int kBufferSize = 1024; |
691 char os_error_message[kBufferSize]; | 689 char os_error_message[kBufferSize]; |
692 Utils::StrError(errno, os_error_message, kBufferSize); | 690 Utils::StrError(errno, os_error_message, kBufferSize); |
693 int bytes_written = FDUtils::WriteToBlocking( | 691 int bytes_written = FDUtils::WriteToBlocking(exec_control_[1], &child_errno, |
694 exec_control_[1], &child_errno, sizeof(child_errno)); | 692 sizeof(child_errno)); |
695 if (bytes_written == sizeof(child_errno)) { | 693 if (bytes_written == sizeof(child_errno)) { |
696 FDUtils::WriteToBlocking( | 694 FDUtils::WriteToBlocking(exec_control_[1], os_error_message, |
697 exec_control_[1], os_error_message, strlen(os_error_message) + 1); | 695 strlen(os_error_message) + 1); |
698 } | 696 } |
699 VOID_TEMP_FAILURE_RETRY(close(exec_control_[1])); | 697 VOID_TEMP_FAILURE_RETRY(close(exec_control_[1])); |
700 exit(1); | 698 exit(1); |
701 } | 699 } |
702 | 700 |
703 | 701 |
704 void ReportPid(int pid) { | 702 void ReportPid(int pid) { |
705 // In the case of starting a detached process the actual pid of that process | 703 // In the case of starting a detached process the actual pid of that process |
706 // is communicated using the exec control pipe. | 704 // is communicated using the exec control pipe. |
707 int bytes_written = | 705 int bytes_written = |
(...skipping 28 matching lines...) Expand all Loading... |
736 | 734 |
737 | 735 |
738 void CloseAllPipes() { | 736 void CloseAllPipes() { |
739 ClosePipe(exec_control_); | 737 ClosePipe(exec_control_); |
740 ClosePipe(read_in_); | 738 ClosePipe(read_in_); |
741 ClosePipe(read_err_); | 739 ClosePipe(read_err_); |
742 ClosePipe(write_out_); | 740 ClosePipe(write_out_); |
743 } | 741 } |
744 | 742 |
745 | 743 |
746 int read_in_[2]; // Pipe for stdout to child process. | 744 int read_in_[2]; // Pipe for stdout to child process. |
747 int read_err_[2]; // Pipe for stderr to child process. | 745 int read_err_[2]; // Pipe for stderr to child process. |
748 int write_out_[2]; // Pipe for stdin to child process. | 746 int write_out_[2]; // Pipe for stdin to child process. |
749 int exec_control_[2]; // Pipe to get the result from exec. | 747 int exec_control_[2]; // Pipe to get the result from exec. |
750 | 748 |
751 char** program_arguments_; | 749 char** program_arguments_; |
752 char** program_environment_; | 750 char** program_environment_; |
753 | 751 |
754 const char* path_; | 752 const char* path_; |
755 const char* working_directory_; | 753 const char* working_directory_; |
756 ProcessStartMode mode_; | 754 ProcessStartMode mode_; |
757 intptr_t* in_; | 755 intptr_t* in_; |
758 intptr_t* out_; | 756 intptr_t* out_; |
(...skipping 13 matching lines...) Expand all Loading... |
772 const char* working_directory, | 770 const char* working_directory, |
773 char* environment[], | 771 char* environment[], |
774 intptr_t environment_length, | 772 intptr_t environment_length, |
775 ProcessStartMode mode, | 773 ProcessStartMode mode, |
776 intptr_t* in, | 774 intptr_t* in, |
777 intptr_t* out, | 775 intptr_t* out, |
778 intptr_t* err, | 776 intptr_t* err, |
779 intptr_t* id, | 777 intptr_t* id, |
780 intptr_t* exit_event, | 778 intptr_t* exit_event, |
781 char** os_error_message) { | 779 char** os_error_message) { |
782 ProcessStarter starter(path, | 780 ProcessStarter starter(path, arguments, arguments_length, working_directory, |
783 arguments, | 781 environment, environment_length, mode, in, out, err, |
784 arguments_length, | 782 id, exit_event, os_error_message); |
785 working_directory, | |
786 environment, | |
787 environment_length, | |
788 mode, | |
789 in, | |
790 out, | |
791 err, | |
792 id, | |
793 exit_event, | |
794 os_error_message); | |
795 return starter.Start(); | 783 return starter.Start(); |
796 } | 784 } |
797 | 785 |
798 | 786 |
799 class BufferList: public BufferListBase { | 787 class BufferList : public BufferListBase { |
800 public: | 788 public: |
801 BufferList() {} | 789 BufferList() {} |
802 | 790 |
803 bool Read(int fd, intptr_t available) { | 791 bool Read(int fd, intptr_t available) { |
804 // Read all available bytes. | 792 // Read all available bytes. |
805 while (available > 0) { | 793 while (available > 0) { |
806 if (free_size_ == 0) { | 794 if (free_size_ == 0) { |
807 Allocate(); | 795 Allocate(); |
808 } | 796 } |
809 ASSERT(free_size_ > 0); | 797 ASSERT(free_size_ > 0); |
810 ASSERT(free_size_ <= kBufferSize); | 798 ASSERT(free_size_ <= kBufferSize); |
811 size_t block_size = dart::Utils::Minimum(free_size_, available); | 799 size_t block_size = dart::Utils::Minimum(free_size_, available); |
812 ssize_t bytes = TEMP_FAILURE_RETRY(read( | 800 ssize_t bytes = TEMP_FAILURE_RETRY( |
813 fd, | 801 read(fd, reinterpret_cast<void*>(FreeSpaceAddress()), block_size)); |
814 reinterpret_cast<void*>(FreeSpaceAddress()), | |
815 block_size)); | |
816 if (bytes < 0) { | 802 if (bytes < 0) { |
817 return false; | 803 return false; |
818 } | 804 } |
819 data_size_ += bytes; | 805 data_size_ += bytes; |
820 free_size_ -= bytes; | 806 free_size_ -= bytes; |
821 available -= bytes; | 807 available -= bytes; |
822 } | 808 } |
823 return true; | 809 return true; |
824 } | 810 } |
825 | 811 |
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
885 if (fds[i].fd == out) { | 871 if (fds[i].fd == out) { |
886 if (!out_data.Read(out, avail)) { | 872 if (!out_data.Read(out, avail)) { |
887 return CloseProcessBuffers(fds); | 873 return CloseProcessBuffers(fds); |
888 } | 874 } |
889 } else if (fds[i].fd == err) { | 875 } else if (fds[i].fd == err) { |
890 if (!err_data.Read(err, avail)) { | 876 if (!err_data.Read(err, avail)) { |
891 return CloseProcessBuffers(fds); | 877 return CloseProcessBuffers(fds); |
892 } | 878 } |
893 } else if (fds[i].fd == exit_event) { | 879 } else if (fds[i].fd == exit_event) { |
894 if (avail == 8) { | 880 if (avail == 8) { |
895 intptr_t b = TEMP_FAILURE_RETRY(read(fds[i].fd, | 881 intptr_t b = |
896 exit_code_data.bytes, 8)); | 882 TEMP_FAILURE_RETRY(read(fds[i].fd, exit_code_data.bytes, 8)); |
897 if (b != 8) { | 883 if (b != 8) { |
898 return CloseProcessBuffers(fds); | 884 return CloseProcessBuffers(fds); |
899 } | 885 } |
900 } | 886 } |
901 } else { | 887 } else { |
902 UNREACHABLE(); | 888 UNREACHABLE(); |
903 } | 889 } |
904 } | 890 } |
905 } | 891 } |
906 if (((fds[i].revents & POLLHUP) != 0) || | 892 if (((fds[i].revents & POLLHUP) != 0) || |
(...skipping 18 matching lines...) Expand all Loading... |
925 exit_code = -exit_code; | 911 exit_code = -exit_code; |
926 } | 912 } |
927 result->set_exit_code(exit_code); | 913 result->set_exit_code(exit_code); |
928 | 914 |
929 return true; | 915 return true; |
930 } | 916 } |
931 | 917 |
932 | 918 |
933 static int SignalMap(intptr_t id) { | 919 static int SignalMap(intptr_t id) { |
934 switch (static_cast<ProcessSignals>(id)) { | 920 switch (static_cast<ProcessSignals>(id)) { |
935 case kSighup: return SIGHUP; | 921 case kSighup: |
936 case kSigint: return SIGINT; | 922 return SIGHUP; |
937 case kSigquit: return SIGQUIT; | 923 case kSigint: |
938 case kSigill: return SIGILL; | 924 return SIGINT; |
939 case kSigtrap: return SIGTRAP; | 925 case kSigquit: |
940 case kSigabrt: return SIGABRT; | 926 return SIGQUIT; |
941 case kSigbus: return SIGBUS; | 927 case kSigill: |
942 case kSigfpe: return SIGFPE; | 928 return SIGILL; |
943 case kSigkill: return SIGKILL; | 929 case kSigtrap: |
944 case kSigusr1: return SIGUSR1; | 930 return SIGTRAP; |
945 case kSigsegv: return SIGSEGV; | 931 case kSigabrt: |
946 case kSigusr2: return SIGUSR2; | 932 return SIGABRT; |
947 case kSigpipe: return SIGPIPE; | 933 case kSigbus: |
948 case kSigalrm: return SIGALRM; | 934 return SIGBUS; |
949 case kSigterm: return SIGTERM; | 935 case kSigfpe: |
950 case kSigchld: return SIGCHLD; | 936 return SIGFPE; |
951 case kSigcont: return SIGCONT; | 937 case kSigkill: |
952 case kSigstop: return SIGSTOP; | 938 return SIGKILL; |
953 case kSigtstp: return SIGTSTP; | 939 case kSigusr1: |
954 case kSigttin: return SIGTTIN; | 940 return SIGUSR1; |
955 case kSigttou: return SIGTTOU; | 941 case kSigsegv: |
956 case kSigurg: return SIGURG; | 942 return SIGSEGV; |
957 case kSigxcpu: return SIGXCPU; | 943 case kSigusr2: |
958 case kSigxfsz: return SIGXFSZ; | 944 return SIGUSR2; |
959 case kSigvtalrm: return SIGVTALRM; | 945 case kSigpipe: |
960 case kSigprof: return SIGPROF; | 946 return SIGPIPE; |
961 case kSigwinch: return SIGWINCH; | 947 case kSigalrm: |
962 case kSigpoll: return -1; | 948 return SIGALRM; |
963 case kSigsys: return SIGSYS; | 949 case kSigterm: |
| 950 return SIGTERM; |
| 951 case kSigchld: |
| 952 return SIGCHLD; |
| 953 case kSigcont: |
| 954 return SIGCONT; |
| 955 case kSigstop: |
| 956 return SIGSTOP; |
| 957 case kSigtstp: |
| 958 return SIGTSTP; |
| 959 case kSigttin: |
| 960 return SIGTTIN; |
| 961 case kSigttou: |
| 962 return SIGTTOU; |
| 963 case kSigurg: |
| 964 return SIGURG; |
| 965 case kSigxcpu: |
| 966 return SIGXCPU; |
| 967 case kSigxfsz: |
| 968 return SIGXFSZ; |
| 969 case kSigvtalrm: |
| 970 return SIGVTALRM; |
| 971 case kSigprof: |
| 972 return SIGPROF; |
| 973 case kSigwinch: |
| 974 return SIGWINCH; |
| 975 case kSigpoll: |
| 976 return -1; |
| 977 case kSigsys: |
| 978 return SIGSYS; |
964 } | 979 } |
965 return -1; | 980 return -1; |
966 } | 981 } |
967 | 982 |
968 | 983 |
969 bool Process::Kill(intptr_t id, int signal) { | 984 bool Process::Kill(intptr_t id, int signal) { |
970 return (TEMP_FAILURE_RETRY(kill(id, SignalMap(signal))) != -1); | 985 return (TEMP_FAILURE_RETRY(kill(id, SignalMap(signal))) != -1); |
971 } | 986 } |
972 | 987 |
973 | 988 |
974 void Process::TerminateExitCodeHandler() { | 989 void Process::TerminateExitCodeHandler() { |
975 ExitCodeHandler::TerminateExitCodeThread(); | 990 ExitCodeHandler::TerminateExitCodeThread(); |
976 } | 991 } |
977 | 992 |
978 | 993 |
979 intptr_t Process::CurrentProcessId() { | 994 intptr_t Process::CurrentProcessId() { |
980 return static_cast<intptr_t>(getpid()); | 995 return static_cast<intptr_t>(getpid()); |
981 } | 996 } |
982 | 997 |
983 | 998 |
984 static Mutex* signal_mutex = new Mutex(); | 999 static Mutex* signal_mutex = new Mutex(); |
985 static SignalInfo* signal_handlers = NULL; | 1000 static SignalInfo* signal_handlers = NULL; |
986 static const int kSignalsCount = 7; | 1001 static const int kSignalsCount = 7; |
987 static const int kSignals[kSignalsCount] = { | 1002 static const int kSignals[kSignalsCount] = { |
988 SIGHUP, | 1003 SIGHUP, SIGINT, SIGTERM, SIGUSR1, SIGUSR2, SIGWINCH, |
989 SIGINT, | 1004 SIGQUIT // Allow VMService to listen on SIGQUIT. |
990 SIGTERM, | |
991 SIGUSR1, | |
992 SIGUSR2, | |
993 SIGWINCH, | |
994 SIGQUIT // Allow VMService to listen on SIGQUIT. | |
995 }; | 1005 }; |
996 | 1006 |
997 | 1007 |
998 SignalInfo::~SignalInfo() { | 1008 SignalInfo::~SignalInfo() { |
999 VOID_TEMP_FAILURE_RETRY(close(fd_)); | 1009 VOID_TEMP_FAILURE_RETRY(close(fd_)); |
1000 } | 1010 } |
1001 | 1011 |
1002 | 1012 |
1003 static void SignalHandler(int signal) { | 1013 static void SignalHandler(int signal) { |
1004 MutexLocker lock(signal_mutex); | 1014 MutexLocker lock(signal_mutex); |
(...skipping 20 matching lines...) Expand all Loading... |
1025 break; | 1035 break; |
1026 } | 1036 } |
1027 } | 1037 } |
1028 if (!found) { | 1038 if (!found) { |
1029 return -1; | 1039 return -1; |
1030 } | 1040 } |
1031 int fds[2]; | 1041 int fds[2]; |
1032 if (NO_RETRY_EXPECTED(pipe(fds)) != 0) { | 1042 if (NO_RETRY_EXPECTED(pipe(fds)) != 0) { |
1033 return -1; | 1043 return -1; |
1034 } | 1044 } |
1035 if (!FDUtils::SetCloseOnExec(fds[0]) || | 1045 if (!FDUtils::SetCloseOnExec(fds[0]) || !FDUtils::SetCloseOnExec(fds[1]) || |
1036 !FDUtils::SetCloseOnExec(fds[1]) || | |
1037 !FDUtils::SetNonBlocking(fds[0])) { | 1046 !FDUtils::SetNonBlocking(fds[0])) { |
1038 VOID_TEMP_FAILURE_RETRY(close(fds[0])); | 1047 VOID_TEMP_FAILURE_RETRY(close(fds[0])); |
1039 VOID_TEMP_FAILURE_RETRY(close(fds[1])); | 1048 VOID_TEMP_FAILURE_RETRY(close(fds[1])); |
1040 return -1; | 1049 return -1; |
1041 } | 1050 } |
1042 ThreadSignalBlocker blocker(kSignalsCount, kSignals); | 1051 ThreadSignalBlocker blocker(kSignalsCount, kSignals); |
1043 MutexLocker lock(signal_mutex); | 1052 MutexLocker lock(signal_mutex); |
1044 SignalInfo* handler = signal_handlers; | 1053 SignalInfo* handler = signal_handlers; |
1045 bool listen = true; | 1054 bool listen = true; |
1046 while (handler != NULL) { | 1055 while (handler != NULL) { |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1105 VOID_NO_RETRY_EXPECTED(sigaction(signal, &act, NULL)); | 1114 VOID_NO_RETRY_EXPECTED(sigaction(signal, &act, NULL)); |
1106 } | 1115 } |
1107 } | 1116 } |
1108 | 1117 |
1109 } // namespace bin | 1118 } // namespace bin |
1110 } // namespace dart | 1119 } // namespace dart |
1111 | 1120 |
1112 #endif // defined(TARGET_OS_MACOS) | 1121 #endif // defined(TARGET_OS_MACOS) |
1113 | 1122 |
1114 #endif // !defined(DART_IO_DISABLED) | 1123 #endif // !defined(DART_IO_DISABLED) |
OLD | NEW |