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

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

Issue 2974233002: VM: Re-format to use at most one newline between functions (Closed)
Patch Set: Rebase and merge Created 3 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 | « runtime/bin/process_linux.cc ('k') | runtime/bin/process_unsupported.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(HOST_OS_MACOS) 8 #if defined(HOST_OS_MACOS)
9 9
10 #include "bin/process.h" 10 #include "bin/process.h"
11 11
12 #if !HOST_OS_IOS 12 #if !HOST_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 <mach/mach.h> // NOLINT 17 #include <mach/mach.h> // NOLINT
18 #include <poll.h> // NOLINT 18 #include <poll.h> // NOLINT
19 #include <signal.h> // NOLINT 19 #include <signal.h> // NOLINT
20 #include <stdio.h> // NOLINT 20 #include <stdio.h> // NOLINT
21 #include <stdlib.h> // NOLINT 21 #include <stdlib.h> // NOLINT
22 #include <string.h> // NOLINT 22 #include <string.h> // NOLINT
23 #include <unistd.h> // NOLINT 23 #include <unistd.h> // NOLINT
24 24
25 #include "bin/dartutils.h" 25 #include "bin/dartutils.h"
26 #include "bin/fdutils.h" 26 #include "bin/fdutils.h"
27 #include "bin/lockers.h" 27 #include "bin/lockers.h"
28 #include "bin/log.h" 28 #include "bin/log.h"
29 #include "bin/thread.h" 29 #include "bin/thread.h"
30 30
31 #include "platform/signal_blocker.h" 31 #include "platform/signal_blocker.h"
32 #include "platform/utils.h" 32 #include "platform/utils.h"
33 33
(...skipping 23 matching lines...) Expand all
57 void set_next(ProcessInfo* info) { next_ = info; } 57 void set_next(ProcessInfo* info) { next_ = info; }
58 58
59 private: 59 private:
60 pid_t pid_; 60 pid_t pid_;
61 intptr_t fd_; 61 intptr_t fd_;
62 ProcessInfo* next_; 62 ProcessInfo* next_;
63 63
64 DISALLOW_COPY_AND_ASSIGN(ProcessInfo); 64 DISALLOW_COPY_AND_ASSIGN(ProcessInfo);
65 }; 65 };
66 66
67
68 // Singly-linked list of ProcessInfo objects for all active processes 67 // Singly-linked list of ProcessInfo objects for all active processes
69 // started from Dart. 68 // started from Dart.
70 class ProcessInfoList { 69 class ProcessInfoList {
71 public: 70 public:
72 static void AddProcess(pid_t pid, intptr_t fd) { 71 static void AddProcess(pid_t pid, intptr_t fd) {
73 MutexLocker locker(mutex_); 72 MutexLocker locker(mutex_);
74 ProcessInfo* info = new ProcessInfo(pid, fd); 73 ProcessInfo* info = new ProcessInfo(pid, fd);
75 info->set_next(active_processes_); 74 info->set_next(active_processes_);
76 active_processes_ = info; 75 active_processes_ = info;
77 } 76 }
78 77
79
80 static intptr_t LookupProcessExitFd(pid_t pid) { 78 static intptr_t LookupProcessExitFd(pid_t pid) {
81 MutexLocker locker(mutex_); 79 MutexLocker locker(mutex_);
82 ProcessInfo* current = active_processes_; 80 ProcessInfo* current = active_processes_;
83 while (current != NULL) { 81 while (current != NULL) {
84 if (current->pid() == pid) { 82 if (current->pid() == pid) {
85 return current->fd(); 83 return current->fd();
86 } 84 }
87 current = current->next(); 85 current = current->next();
88 } 86 }
89 return 0; 87 return 0;
90 } 88 }
91 89
92
93 static void RemoveProcess(pid_t pid) { 90 static void RemoveProcess(pid_t pid) {
94 MutexLocker locker(mutex_); 91 MutexLocker locker(mutex_);
95 ProcessInfo* prev = NULL; 92 ProcessInfo* prev = NULL;
96 ProcessInfo* current = active_processes_; 93 ProcessInfo* current = active_processes_;
97 while (current != NULL) { 94 while (current != NULL) {
98 if (current->pid() == pid) { 95 if (current->pid() == pid) {
99 if (prev == NULL) { 96 if (prev == NULL) {
100 active_processes_ = current->next(); 97 active_processes_ = current->next();
101 } else { 98 } else {
102 prev->set_next(current->next()); 99 prev->set_next(current->next());
(...skipping 11 matching lines...) Expand all
114 // started from Dart code. 111 // started from Dart code.
115 static ProcessInfo* active_processes_; 112 static ProcessInfo* active_processes_;
116 // Mutex protecting all accesses to the linked list of active 113 // Mutex protecting all accesses to the linked list of active
117 // processes. 114 // processes.
118 static Mutex* mutex_; 115 static Mutex* mutex_;
119 116
120 DISALLOW_ALLOCATION(); 117 DISALLOW_ALLOCATION();
121 DISALLOW_IMPLICIT_CONSTRUCTORS(ProcessInfoList); 118 DISALLOW_IMPLICIT_CONSTRUCTORS(ProcessInfoList);
122 }; 119 };
123 120
124
125 ProcessInfo* ProcessInfoList::active_processes_ = NULL; 121 ProcessInfo* ProcessInfoList::active_processes_ = NULL;
126 Mutex* ProcessInfoList::mutex_ = new Mutex(); 122 Mutex* ProcessInfoList::mutex_ = new Mutex();
127 123
128
129 // The exit code handler sets up a separate thread which waits for child 124 // The exit code handler sets up a separate thread which waits for child
130 // processes to terminate. That separate thread can then get the exit code from 125 // processes to terminate. That separate thread can then get the exit code from
131 // processes that have exited and communicate it to Dart through the 126 // processes that have exited and communicate it to Dart through the
132 // event loop. 127 // event loop.
133 class ExitCodeHandler { 128 class ExitCodeHandler {
134 public: 129 public:
135 // Notify the ExitCodeHandler that another process exists. 130 // Notify the ExitCodeHandler that another process exists.
136 static void ProcessStarted() { 131 static void ProcessStarted() {
137 // Multiple isolates could be starting processes at the same 132 // Multiple isolates could be starting processes at the same
138 // time. Make sure that only one ExitCodeHandler thread exists. 133 // time. Make sure that only one ExitCodeHandler thread exists.
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after
232 227
233 static bool terminate_done_; 228 static bool terminate_done_;
234 static int process_count_; 229 static int process_count_;
235 static bool running_; 230 static bool running_;
236 static Monitor* monitor_; 231 static Monitor* monitor_;
237 232
238 DISALLOW_ALLOCATION(); 233 DISALLOW_ALLOCATION();
239 DISALLOW_IMPLICIT_CONSTRUCTORS(ExitCodeHandler); 234 DISALLOW_IMPLICIT_CONSTRUCTORS(ExitCodeHandler);
240 }; 235 };
241 236
242
243 bool ExitCodeHandler::running_ = false; 237 bool ExitCodeHandler::running_ = false;
244 int ExitCodeHandler::process_count_ = 0; 238 int ExitCodeHandler::process_count_ = 0;
245 bool ExitCodeHandler::terminate_done_ = false; 239 bool ExitCodeHandler::terminate_done_ = false;
246 Monitor* ExitCodeHandler::monitor_ = new Monitor(); 240 Monitor* ExitCodeHandler::monitor_ = new Monitor();
247 241
248
249 class ProcessStarter { 242 class ProcessStarter {
250 public: 243 public:
251 ProcessStarter(const char* path, 244 ProcessStarter(const char* path,
252 char* arguments[], 245 char* arguments[],
253 intptr_t arguments_length, 246 intptr_t arguments_length,
254 const char* working_directory, 247 const char* working_directory,
255 char* environment[], 248 char* environment[],
256 intptr_t environment_length, 249 intptr_t environment_length,
257 ProcessStartMode mode, 250 ProcessStartMode mode,
258 intptr_t* in, 251 intptr_t* in,
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
291 if (environment != NULL) { 284 if (environment != NULL) {
292 program_environment_ = reinterpret_cast<char**>(Dart_ScopeAllocate( 285 program_environment_ = reinterpret_cast<char**>(Dart_ScopeAllocate(
293 (environment_length + 1) * sizeof(*program_environment_))); 286 (environment_length + 1) * sizeof(*program_environment_)));
294 for (int i = 0; i < environment_length; i++) { 287 for (int i = 0; i < environment_length; i++) {
295 program_environment_[i] = environment[i]; 288 program_environment_[i] = environment[i];
296 } 289 }
297 program_environment_[environment_length] = NULL; 290 program_environment_[environment_length] = NULL;
298 } 291 }
299 } 292 }
300 293
301
302 int Start() { 294 int Start() {
303 // Create pipes required. 295 // Create pipes required.
304 int err = CreatePipes(); 296 int err = CreatePipes();
305 if (err != 0) { 297 if (err != 0) {
306 return err; 298 return err;
307 } 299 }
308 300
309 // Fork to create the new process. 301 // Fork to create the new process.
310 pid_t pid = TEMP_FAILURE_RETRY(fork()); 302 pid_t pid = TEMP_FAILURE_RETRY(fork());
311 if (pid < 0) { 303 if (pid < 0) {
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after
424 if (result < 0) { 416 if (result < 0) {
425 return CleanupAndReturnError(); 417 return CleanupAndReturnError();
426 } 418 }
427 FDUtils::SetCloseOnExec(write_out_[0]); 419 FDUtils::SetCloseOnExec(write_out_[0]);
428 FDUtils::SetCloseOnExec(write_out_[1]); 420 FDUtils::SetCloseOnExec(write_out_[1]);
429 } 421 }
430 422
431 return 0; 423 return 0;
432 } 424 }
433 425
434
435 void NewProcess() { 426 void NewProcess() {
436 // Wait for parent process before setting up the child process. 427 // Wait for parent process before setting up the child process.
437 char msg; 428 char msg;
438 int bytes_read = FDUtils::ReadFromBlocking(read_in_[0], &msg, sizeof(msg)); 429 int bytes_read = FDUtils::ReadFromBlocking(read_in_[0], &msg, sizeof(msg));
439 if (bytes_read != sizeof(msg)) { 430 if (bytes_read != sizeof(msg)) {
440 perror("Failed receiving notification message"); 431 perror("Failed receiving notification message");
441 exit(1); 432 exit(1);
442 } 433 }
443 if (mode_ == kNormal) { 434 if (mode_ == kNormal) {
444 ExecProcess(); 435 ExecProcess();
445 } else { 436 } else {
446 ExecDetachedProcess(); 437 ExecDetachedProcess();
447 } 438 }
448 } 439 }
449 440
450
451 void ExecProcess() { 441 void ExecProcess() {
452 if (TEMP_FAILURE_RETRY(dup2(write_out_[0], STDIN_FILENO)) == -1) { 442 if (TEMP_FAILURE_RETRY(dup2(write_out_[0], STDIN_FILENO)) == -1) {
453 ReportChildError(); 443 ReportChildError();
454 } 444 }
455 445
456 if (TEMP_FAILURE_RETRY(dup2(read_in_[1], STDOUT_FILENO)) == -1) { 446 if (TEMP_FAILURE_RETRY(dup2(read_in_[1], STDOUT_FILENO)) == -1) {
457 ReportChildError(); 447 ReportChildError();
458 } 448 }
459 449
460 if (TEMP_FAILURE_RETRY(dup2(read_err_[1], STDERR_FILENO)) == -1) { 450 if (TEMP_FAILURE_RETRY(dup2(read_err_[1], STDERR_FILENO)) == -1) {
(...skipping 13 matching lines...) Expand all
474 *environ = program_environment_; 464 *environ = program_environment_;
475 } 465 }
476 #endif 466 #endif
477 467
478 VOID_TEMP_FAILURE_RETRY( 468 VOID_TEMP_FAILURE_RETRY(
479 execvp(path_, const_cast<char* const*>(program_arguments_))); 469 execvp(path_, const_cast<char* const*>(program_arguments_)));
480 470
481 ReportChildError(); 471 ReportChildError();
482 } 472 }
483 473
484
485 void ExecDetachedProcess() { 474 void ExecDetachedProcess() {
486 if (mode_ == kDetached) { 475 if (mode_ == kDetached) {
487 ASSERT(write_out_[0] == -1); 476 ASSERT(write_out_[0] == -1);
488 ASSERT(write_out_[1] == -1); 477 ASSERT(write_out_[1] == -1);
489 ASSERT(read_err_[0] == -1); 478 ASSERT(read_err_[0] == -1);
490 ASSERT(read_err_[1] == -1); 479 ASSERT(read_err_[1] == -1);
491 // For a detached process the pipe to connect stdout is only used for 480 // For a detached process the pipe to connect stdout is only used for
492 // signaling when to do the first fork. 481 // signaling when to do the first fork.
493 VOID_TEMP_FAILURE_RETRY(close(read_in_[0])); 482 VOID_TEMP_FAILURE_RETRY(close(read_in_[0]));
494 read_in_[0] = -1; 483 read_in_[0] = -1;
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
532 // Exit the intermeiate process. 521 // Exit the intermeiate process.
533 exit(0); 522 exit(0);
534 } 523 }
535 } 524 }
536 } else { 525 } else {
537 // Exit the intermeiate process. 526 // Exit the intermeiate process.
538 exit(0); 527 exit(0);
539 } 528 }
540 } 529 }
541 530
542
543 int RegisterProcess(pid_t pid) { 531 int RegisterProcess(pid_t pid) {
544 int result; 532 int result;
545 int event_fds[2]; 533 int event_fds[2];
546 result = TEMP_FAILURE_RETRY(pipe(event_fds)); 534 result = TEMP_FAILURE_RETRY(pipe(event_fds));
547 if (result < 0) { 535 if (result < 0) {
548 return CleanupAndReturnError(); 536 return CleanupAndReturnError();
549 } 537 }
550 FDUtils::SetCloseOnExec(event_fds[0]); 538 FDUtils::SetCloseOnExec(event_fds[0]);
551 FDUtils::SetCloseOnExec(event_fds[1]); 539 FDUtils::SetCloseOnExec(event_fds[1]);
552 540
553 ProcessInfoList::AddProcess(pid, event_fds[1]); 541 ProcessInfoList::AddProcess(pid, event_fds[1]);
554 *exit_event_ = event_fds[0]; 542 *exit_event_ = event_fds[0];
555 FDUtils::SetNonBlocking(event_fds[0]); 543 FDUtils::SetNonBlocking(event_fds[0]);
556 return 0; 544 return 0;
557 } 545 }
558 546
559
560 int ReadExecResult() { 547 int ReadExecResult() {
561 int child_errno; 548 int child_errno;
562 int bytes_read = -1; 549 int bytes_read = -1;
563 // Read exec result from child. If no data is returned the exec was 550 // Read exec result from child. If no data is returned the exec was
564 // successful and the exec call closed the pipe. Otherwise the errno 551 // successful and the exec call closed the pipe. Otherwise the errno
565 // is written to the pipe. 552 // is written to the pipe.
566 bytes_read = FDUtils::ReadFromBlocking(exec_control_[0], &child_errno, 553 bytes_read = FDUtils::ReadFromBlocking(exec_control_[0], &child_errno,
567 sizeof(child_errno)); 554 sizeof(child_errno));
568 if (bytes_read == sizeof(child_errno)) { 555 if (bytes_read == sizeof(child_errno)) {
569 ReadChildError(); 556 ReadChildError();
570 return child_errno; 557 return child_errno;
571 } else if (bytes_read == -1) { 558 } else if (bytes_read == -1) {
572 return errno; 559 return errno;
573 } 560 }
574 return 0; 561 return 0;
575 } 562 }
576 563
577
578 int ReadDetachedExecResult(pid_t* pid) { 564 int ReadDetachedExecResult(pid_t* pid) {
579 int child_errno; 565 int child_errno;
580 int bytes_read = -1; 566 int bytes_read = -1;
581 // Read exec result from child. If only pid data is returned the exec was 567 // Read exec result from child. If only pid data is returned the exec was
582 // successful and the exec call closed the pipe. Otherwise the errno 568 // successful and the exec call closed the pipe. Otherwise the errno
583 // is written to the pipe as well. 569 // is written to the pipe as well.
584 int result[2]; 570 int result[2];
585 bytes_read = 571 bytes_read =
586 FDUtils::ReadFromBlocking(exec_control_[0], result, sizeof(result)); 572 FDUtils::ReadFromBlocking(exec_control_[0], result, sizeof(result));
587 if (bytes_read == sizeof(int)) { 573 if (bytes_read == sizeof(int)) {
588 *pid = result[0]; 574 *pid = result[0];
589 } else if (bytes_read == 2 * sizeof(int)) { 575 } else if (bytes_read == 2 * sizeof(int)) {
590 *pid = result[0]; 576 *pid = result[0];
591 child_errno = result[1]; 577 child_errno = result[1];
592 ReadChildError(); 578 ReadChildError();
593 return child_errno; 579 return child_errno;
594 } else if (bytes_read == -1) { 580 } else if (bytes_read == -1) {
595 return errno; 581 return errno;
596 } 582 }
597 return 0; 583 return 0;
598 } 584 }
599 585
600
601 void SetupDetached() { 586 void SetupDetached() {
602 ASSERT(mode_ == kDetached); 587 ASSERT(mode_ == kDetached);
603 588
604 // Close all open file descriptors except for exec_control_[1]. 589 // Close all open file descriptors except for exec_control_[1].
605 int max_fds = sysconf(_SC_OPEN_MAX); 590 int max_fds = sysconf(_SC_OPEN_MAX);
606 if (max_fds == -1) { 591 if (max_fds == -1) {
607 max_fds = _POSIX_OPEN_MAX; 592 max_fds = _POSIX_OPEN_MAX;
608 } 593 }
609 for (int fd = 0; fd < max_fds; fd++) { 594 for (int fd = 0; fd < max_fds; fd++) {
610 if (fd != exec_control_[1]) { 595 if (fd != exec_control_[1]) {
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
653 ReportChildError(); 638 ReportChildError();
654 } 639 }
655 VOID_TEMP_FAILURE_RETRY(close(read_in_[1])); 640 VOID_TEMP_FAILURE_RETRY(close(read_in_[1]));
656 641
657 if (TEMP_FAILURE_RETRY(dup2(read_err_[1], STDERR_FILENO)) == -1) { 642 if (TEMP_FAILURE_RETRY(dup2(read_err_[1], STDERR_FILENO)) == -1) {
658 ReportChildError(); 643 ReportChildError();
659 } 644 }
660 VOID_TEMP_FAILURE_RETRY(close(read_err_[1])); 645 VOID_TEMP_FAILURE_RETRY(close(read_err_[1]));
661 } 646 }
662 647
663
664 int CleanupAndReturnError() { 648 int CleanupAndReturnError() {
665 int actual_errno = errno; 649 int actual_errno = errno;
666 // If CleanupAndReturnError is called without an actual errno make 650 // If CleanupAndReturnError is called without an actual errno make
667 // sure to return an error anyway. 651 // sure to return an error anyway.
668 if (actual_errno == 0) { 652 if (actual_errno == 0) {
669 actual_errno = EPERM; 653 actual_errno = EPERM;
670 } 654 }
671 SetChildOsErrorMessage(); 655 SetChildOsErrorMessage();
672 CloseAllPipes(); 656 CloseAllPipes();
673 return actual_errno; 657 return actual_errno;
674 } 658 }
675 659
676
677 void SetChildOsErrorMessage() { 660 void SetChildOsErrorMessage() {
678 const int kBufferSize = 1024; 661 const int kBufferSize = 1024;
679 char* error_message = DartUtils::ScopedCString(kBufferSize); 662 char* error_message = DartUtils::ScopedCString(kBufferSize);
680 Utils::StrError(errno, error_message, kBufferSize); 663 Utils::StrError(errno, error_message, kBufferSize);
681 *os_error_message_ = error_message; 664 *os_error_message_ = error_message;
682 } 665 }
683 666
684
685 void ReportChildError() { 667 void ReportChildError() {
686 // In the case of failure in the child process write the errno and 668 // In the case of failure in the child process write the errno and
687 // the OS error message to the exec control pipe and exit. 669 // the OS error message to the exec control pipe and exit.
688 int child_errno = errno; 670 int child_errno = errno;
689 const int kBufferSize = 1024; 671 const int kBufferSize = 1024;
690 char os_error_message[kBufferSize]; 672 char os_error_message[kBufferSize];
691 Utils::StrError(errno, os_error_message, kBufferSize); 673 Utils::StrError(errno, os_error_message, kBufferSize);
692 int bytes_written = FDUtils::WriteToBlocking(exec_control_[1], &child_errno, 674 int bytes_written = FDUtils::WriteToBlocking(exec_control_[1], &child_errno,
693 sizeof(child_errno)); 675 sizeof(child_errno));
694 if (bytes_written == sizeof(child_errno)) { 676 if (bytes_written == sizeof(child_errno)) {
695 FDUtils::WriteToBlocking(exec_control_[1], os_error_message, 677 FDUtils::WriteToBlocking(exec_control_[1], os_error_message,
696 strlen(os_error_message) + 1); 678 strlen(os_error_message) + 1);
697 } 679 }
698 VOID_TEMP_FAILURE_RETRY(close(exec_control_[1])); 680 VOID_TEMP_FAILURE_RETRY(close(exec_control_[1]));
699 exit(1); 681 exit(1);
700 } 682 }
701 683
702
703 void ReportPid(int pid) { 684 void ReportPid(int pid) {
704 // In the case of starting a detached process the actual pid of that process 685 // In the case of starting a detached process the actual pid of that process
705 // is communicated using the exec control pipe. 686 // is communicated using the exec control pipe.
706 int bytes_written = 687 int bytes_written =
707 FDUtils::WriteToBlocking(exec_control_[1], &pid, sizeof(pid)); 688 FDUtils::WriteToBlocking(exec_control_[1], &pid, sizeof(pid));
708 ASSERT(bytes_written == sizeof(int)); 689 ASSERT(bytes_written == sizeof(int));
709 USE(bytes_written); 690 USE(bytes_written);
710 } 691 }
711 692
712
713 void ReadChildError() { 693 void ReadChildError() {
714 const int kMaxMessageSize = 256; 694 const int kMaxMessageSize = 256;
715 char* message = DartUtils::ScopedCString(kMaxMessageSize); 695 char* message = DartUtils::ScopedCString(kMaxMessageSize);
716 if (message != NULL) { 696 if (message != NULL) {
717 FDUtils::ReadFromBlocking(exec_control_[0], message, kMaxMessageSize); 697 FDUtils::ReadFromBlocking(exec_control_[0], message, kMaxMessageSize);
718 message[kMaxMessageSize - 1] = '\0'; 698 message[kMaxMessageSize - 1] = '\0';
719 *os_error_message_ = message; 699 *os_error_message_ = message;
720 } else { 700 } else {
721 // Could not get error message. It will be NULL. 701 // Could not get error message. It will be NULL.
722 ASSERT(*os_error_message_ == NULL); 702 ASSERT(*os_error_message_ == NULL);
723 } 703 }
724 } 704 }
725 705
726
727 void ClosePipe(int* fds) { 706 void ClosePipe(int* fds) {
728 for (int i = 0; i < 2; i++) { 707 for (int i = 0; i < 2; i++) {
729 if (fds[i] != -1) { 708 if (fds[i] != -1) {
730 VOID_TEMP_FAILURE_RETRY(close(fds[i])); 709 VOID_TEMP_FAILURE_RETRY(close(fds[i]));
731 fds[i] = -1; 710 fds[i] = -1;
732 } 711 }
733 } 712 }
734 } 713 }
735 714
736
737 void CloseAllPipes() { 715 void CloseAllPipes() {
738 ClosePipe(exec_control_); 716 ClosePipe(exec_control_);
739 ClosePipe(read_in_); 717 ClosePipe(read_in_);
740 ClosePipe(read_err_); 718 ClosePipe(read_err_);
741 ClosePipe(write_out_); 719 ClosePipe(write_out_);
742 } 720 }
743 721
744
745 int read_in_[2]; // Pipe for stdout to child process. 722 int read_in_[2]; // Pipe for stdout to child process.
746 int read_err_[2]; // Pipe for stderr to child process. 723 int read_err_[2]; // Pipe for stderr to child process.
747 int write_out_[2]; // Pipe for stdin to child process. 724 int write_out_[2]; // Pipe for stdin to child process.
748 int exec_control_[2]; // Pipe to get the result from exec. 725 int exec_control_[2]; // Pipe to get the result from exec.
749 726
750 char** program_arguments_; 727 char** program_arguments_;
751 char** program_environment_; 728 char** program_environment_;
752 729
753 const char* path_; 730 const char* path_;
754 const char* working_directory_; 731 const char* working_directory_;
755 ProcessStartMode mode_; 732 ProcessStartMode mode_;
756 intptr_t* in_; 733 intptr_t* in_;
757 intptr_t* out_; 734 intptr_t* out_;
758 intptr_t* err_; 735 intptr_t* err_;
759 intptr_t* id_; 736 intptr_t* id_;
760 intptr_t* exit_event_; 737 intptr_t* exit_event_;
761 char** os_error_message_; 738 char** os_error_message_;
762 739
763 DISALLOW_ALLOCATION(); 740 DISALLOW_ALLOCATION();
764 DISALLOW_IMPLICIT_CONSTRUCTORS(ProcessStarter); 741 DISALLOW_IMPLICIT_CONSTRUCTORS(ProcessStarter);
765 }; 742 };
766 743
767
768 int Process::Start(const char* path, 744 int Process::Start(const char* path,
769 char* arguments[], 745 char* arguments[],
770 intptr_t arguments_length, 746 intptr_t arguments_length,
771 const char* working_directory, 747 const char* working_directory,
772 char* environment[], 748 char* environment[],
773 intptr_t environment_length, 749 intptr_t environment_length,
774 ProcessStartMode mode, 750 ProcessStartMode mode,
775 intptr_t* in, 751 intptr_t* in,
776 intptr_t* out, 752 intptr_t* out,
777 intptr_t* err, 753 intptr_t* err,
778 intptr_t* id, 754 intptr_t* id,
779 intptr_t* exit_event, 755 intptr_t* exit_event,
780 char** os_error_message) { 756 char** os_error_message) {
781 ProcessStarter starter(path, arguments, arguments_length, working_directory, 757 ProcessStarter starter(path, arguments, arguments_length, working_directory,
782 environment, environment_length, mode, in, out, err, 758 environment, environment_length, mode, in, out, err,
783 id, exit_event, os_error_message); 759 id, exit_event, os_error_message);
784 return starter.Start(); 760 return starter.Start();
785 } 761 }
786 762
787
788 static bool CloseProcessBuffers(struct pollfd fds[3]) { 763 static bool CloseProcessBuffers(struct pollfd fds[3]) {
789 int e = errno; 764 int e = errno;
790 VOID_TEMP_FAILURE_RETRY(close(fds[0].fd)); 765 VOID_TEMP_FAILURE_RETRY(close(fds[0].fd));
791 VOID_TEMP_FAILURE_RETRY(close(fds[1].fd)); 766 VOID_TEMP_FAILURE_RETRY(close(fds[1].fd));
792 VOID_TEMP_FAILURE_RETRY(close(fds[2].fd)); 767 VOID_TEMP_FAILURE_RETRY(close(fds[2].fd));
793 errno = e; 768 errno = e;
794 return false; 769 return false;
795 } 770 }
796 771
797
798 bool Process::Wait(intptr_t pid, 772 bool Process::Wait(intptr_t pid,
799 intptr_t in, 773 intptr_t in,
800 intptr_t out, 774 intptr_t out,
801 intptr_t err, 775 intptr_t err,
802 intptr_t exit_event, 776 intptr_t exit_event,
803 ProcessResult* result) { 777 ProcessResult* result) {
804 // Close input to the process right away. 778 // Close input to the process right away.
805 VOID_TEMP_FAILURE_RETRY(close(in)); 779 VOID_TEMP_FAILURE_RETRY(close(in));
806 780
807 // There is no return from this function using Dart_PropagateError 781 // There is no return from this function using Dart_PropagateError
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
881 intptr_t exit_code = exit_code_data.ints[0]; 855 intptr_t exit_code = exit_code_data.ints[0];
882 intptr_t negative = exit_code_data.ints[1]; 856 intptr_t negative = exit_code_data.ints[1];
883 if (negative != 0) { 857 if (negative != 0) {
884 exit_code = -exit_code; 858 exit_code = -exit_code;
885 } 859 }
886 result->set_exit_code(exit_code); 860 result->set_exit_code(exit_code);
887 861
888 return true; 862 return true;
889 } 863 }
890 864
891
892 static int SignalMap(intptr_t id) { 865 static int SignalMap(intptr_t id) {
893 switch (static_cast<ProcessSignals>(id)) { 866 switch (static_cast<ProcessSignals>(id)) {
894 case kSighup: 867 case kSighup:
895 return SIGHUP; 868 return SIGHUP;
896 case kSigint: 869 case kSigint:
897 return SIGINT; 870 return SIGINT;
898 case kSigquit: 871 case kSigquit:
899 return SIGQUIT; 872 return SIGQUIT;
900 case kSigill: 873 case kSigill:
901 return SIGILL; 874 return SIGILL;
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
946 case kSigwinch: 919 case kSigwinch:
947 return SIGWINCH; 920 return SIGWINCH;
948 case kSigpoll: 921 case kSigpoll:
949 return -1; 922 return -1;
950 case kSigsys: 923 case kSigsys:
951 return SIGSYS; 924 return SIGSYS;
952 } 925 }
953 return -1; 926 return -1;
954 } 927 }
955 928
956
957 bool Process::Kill(intptr_t id, int signal) { 929 bool Process::Kill(intptr_t id, int signal) {
958 return (TEMP_FAILURE_RETRY(kill(id, SignalMap(signal))) != -1); 930 return (TEMP_FAILURE_RETRY(kill(id, SignalMap(signal))) != -1);
959 } 931 }
960 932
961
962 void Process::TerminateExitCodeHandler() { 933 void Process::TerminateExitCodeHandler() {
963 ExitCodeHandler::TerminateExitCodeThread(); 934 ExitCodeHandler::TerminateExitCodeThread();
964 } 935 }
965 936
966
967 intptr_t Process::CurrentProcessId() { 937 intptr_t Process::CurrentProcessId() {
968 return static_cast<intptr_t>(getpid()); 938 return static_cast<intptr_t>(getpid());
969 } 939 }
970 940
971
972 int64_t Process::CurrentRSS() { 941 int64_t Process::CurrentRSS() {
973 struct mach_task_basic_info info; 942 struct mach_task_basic_info info;
974 mach_msg_type_number_t infoCount = MACH_TASK_BASIC_INFO_COUNT; 943 mach_msg_type_number_t infoCount = MACH_TASK_BASIC_INFO_COUNT;
975 kern_return_t result = 944 kern_return_t result =
976 task_info(mach_task_self(), MACH_TASK_BASIC_INFO, 945 task_info(mach_task_self(), MACH_TASK_BASIC_INFO,
977 reinterpret_cast<task_info_t>(&info), &infoCount); 946 reinterpret_cast<task_info_t>(&info), &infoCount);
978 if (result != KERN_SUCCESS) { 947 if (result != KERN_SUCCESS) {
979 return -1; 948 return -1;
980 } 949 }
981 return info.resident_size; 950 return info.resident_size;
982 } 951 }
983 952
984
985 int64_t Process::MaxRSS() { 953 int64_t Process::MaxRSS() {
986 struct rusage usage; 954 struct rusage usage;
987 usage.ru_maxrss = 0; 955 usage.ru_maxrss = 0;
988 int r = getrusage(RUSAGE_SELF, &usage); 956 int r = getrusage(RUSAGE_SELF, &usage);
989 if (r < 0) { 957 if (r < 0) {
990 return -1; 958 return -1;
991 } 959 }
992 return usage.ru_maxrss; 960 return usage.ru_maxrss;
993 } 961 }
994 962
995
996 static Mutex* signal_mutex = new Mutex(); 963 static Mutex* signal_mutex = new Mutex();
997 static SignalInfo* signal_handlers = NULL; 964 static SignalInfo* signal_handlers = NULL;
998 static const int kSignalsCount = 7; 965 static const int kSignalsCount = 7;
999 static const int kSignals[kSignalsCount] = { 966 static const int kSignals[kSignalsCount] = {
1000 SIGHUP, SIGINT, SIGTERM, SIGUSR1, SIGUSR2, SIGWINCH, 967 SIGHUP, SIGINT, SIGTERM, SIGUSR1, SIGUSR2, SIGWINCH,
1001 SIGQUIT // Allow VMService to listen on SIGQUIT. 968 SIGQUIT // Allow VMService to listen on SIGQUIT.
1002 }; 969 };
1003 970
1004
1005 SignalInfo::~SignalInfo() { 971 SignalInfo::~SignalInfo() {
1006 VOID_TEMP_FAILURE_RETRY(close(fd_)); 972 VOID_TEMP_FAILURE_RETRY(close(fd_));
1007 } 973 }
1008 974
1009
1010 static void SignalHandler(int signal) { 975 static void SignalHandler(int signal) {
1011 MutexLocker lock(signal_mutex); 976 MutexLocker lock(signal_mutex);
1012 const SignalInfo* handler = signal_handlers; 977 const SignalInfo* handler = signal_handlers;
1013 while (handler != NULL) { 978 while (handler != NULL) {
1014 if (handler->signal() == signal) { 979 if (handler->signal() == signal) {
1015 int value = 0; 980 int value = 0;
1016 VOID_TEMP_FAILURE_RETRY(write(handler->fd(), &value, 1)); 981 VOID_TEMP_FAILURE_RETRY(write(handler->fd(), &value, 1));
1017 } 982 }
1018 handler = handler->next(); 983 handler = handler->next();
1019 } 984 }
1020 } 985 }
1021 986
1022
1023 intptr_t Process::SetSignalHandler(intptr_t signal) { 987 intptr_t Process::SetSignalHandler(intptr_t signal) {
1024 signal = SignalMap(signal); 988 signal = SignalMap(signal);
1025 if (signal == -1) { 989 if (signal == -1) {
1026 return -1; 990 return -1;
1027 } 991 }
1028 bool found = false; 992 bool found = false;
1029 for (int i = 0; i < kSignalsCount; i++) { 993 for (int i = 0; i < kSignalsCount; i++) {
1030 if (kSignals[i] == signal) { 994 if (kSignals[i] == signal) {
1031 found = true; 995 found = true;
1032 break; 996 break;
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
1068 if (status < 0) { 1032 if (status < 0) {
1069 VOID_TEMP_FAILURE_RETRY(close(fds[0])); 1033 VOID_TEMP_FAILURE_RETRY(close(fds[0]));
1070 VOID_TEMP_FAILURE_RETRY(close(fds[1])); 1034 VOID_TEMP_FAILURE_RETRY(close(fds[1]));
1071 return -1; 1035 return -1;
1072 } 1036 }
1073 } 1037 }
1074 signal_handlers = new SignalInfo(fds[1], signal, signal_handlers); 1038 signal_handlers = new SignalInfo(fds[1], signal, signal_handlers);
1075 return fds[0]; 1039 return fds[0];
1076 } 1040 }
1077 1041
1078
1079 void Process::ClearSignalHandler(intptr_t signal, Dart_Port port) { 1042 void Process::ClearSignalHandler(intptr_t signal, Dart_Port port) {
1080 // Either the port is illegal or there is no current isolate, but not both. 1043 // Either the port is illegal or there is no current isolate, but not both.
1081 ASSERT((port != ILLEGAL_PORT) || (Dart_CurrentIsolate() == NULL)); 1044 ASSERT((port != ILLEGAL_PORT) || (Dart_CurrentIsolate() == NULL));
1082 ASSERT((port == ILLEGAL_PORT) || (Dart_CurrentIsolate() != NULL)); 1045 ASSERT((port == ILLEGAL_PORT) || (Dart_CurrentIsolate() != NULL));
1083 signal = SignalMap(signal); 1046 signal = SignalMap(signal);
1084 if (signal == -1) { 1047 if (signal == -1) {
1085 return; 1048 return;
1086 } 1049 }
1087 ThreadSignalBlocker blocker(kSignalsCount, kSignals); 1050 ThreadSignalBlocker blocker(kSignalsCount, kSignals);
1088 MutexLocker lock(signal_mutex); 1051 MutexLocker lock(signal_mutex);
(...skipping 25 matching lines...) Expand all
1114 VOID_NO_RETRY_EXPECTED(sigaction(signal, &act, NULL)); 1077 VOID_NO_RETRY_EXPECTED(sigaction(signal, &act, NULL));
1115 } 1078 }
1116 } 1079 }
1117 1080
1118 } // namespace bin 1081 } // namespace bin
1119 } // namespace dart 1082 } // namespace dart
1120 1083
1121 #endif // defined(HOST_OS_MACOS) 1084 #endif // defined(HOST_OS_MACOS)
1122 1085
1123 #endif // !defined(DART_IO_DISABLED) 1086 #endif // !defined(DART_IO_DISABLED)
OLDNEW
« no previous file with comments | « runtime/bin/process_linux.cc ('k') | runtime/bin/process_unsupported.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698