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

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

Issue 1800863002: Cleanup in //runtime/bin (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Windows fixes Created 4 years, 9 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
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 #include "platform/globals.h" 5 #include "platform/globals.h"
6 #if defined(TARGET_OS_MACOS) 6 #if defined(TARGET_OS_MACOS)
7 7
8 #include "bin/process.h" 8 #include "bin/process.h"
9 9
10 #if !TARGET_OS_IOS 10 #if !TARGET_OS_IOS
(...skipping 10 matching lines...) Expand all
21 21
22 #include "bin/dartutils.h" 22 #include "bin/dartutils.h"
23 #include "bin/fdutils.h" 23 #include "bin/fdutils.h"
24 #include "bin/lockers.h" 24 #include "bin/lockers.h"
25 #include "bin/log.h" 25 #include "bin/log.h"
26 #include "bin/thread.h" 26 #include "bin/thread.h"
27 27
28 #include "platform/signal_blocker.h" 28 #include "platform/signal_blocker.h"
29 #include "platform/utils.h" 29 #include "platform/utils.h"
30 30
31
32
33 namespace dart { 31 namespace dart {
34 namespace bin { 32 namespace bin {
35 33
36 // ProcessInfo is used to map a process id to the file descriptor for 34 // ProcessInfo is used to map a process id to the file descriptor for
37 // the pipe used to communicate the exit code of the process to Dart. 35 // the pipe used to communicate the exit code of the process to Dart.
38 // ProcessInfo objects are kept in the static singly-linked 36 // ProcessInfo objects are kept in the static singly-linked
39 // ProcessInfoList. 37 // ProcessInfoList.
40 class ProcessInfo { 38 class ProcessInfo {
41 public: 39 public:
42 ProcessInfo(pid_t pid, intptr_t fd) : pid_(pid), fd_(fd) { } 40 ProcessInfo(pid_t pid, intptr_t fd) : pid_(pid), fd_(fd) { }
43 ~ProcessInfo() { 41 ~ProcessInfo() {
44 int closed = TEMP_FAILURE_RETRY(close(fd_)); 42 int closed = TEMP_FAILURE_RETRY(close(fd_));
45 if (closed != 0) { 43 if (closed != 0) {
46 FATAL("Failed to close process exit code pipe"); 44 FATAL("Failed to close process exit code pipe");
47 } 45 }
48 } 46 }
49 pid_t pid() { return pid_; } 47 pid_t pid() { return pid_; }
50 intptr_t fd() { return fd_; } 48 intptr_t fd() { return fd_; }
51 ProcessInfo* next() { return next_; } 49 ProcessInfo* next() { return next_; }
52 void set_next(ProcessInfo* info) { next_ = info; } 50 void set_next(ProcessInfo* info) { next_ = info; }
53 51
54 private: 52 private:
55 pid_t pid_; 53 pid_t pid_;
56 intptr_t fd_; 54 intptr_t fd_;
57 ProcessInfo* next_; 55 ProcessInfo* next_;
56
57 DISALLOW_COPY_AND_ASSIGN(ProcessInfo);
58 }; 58 };
59 59
60 60
61 // Singly-linked list of ProcessInfo objects for all active processes 61 // Singly-linked list of ProcessInfo objects for all active processes
62 // started from Dart. 62 // started from Dart.
63 class ProcessInfoList { 63 class ProcessInfoList {
64 public: 64 public:
65 static void AddProcess(pid_t pid, intptr_t fd) { 65 static void AddProcess(pid_t pid, intptr_t fd) {
66 MutexLocker locker(mutex_); 66 MutexLocker locker(mutex_);
67 ProcessInfo* info = new ProcessInfo(pid, fd); 67 ProcessInfo* info = new ProcessInfo(pid, fd);
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
102 } 102 }
103 } 103 }
104 104
105 private: 105 private:
106 // Linked list of ProcessInfo objects for all active processes 106 // Linked list of ProcessInfo objects for all active processes
107 // started from Dart code. 107 // started from Dart code.
108 static ProcessInfo* active_processes_; 108 static ProcessInfo* active_processes_;
109 // Mutex protecting all accesses to the linked list of active 109 // Mutex protecting all accesses to the linked list of active
110 // processes. 110 // processes.
111 static Mutex* mutex_; 111 static Mutex* mutex_;
112
113 DISALLOW_ALLOCATION();
114 DISALLOW_IMPLICIT_CONSTRUCTORS(ProcessInfoList);
112 }; 115 };
113 116
114 117
115 ProcessInfo* ProcessInfoList::active_processes_ = NULL; 118 ProcessInfo* ProcessInfoList::active_processes_ = NULL;
116 Mutex* ProcessInfoList::mutex_ = new Mutex(); 119 Mutex* ProcessInfoList::mutex_ = new Mutex();
117 120
118 121
119 // The exit code handler sets up a separate thread which waits for child 122 // The exit code handler sets up a separate thread which waits for child
120 // processes to terminate. That separate thread can then get the exit code from 123 // processes to terminate. That separate thread can then get the exit code from
121 // processes that have exited and communicate it to Dart through the 124 // processes that have exited and communicate it to Dart through the
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after
198 } 201 }
199 intptr_t exit_code_fd = ProcessInfoList::LookupProcessExitFd(pid); 202 intptr_t exit_code_fd = ProcessInfoList::LookupProcessExitFd(pid);
200 if (exit_code_fd != 0) { 203 if (exit_code_fd != 0) {
201 int message[2] = { exit_code, negative }; 204 int message[2] = { exit_code, negative };
202 ssize_t result = 205 ssize_t result =
203 FDUtils::WriteToBlocking(exit_code_fd, &message, sizeof(message)); 206 FDUtils::WriteToBlocking(exit_code_fd, &message, sizeof(message));
204 // If the process has been closed, the read end of the exit 207 // If the process has been closed, the read end of the exit
205 // pipe has been closed. It is therefore not a problem that 208 // pipe has been closed. It is therefore not a problem that
206 // write fails with a broken pipe error. Other errors should 209 // write fails with a broken pipe error. Other errors should
207 // not happen. 210 // not happen.
208 if (result != -1 && result != sizeof(message)) { 211 if ((result != -1) && (result != sizeof(message))) {
209 FATAL("Failed to write entire process exit message"); 212 FATAL("Failed to write entire process exit message");
210 } else if (result == -1 && errno != EPIPE) { 213 } else if ((result == -1) && (errno != EPIPE)) {
211 FATAL1("Failed to write exit code: %d", errno); 214 FATAL1("Failed to write exit code: %d", errno);
212 } 215 }
213 ProcessInfoList::RemoveProcess(pid); 216 ProcessInfoList::RemoveProcess(pid);
214 { 217 {
215 MonitorLocker locker(monitor_); 218 MonitorLocker locker(monitor_);
216 process_count_--; 219 process_count_--;
217 } 220 }
218 } 221 }
219 } 222 }
220 } 223 }
221 } 224 }
222 225
223 static bool terminate_done_; 226 static bool terminate_done_;
224 static int process_count_; 227 static int process_count_;
225 static bool running_; 228 static bool running_;
226 static Monitor* monitor_; 229 static Monitor* monitor_;
230
231 DISALLOW_ALLOCATION();
232 DISALLOW_IMPLICIT_CONSTRUCTORS(ExitCodeHandler);
227 }; 233 };
228 234
229 235
230 bool ExitCodeHandler::running_ = false; 236 bool ExitCodeHandler::running_ = false;
231 int ExitCodeHandler::process_count_ = 0; 237 int ExitCodeHandler::process_count_ = 0;
232 bool ExitCodeHandler::terminate_done_ = false; 238 bool ExitCodeHandler::terminate_done_ = false;
233 Monitor* ExitCodeHandler::monitor_ = new Monitor(); 239 Monitor* ExitCodeHandler::monitor_ = new Monitor();
234 240
235 241
236 class ProcessStarter { 242 class ProcessStarter {
(...skipping 22 matching lines...) Expand all
259 os_error_message_(os_error_message) { 265 os_error_message_(os_error_message) {
260 read_in_[0] = -1; 266 read_in_[0] = -1;
261 read_in_[1] = -1; 267 read_in_[1] = -1;
262 read_err_[0] = -1; 268 read_err_[0] = -1;
263 read_err_[1] = -1; 269 read_err_[1] = -1;
264 write_out_[0] = -1; 270 write_out_[0] = -1;
265 write_out_[1] = -1; 271 write_out_[1] = -1;
266 exec_control_[0] = -1; 272 exec_control_[0] = -1;
267 exec_control_[1] = -1; 273 exec_control_[1] = -1;
268 274
269 program_arguments_ = new char*[arguments_length + 2]; 275 program_arguments_ = reinterpret_cast<char**>(Dart_ScopeAllocate(
zra 2016/03/15 18:12:29 Changed to scope allocation.
276 (arguments_length + 2) * sizeof(*program_arguments_)));
270 program_arguments_[0] = const_cast<char*>(path_); 277 program_arguments_[0] = const_cast<char*>(path_);
271 for (int i = 0; i < arguments_length; i++) { 278 for (int i = 0; i < arguments_length; i++) {
272 program_arguments_[i + 1] = arguments[i]; 279 program_arguments_[i + 1] = arguments[i];
273 } 280 }
274 program_arguments_[arguments_length + 1] = NULL; 281 program_arguments_[arguments_length + 1] = NULL;
275 282
276 program_environment_ = NULL; 283 program_environment_ = NULL;
277 if (environment != NULL) { 284 if (environment != NULL) {
278 program_environment_ = new char*[environment_length + 1]; 285 program_environment_ = reinterpret_cast<char**>(Dart_ScopeAllocate(
zra 2016/03/15 18:12:29 ditto.
286 (environment_length + 1) * sizeof(*program_environment_)));
279 for (int i = 0; i < environment_length; i++) { 287 for (int i = 0; i < environment_length; i++) {
280 program_environment_[i] = environment[i]; 288 program_environment_[i] = environment[i];
281 } 289 }
282 program_environment_[environment_length] = NULL; 290 program_environment_[environment_length] = NULL;
283 } 291 }
284 } 292 }
285 293
286 294
287 ~ProcessStarter() {
288 delete[] program_arguments_;
289 delete[] program_environment_;
290 }
291
292
293 int Start() { 295 int Start() {
294 // Create pipes required. 296 // Create pipes required.
295 int err = CreatePipes(); 297 int err = CreatePipes();
296 if (err != 0) { 298 if (err != 0) {
297 return err; 299 return err;
298 } 300 }
299 301
300 // Fork to create the new process. 302 // Fork to create the new process.
301 pid_t pid = TEMP_FAILURE_RETRY(fork()); 303 pid_t pid = TEMP_FAILURE_RETRY(fork());
302 if (pid < 0) { 304 if (pid < 0) {
(...skipping 199 matching lines...) Expand 10 before | Expand all | Expand 10 after
502 pid = TEMP_FAILURE_RETRY(fork()); 504 pid = TEMP_FAILURE_RETRY(fork());
503 if (pid < 0) { 505 if (pid < 0) {
504 ReportChildError(); 506 ReportChildError();
505 } else if (pid == 0) { 507 } else if (pid == 0) {
506 if (mode_ == kDetached) { 508 if (mode_ == kDetached) {
507 SetupDetached(); 509 SetupDetached();
508 } else { 510 } else {
509 SetupDetachedWithStdio(); 511 SetupDetachedWithStdio();
510 } 512 }
511 513
512 if (working_directory_ != NULL && 514 if ((working_directory_ != NULL) &&
513 TEMP_FAILURE_RETRY(chdir(working_directory_)) == -1) { 515 (TEMP_FAILURE_RETRY(chdir(working_directory_)) == -1)) {
514 ReportChildError(); 516 ReportChildError();
515 } 517 }
516 518
517 // Report the final PID and do the exec. 519 // Report the final PID and do the exec.
518 ReportPid(getpid()); // getpid cannot fail. 520 ReportPid(getpid()); // getpid cannot fail.
519 VOID_TEMP_FAILURE_RETRY( 521 VOID_TEMP_FAILURE_RETRY(
520 execvp(path_, const_cast<char* const*>(program_arguments_))); 522 execvp(path_, const_cast<char* const*>(program_arguments_)));
521 ReportChildError(); 523 ReportChildError();
522 } else { 524 } else {
523 // Exit the intermeiate process. 525 // Exit the intermeiate process.
(...skipping 23 matching lines...) Expand all
547 return 0; 549 return 0;
548 } 550 }
549 551
550 552
551 int ReadExecResult() { 553 int ReadExecResult() {
552 int child_errno; 554 int child_errno;
553 int bytes_read = -1; 555 int bytes_read = -1;
554 // Read exec result from child. If no data is returned the exec was 556 // Read exec result from child. If no data is returned the exec was
555 // successful and the exec call closed the pipe. Otherwise the errno 557 // successful and the exec call closed the pipe. Otherwise the errno
556 // is written to the pipe. 558 // is written to the pipe.
557 bytes_read = 559 bytes_read = FDUtils::ReadFromBlocking(
558 FDUtils::ReadFromBlocking( 560 exec_control_[0], &child_errno, sizeof(child_errno));
559 exec_control_[0], &child_errno, sizeof(child_errno));
560 if (bytes_read == sizeof(child_errno)) { 561 if (bytes_read == sizeof(child_errno)) {
561 ReadChildError(); 562 ReadChildError();
562 return child_errno; 563 return child_errno;
563 } else if (bytes_read == -1) { 564 } else if (bytes_read == -1) {
564 return errno; 565 return errno;
565 } 566 }
566 return 0; 567 return 0;
567 } 568 }
568 569
569 570
570 int ReadDetachedExecResult(pid_t *pid) { 571 int ReadDetachedExecResult(pid_t *pid) {
571 int child_errno; 572 int child_errno;
572 int bytes_read = -1; 573 int bytes_read = -1;
573 // Read exec result from child. If only pid data is returned the exec was 574 // Read exec result from child. If only pid data is returned the exec was
574 // successful and the exec call closed the pipe. Otherwise the errno 575 // successful and the exec call closed the pipe. Otherwise the errno
575 // is written to the pipe as well. 576 // is written to the pipe as well.
576 int result[2]; 577 int result[2];
577 bytes_read = 578 bytes_read =
578 FDUtils::ReadFromBlocking( 579 FDUtils::ReadFromBlocking(exec_control_[0], result, sizeof(result));
579 exec_control_[0], result, sizeof(result));
580 if (bytes_read == sizeof(int)) { 580 if (bytes_read == sizeof(int)) {
581 *pid = result[0]; 581 *pid = result[0];
582 } else if (bytes_read == 2 * sizeof(int)) { 582 } else if (bytes_read == 2 * sizeof(int)) {
583 *pid = result[0]; 583 *pid = result[0];
584 child_errno = result[1]; 584 child_errno = result[1];
585 ReadChildError(); 585 ReadChildError();
586 return child_errno; 586 return child_errno;
587 } else if (bytes_read == -1) { 587 } else if (bytes_read == -1) {
588 return errno; 588 return errno;
589 } 589 }
590 return 0; 590 return 0;
591 } 591 }
592 592
593 593
594 void SetupDetached() { 594 void SetupDetached() {
595 ASSERT(mode_ == kDetached); 595 ASSERT(mode_ == kDetached);
596 596
597 // Close all open file descriptors except for exec_control_[1]. 597 // Close all open file descriptors except for exec_control_[1].
598 int max_fds = sysconf(_SC_OPEN_MAX); 598 int max_fds = sysconf(_SC_OPEN_MAX);
599 if (max_fds == -1) max_fds = _POSIX_OPEN_MAX; 599 if (max_fds == -1) {
600 max_fds = _POSIX_OPEN_MAX;
601 }
600 for (int fd = 0; fd < max_fds; fd++) { 602 for (int fd = 0; fd < max_fds; fd++) {
601 if (fd != exec_control_[1]) { 603 if (fd != exec_control_[1]) {
602 VOID_TEMP_FAILURE_RETRY(close(fd)); 604 VOID_TEMP_FAILURE_RETRY(close(fd));
603 } 605 }
604 } 606 }
605 607
606 // Re-open stdin, stdout and stderr and connect them to /dev/null. 608 // Re-open stdin, stdout and stderr and connect them to /dev/null.
607 // The loop above should already have closed all of them, so 609 // The loop above should already have closed all of them, so
608 // creating new file descriptors should start at STDIN_FILENO. 610 // creating new file descriptors should start at STDIN_FILENO.
609 int fd = TEMP_FAILURE_RETRY(open("/dev/null", O_RDWR)); 611 int fd = TEMP_FAILURE_RETRY(open("/dev/null", O_RDWR));
610 if (fd != STDIN_FILENO) { 612 if (fd != STDIN_FILENO) {
611 ReportChildError(); 613 ReportChildError();
612 } 614 }
613 if (TEMP_FAILURE_RETRY(dup2(STDIN_FILENO, STDOUT_FILENO)) != 615 if (TEMP_FAILURE_RETRY(dup2(STDIN_FILENO, STDOUT_FILENO)) !=
614 STDOUT_FILENO) { 616 STDOUT_FILENO) {
615 ReportChildError(); 617 ReportChildError();
616 } 618 }
617 if (TEMP_FAILURE_RETRY(dup2(STDIN_FILENO, STDERR_FILENO)) != 619 if (TEMP_FAILURE_RETRY(dup2(STDIN_FILENO, STDERR_FILENO)) !=
618 STDERR_FILENO) { 620 STDERR_FILENO) {
619 ReportChildError(); 621 ReportChildError();
620 } 622 }
621 } 623 }
622 624
623 void SetupDetachedWithStdio() { 625 void SetupDetachedWithStdio() {
624 // Close all open file descriptors except for 626 // Close all open file descriptors except for
625 // exec_control_[1], write_out_[0], read_in_[1] and 627 // exec_control_[1], write_out_[0], read_in_[1] and
626 // read_err_[1]. 628 // read_err_[1].
627 int max_fds = sysconf(_SC_OPEN_MAX); 629 int max_fds = sysconf(_SC_OPEN_MAX);
628 if (max_fds == -1) max_fds = _POSIX_OPEN_MAX; 630 if (max_fds == -1) {
631 max_fds = _POSIX_OPEN_MAX;
632 }
629 for (int fd = 0; fd < max_fds; fd++) { 633 for (int fd = 0; fd < max_fds; fd++) {
630 if (fd != exec_control_[1] && 634 if ((fd != exec_control_[1]) &&
631 fd != write_out_[0] && 635 (fd != write_out_[0]) &&
632 fd != read_in_[1] && 636 (fd != read_in_[1]) &&
633 fd != read_err_[1]) { 637 (fd != read_err_[1])) {
634 VOID_TEMP_FAILURE_RETRY(close(fd)); 638 VOID_TEMP_FAILURE_RETRY(close(fd));
635 } 639 }
636 } 640 }
637 641
638 if (TEMP_FAILURE_RETRY(dup2(write_out_[0], STDIN_FILENO)) == -1) { 642 if (TEMP_FAILURE_RETRY(dup2(write_out_[0], STDIN_FILENO)) == -1) {
639 ReportChildError(); 643 ReportChildError();
640 } 644 }
641 VOID_TEMP_FAILURE_RETRY(close(write_out_[0])); 645 VOID_TEMP_FAILURE_RETRY(close(write_out_[0]));
642 646
643 if (TEMP_FAILURE_RETRY(dup2(read_in_[1], STDOUT_FILENO)) == -1) { 647 if (TEMP_FAILURE_RETRY(dup2(read_in_[1], STDOUT_FILENO)) == -1) {
(...skipping 29 matching lines...) Expand all
673 } 677 }
674 678
675 679
676 void ReportChildError() { 680 void ReportChildError() {
677 // In the case of failure in the child process write the errno and 681 // In the case of failure in the child process write the errno and
678 // the OS error message to the exec control pipe and exit. 682 // the OS error message to the exec control pipe and exit.
679 int child_errno = errno; 683 int child_errno = errno;
680 const int kBufferSize = 1024; 684 const int kBufferSize = 1024;
681 char os_error_message[kBufferSize]; 685 char os_error_message[kBufferSize];
682 Utils::StrError(errno, os_error_message, kBufferSize); 686 Utils::StrError(errno, os_error_message, kBufferSize);
683 int bytes_written = 687 int bytes_written = FDUtils::WriteToBlocking(
684 FDUtils::WriteToBlocking( 688 exec_control_[1], &child_errno, sizeof(child_errno));
685 exec_control_[1], &child_errno, sizeof(child_errno));
686 if (bytes_written == sizeof(child_errno)) { 689 if (bytes_written == sizeof(child_errno)) {
687 FDUtils::WriteToBlocking( 690 FDUtils::WriteToBlocking(
688 exec_control_[1], os_error_message, strlen(os_error_message) + 1); 691 exec_control_[1], os_error_message, strlen(os_error_message) + 1);
689 } 692 }
690 VOID_TEMP_FAILURE_RETRY(close(exec_control_[1])); 693 VOID_TEMP_FAILURE_RETRY(close(exec_control_[1]));
691 exit(1); 694 exit(1);
692 } 695 }
693 696
694 697
695 void ReportPid(int pid) { 698 void ReportPid(int pid) {
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
744 747
745 const char* path_; 748 const char* path_;
746 const char* working_directory_; 749 const char* working_directory_;
747 ProcessStartMode mode_; 750 ProcessStartMode mode_;
748 intptr_t* in_; 751 intptr_t* in_;
749 intptr_t* out_; 752 intptr_t* out_;
750 intptr_t* err_; 753 intptr_t* err_;
751 intptr_t* id_; 754 intptr_t* id_;
752 intptr_t* exit_event_; 755 intptr_t* exit_event_;
753 char** os_error_message_; 756 char** os_error_message_;
757
758 DISALLOW_ALLOCATION();
759 DISALLOW_IMPLICIT_CONSTRUCTORS(ProcessStarter);
754 }; 760 };
755 761
756 762
757 int Process::Start(const char* path, 763 int Process::Start(const char* path,
758 char* arguments[], 764 char* arguments[],
759 intptr_t arguments_length, 765 intptr_t arguments_length,
760 const char* working_directory, 766 const char* working_directory,
761 char* environment[], 767 char* environment[],
762 intptr_t environment_length, 768 intptr_t environment_length,
763 ProcessStartMode mode, 769 ProcessStartMode mode,
(...skipping 15 matching lines...) Expand all
779 err, 785 err,
780 id, 786 id,
781 exit_event, 787 exit_event,
782 os_error_message); 788 os_error_message);
783 return starter.Start(); 789 return starter.Start();
784 } 790 }
785 791
786 792
787 class BufferList: public BufferListBase { 793 class BufferList: public BufferListBase {
788 public: 794 public:
795 BufferList() {}
796
789 bool Read(int fd, intptr_t available) { 797 bool Read(int fd, intptr_t available) {
790 // Read all available bytes. 798 // Read all available bytes.
791 while (available > 0) { 799 while (available > 0) {
792 if (free_size_ == 0) Allocate(); 800 if (free_size_ == 0) {
801 Allocate();
802 }
793 ASSERT(free_size_ > 0); 803 ASSERT(free_size_ > 0);
794 ASSERT(free_size_ <= kBufferSize); 804 ASSERT(free_size_ <= kBufferSize);
795 size_t block_size = dart::Utils::Minimum(free_size_, available); 805 size_t block_size = dart::Utils::Minimum(free_size_, available);
796 ssize_t bytes = TEMP_FAILURE_RETRY(read( 806 ssize_t bytes = TEMP_FAILURE_RETRY(read(
797 fd, 807 fd,
798 reinterpret_cast<void*>(FreeSpaceAddress()), 808 reinterpret_cast<void*>(FreeSpaceAddress()),
799 block_size)); 809 block_size));
800 if (bytes < 0) return false; 810 if (bytes < 0) {
811 return false;
812 }
801 data_size_ += bytes; 813 data_size_ += bytes;
802 free_size_ -= bytes; 814 free_size_ -= bytes;
803 available -= bytes; 815 available -= bytes;
804 } 816 }
805 return true; 817 return true;
806 } 818 }
819
820 private:
821 DISALLOW_COPY_AND_ASSIGN(BufferList);
807 }; 822 };
808 823
809 824
810 static bool CloseProcessBuffers(struct pollfd fds[3]) { 825 static bool CloseProcessBuffers(struct pollfd fds[3]) {
811 int e = errno; 826 int e = errno;
812 VOID_TEMP_FAILURE_RETRY(close(fds[0].fd)); 827 VOID_TEMP_FAILURE_RETRY(close(fds[0].fd));
813 VOID_TEMP_FAILURE_RETRY(close(fds[1].fd)); 828 VOID_TEMP_FAILURE_RETRY(close(fds[1].fd));
814 VOID_TEMP_FAILURE_RETRY(close(fds[2].fd)); 829 VOID_TEMP_FAILURE_RETRY(close(fds[2].fd));
815 errno = e; 830 errno = e;
816 return false; 831 return false;
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
849 while (alive > 0) { 864 while (alive > 0) {
850 // Blocking call waiting for events from the child process. 865 // Blocking call waiting for events from the child process.
851 if (TEMP_FAILURE_RETRY(poll(fds, alive, -1)) <= 0) { 866 if (TEMP_FAILURE_RETRY(poll(fds, alive, -1)) <= 0) {
852 return CloseProcessBuffers(fds); 867 return CloseProcessBuffers(fds);
853 } 868 }
854 869
855 // Process incoming data. 870 // Process incoming data.
856 int current_alive = alive; 871 int current_alive = alive;
857 for (int i = 0; i < current_alive; i++) { 872 for (int i = 0; i < current_alive; i++) {
858 intptr_t avail; 873 intptr_t avail;
859 if (fds[i].revents & POLLIN) { 874 if ((fds[i].revents & POLLIN) != 0) {
860 avail = FDUtils::AvailableBytes(fds[i].fd); 875 avail = FDUtils::AvailableBytes(fds[i].fd);
861 // On Mac OS POLLIN can be set with zero available 876 // On Mac OS POLLIN can be set with zero available
862 // bytes. POLLHUP is most likely also set in this case. 877 // bytes. POLLHUP is most likely also set in this case.
863 if (avail > 0) { 878 if (avail > 0) {
864 if (fds[i].fd == out) { 879 if (fds[i].fd == out) {
865 if (!out_data.Read(out, avail)) { 880 if (!out_data.Read(out, avail)) {
866 return CloseProcessBuffers(fds); 881 return CloseProcessBuffers(fds);
867 } 882 }
868 } else if (fds[i].fd == err) { 883 } else if (fds[i].fd == err) {
869 if (!err_data.Read(err, avail)) { 884 if (!err_data.Read(err, avail)) {
870 return CloseProcessBuffers(fds); 885 return CloseProcessBuffers(fds);
871 } 886 }
872 } else if (fds[i].fd == exit_event) { 887 } else if (fds[i].fd == exit_event) {
873 if (avail == 8) { 888 if (avail == 8) {
874 intptr_t b = TEMP_FAILURE_RETRY(read(fds[i].fd, 889 intptr_t b = TEMP_FAILURE_RETRY(read(fds[i].fd,
875 exit_code_data.bytes, 8)); 890 exit_code_data.bytes, 8));
876 if (b != 8) { 891 if (b != 8) {
877 return CloseProcessBuffers(fds); 892 return CloseProcessBuffers(fds);
878 } 893 }
879 } 894 }
880 } else { 895 } else {
881 UNREACHABLE(); 896 UNREACHABLE();
882 } 897 }
883 } 898 }
884 } 899 }
885 if (fds[i].revents & POLLHUP || 900 if (((fds[i].revents & POLLHUP) != 0) ||
886 ((fds[i].revents & POLLIN) && avail == 0)) { 901 (((fds[i].revents & POLLIN) != 0) && (avail == 0))) {
887 VOID_TEMP_FAILURE_RETRY(close(fds[i].fd)); 902 VOID_TEMP_FAILURE_RETRY(close(fds[i].fd));
888 alive--; 903 alive--;
889 if (i < alive) { 904 if (i < alive) {
890 fds[i] = fds[alive]; 905 fds[i] = fds[alive];
891 } 906 }
892 } 907 }
893 } 908 }
894 } 909 }
895 910
896 // All handles closed and all data read. 911 // All handles closed and all data read.
897 result->set_stdout_data(out_data.GetData()); 912 result->set_stdout_data(out_data.GetData());
898 result->set_stderr_data(err_data.GetData()); 913 result->set_stderr_data(err_data.GetData());
899 914
900 // Calculate the exit code. 915 // Calculate the exit code.
901 intptr_t exit_code = exit_code_data.ints[0]; 916 intptr_t exit_code = exit_code_data.ints[0];
902 intptr_t negative = exit_code_data.ints[1]; 917 intptr_t negative = exit_code_data.ints[1];
903 if (negative) exit_code = -exit_code; 918 if (negative) {
919 exit_code = -exit_code;
920 }
904 result->set_exit_code(exit_code); 921 result->set_exit_code(exit_code);
905 922
906 return true; 923 return true;
907 } 924 }
908 925
909 926
910 static int SignalMap(intptr_t id) { 927 static int SignalMap(intptr_t id) {
911 switch (static_cast<ProcessSignals>(id)) { 928 switch (static_cast<ProcessSignals>(id)) {
912 case kSighup: return SIGHUP; 929 case kSighup: return SIGHUP;
913 case kSigint: return SIGINT; 930 case kSigint: return SIGINT;
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
985 int value = 0; 1002 int value = 0;
986 VOID_TEMP_FAILURE_RETRY(write(handler->fd(), &value, 1)); 1003 VOID_TEMP_FAILURE_RETRY(write(handler->fd(), &value, 1));
987 } 1004 }
988 handler = handler->next(); 1005 handler = handler->next();
989 } 1006 }
990 } 1007 }
991 1008
992 1009
993 intptr_t Process::SetSignalHandler(intptr_t signal) { 1010 intptr_t Process::SetSignalHandler(intptr_t signal) {
994 signal = SignalMap(signal); 1011 signal = SignalMap(signal);
995 if (signal == -1) return -1; 1012 if (signal == -1) {
1013 return -1;
1014 }
996 bool found = false; 1015 bool found = false;
997 for (int i = 0; i < kSignalsCount; i++) { 1016 for (int i = 0; i < kSignalsCount; i++) {
998 if (kSignals[i] == signal) { 1017 if (kSignals[i] == signal) {
999 found = true; 1018 found = true;
1000 break; 1019 break;
1001 } 1020 }
1002 } 1021 }
1003 if (!found) return -1; 1022 if (!found) {
1023 return -1;
1024 }
1004 int fds[2]; 1025 int fds[2];
1005 if (NO_RETRY_EXPECTED(pipe(fds)) != 0) { 1026 if (NO_RETRY_EXPECTED(pipe(fds)) != 0) {
1006 return -1; 1027 return -1;
1007 } 1028 }
1008 if (!FDUtils::SetCloseOnExec(fds[0]) || 1029 if (!FDUtils::SetCloseOnExec(fds[0]) ||
1009 !FDUtils::SetCloseOnExec(fds[1]) || 1030 !FDUtils::SetCloseOnExec(fds[1]) ||
1010 !FDUtils::SetNonBlocking(fds[0])) { 1031 !FDUtils::SetNonBlocking(fds[0])) {
1011 VOID_TEMP_FAILURE_RETRY(close(fds[0])); 1032 VOID_TEMP_FAILURE_RETRY(close(fds[0]));
1012 VOID_TEMP_FAILURE_RETRY(close(fds[1])); 1033 VOID_TEMP_FAILURE_RETRY(close(fds[1]));
1013 return -1; 1034 return -1;
(...skipping 24 matching lines...) Expand all
1038 return -1; 1059 return -1;
1039 } 1060 }
1040 } 1061 }
1041 signal_handlers = new SignalInfo(fds[1], signal, signal_handlers); 1062 signal_handlers = new SignalInfo(fds[1], signal, signal_handlers);
1042 return fds[0]; 1063 return fds[0];
1043 } 1064 }
1044 1065
1045 1066
1046 void Process::ClearSignalHandler(intptr_t signal) { 1067 void Process::ClearSignalHandler(intptr_t signal) {
1047 signal = SignalMap(signal); 1068 signal = SignalMap(signal);
1048 if (signal == -1) return; 1069 if (signal == -1) {
1070 return;
1071 }
1049 ThreadSignalBlocker blocker(kSignalsCount, kSignals); 1072 ThreadSignalBlocker blocker(kSignalsCount, kSignals);
1050 MutexLocker lock(signal_mutex); 1073 MutexLocker lock(signal_mutex);
1051 SignalInfo* handler = signal_handlers; 1074 SignalInfo* handler = signal_handlers;
1052 bool unlisten = true; 1075 bool unlisten = true;
1053 while (handler != NULL) { 1076 while (handler != NULL) {
1054 bool remove = false; 1077 bool remove = false;
1055 if (handler->signal() == signal) { 1078 if (handler->signal() == signal) {
1056 if (handler->port() == Dart_GetMainPortId()) { 1079 if (handler->port() == Dart_GetMainPortId()) {
1057 if (signal_handlers == handler) signal_handlers = handler->next(); 1080 if (signal_handlers == handler) {
1081 signal_handlers = handler->next();
1082 }
1058 handler->Unlink(); 1083 handler->Unlink();
1059 remove = true; 1084 remove = true;
1060 } else { 1085 } else {
1061 unlisten = false; 1086 unlisten = false;
1062 } 1087 }
1063 } 1088 }
1064 SignalInfo* next = handler->next(); 1089 SignalInfo* next = handler->next();
1065 if (remove) delete handler; 1090 if (remove) {
1091 delete handler;
1092 }
1066 handler = next; 1093 handler = next;
1067 } 1094 }
1068 if (unlisten) { 1095 if (unlisten) {
1069 struct sigaction act; 1096 struct sigaction act;
1070 bzero(&act, sizeof(act)); 1097 bzero(&act, sizeof(act));
1071 act.sa_handler = SIG_DFL; 1098 act.sa_handler = SIG_DFL;
1072 VOID_NO_RETRY_EXPECTED(sigaction(signal, &act, NULL)); 1099 VOID_NO_RETRY_EXPECTED(sigaction(signal, &act, NULL));
1073 } 1100 }
1074 } 1101 }
1075 1102
1076 } // namespace bin 1103 } // namespace bin
1077 } // namespace dart 1104 } // namespace dart
1078 1105
1079 #endif // defined(TARGET_OS_MACOS) 1106 #endif // defined(TARGET_OS_MACOS)
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698