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

Side by Side Diff: runtime/bin/process_android.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.cc ('k') | runtime/bin/process_fuchsia.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_ANDROID) 8 #if defined(HOST_OS_ANDROID)
9 9
10 #include "bin/process.h" 10 #include "bin/process.h"
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
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 96 matching lines...) Expand 10 before | Expand all | Expand 10 after
235 230
236 static bool terminate_done_; 231 static bool terminate_done_;
237 static int process_count_; 232 static int process_count_;
238 static bool running_; 233 static bool running_;
239 static Monitor* monitor_; 234 static Monitor* monitor_;
240 235
241 DISALLOW_ALLOCATION(); 236 DISALLOW_ALLOCATION();
242 DISALLOW_IMPLICIT_CONSTRUCTORS(ExitCodeHandler); 237 DISALLOW_IMPLICIT_CONSTRUCTORS(ExitCodeHandler);
243 }; 238 };
244 239
245
246 bool ExitCodeHandler::running_ = false; 240 bool ExitCodeHandler::running_ = false;
247 int ExitCodeHandler::process_count_ = 0; 241 int ExitCodeHandler::process_count_ = 0;
248 bool ExitCodeHandler::terminate_done_ = false; 242 bool ExitCodeHandler::terminate_done_ = false;
249 Monitor* ExitCodeHandler::monitor_ = new Monitor(); 243 Monitor* ExitCodeHandler::monitor_ = new Monitor();
250 244
251
252 class ProcessStarter { 245 class ProcessStarter {
253 public: 246 public:
254 ProcessStarter(const char* path, 247 ProcessStarter(const char* path,
255 char* arguments[], 248 char* arguments[],
256 intptr_t arguments_length, 249 intptr_t arguments_length,
257 const char* working_directory, 250 const char* working_directory,
258 char* environment[], 251 char* environment[],
259 intptr_t environment_length, 252 intptr_t environment_length,
260 ProcessStartMode mode, 253 ProcessStartMode mode,
261 intptr_t* in, 254 intptr_t* in,
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
294 if (environment != NULL) { 287 if (environment != NULL) {
295 program_environment_ = reinterpret_cast<char**>(Dart_ScopeAllocate( 288 program_environment_ = reinterpret_cast<char**>(Dart_ScopeAllocate(
296 (environment_length + 1) * sizeof(*program_environment_))); 289 (environment_length + 1) * sizeof(*program_environment_)));
297 for (int i = 0; i < environment_length; i++) { 290 for (int i = 0; i < environment_length; i++) {
298 program_environment_[i] = environment[i]; 291 program_environment_[i] = environment[i];
299 } 292 }
300 program_environment_[environment_length] = NULL; 293 program_environment_[environment_length] = NULL;
301 } 294 }
302 } 295 }
303 296
304
305 int Start() { 297 int Start() {
306 // Create pipes required. 298 // Create pipes required.
307 int err = CreatePipes(); 299 int err = CreatePipes();
308 if (err != 0) { 300 if (err != 0) {
309 return err; 301 return err;
310 } 302 }
311 303
312 // Fork to create the new process. 304 // Fork to create the new process.
313 pid_t pid = TEMP_FAILURE_RETRY(fork()); 305 pid_t pid = TEMP_FAILURE_RETRY(fork());
314 if (pid < 0) { 306 if (pid < 0) {
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after
419 411
420 result = TEMP_FAILURE_RETRY(pipe2(write_out_, O_CLOEXEC)); 412 result = TEMP_FAILURE_RETRY(pipe2(write_out_, O_CLOEXEC));
421 if (result < 0) { 413 if (result < 0) {
422 return CleanupAndReturnError(); 414 return CleanupAndReturnError();
423 } 415 }
424 } 416 }
425 417
426 return 0; 418 return 0;
427 } 419 }
428 420
429
430 void NewProcess() { 421 void NewProcess() {
431 // Wait for parent process before setting up the child process. 422 // Wait for parent process before setting up the child process.
432 char msg; 423 char msg;
433 int bytes_read = FDUtils::ReadFromBlocking(read_in_[0], &msg, sizeof(msg)); 424 int bytes_read = FDUtils::ReadFromBlocking(read_in_[0], &msg, sizeof(msg));
434 if (bytes_read != sizeof(msg)) { 425 if (bytes_read != sizeof(msg)) {
435 perror("Failed receiving notification message"); 426 perror("Failed receiving notification message");
436 exit(1); 427 exit(1);
437 } 428 }
438 if (mode_ == kNormal) { 429 if (mode_ == kNormal) {
439 ExecProcess(); 430 ExecProcess();
440 } else { 431 } else {
441 ExecDetachedProcess(); 432 ExecDetachedProcess();
442 } 433 }
443 } 434 }
444 435
445
446 void ExecProcess() { 436 void ExecProcess() {
447 if (TEMP_FAILURE_RETRY(dup2(write_out_[0], STDIN_FILENO)) == -1) { 437 if (TEMP_FAILURE_RETRY(dup2(write_out_[0], STDIN_FILENO)) == -1) {
448 ReportChildError(); 438 ReportChildError();
449 } 439 }
450 440
451 if (TEMP_FAILURE_RETRY(dup2(read_in_[1], STDOUT_FILENO)) == -1) { 441 if (TEMP_FAILURE_RETRY(dup2(read_in_[1], STDOUT_FILENO)) == -1) {
452 ReportChildError(); 442 ReportChildError();
453 } 443 }
454 444
455 if (TEMP_FAILURE_RETRY(dup2(read_err_[1], STDERR_FILENO)) == -1) { 445 if (TEMP_FAILURE_RETRY(dup2(read_err_[1], STDERR_FILENO)) == -1) {
456 ReportChildError(); 446 ReportChildError();
457 } 447 }
458 448
459 if (working_directory_ != NULL && 449 if (working_directory_ != NULL &&
460 TEMP_FAILURE_RETRY(chdir(working_directory_)) == -1) { 450 TEMP_FAILURE_RETRY(chdir(working_directory_)) == -1) {
461 ReportChildError(); 451 ReportChildError();
462 } 452 }
463 453
464 if (program_environment_ != NULL) { 454 if (program_environment_ != NULL) {
465 environ = program_environment_; 455 environ = program_environment_;
466 } 456 }
467 457
468 VOID_TEMP_FAILURE_RETRY( 458 VOID_TEMP_FAILURE_RETRY(
469 execvp(path_, const_cast<char* const*>(program_arguments_))); 459 execvp(path_, const_cast<char* const*>(program_arguments_)));
470 460
471 ReportChildError(); 461 ReportChildError();
472 } 462 }
473 463
474
475 void ExecDetachedProcess() { 464 void ExecDetachedProcess() {
476 if (mode_ == kDetached) { 465 if (mode_ == kDetached) {
477 ASSERT(write_out_[0] == -1); 466 ASSERT(write_out_[0] == -1);
478 ASSERT(write_out_[1] == -1); 467 ASSERT(write_out_[1] == -1);
479 ASSERT(read_err_[0] == -1); 468 ASSERT(read_err_[0] == -1);
480 ASSERT(read_err_[1] == -1); 469 ASSERT(read_err_[1] == -1);
481 // For a detached process the pipe to connect stdout is only used for 470 // For a detached process the pipe to connect stdout is only used for
482 // signaling when to do the first fork. 471 // signaling when to do the first fork.
483 VOID_TEMP_FAILURE_RETRY(close(read_in_[0])); 472 VOID_TEMP_FAILURE_RETRY(close(read_in_[0]));
484 read_in_[0] = -1; 473 read_in_[0] = -1;
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
522 // Exit the intermediate process. 511 // Exit the intermediate process.
523 exit(0); 512 exit(0);
524 } 513 }
525 } 514 }
526 } else { 515 } else {
527 // Exit the intermediate process. 516 // Exit the intermediate process.
528 exit(0); 517 exit(0);
529 } 518 }
530 } 519 }
531 520
532
533 int RegisterProcess(pid_t pid) { 521 int RegisterProcess(pid_t pid) {
534 int result; 522 int result;
535 int event_fds[2]; 523 int event_fds[2];
536 result = TEMP_FAILURE_RETRY(pipe2(event_fds, O_CLOEXEC)); 524 result = TEMP_FAILURE_RETRY(pipe2(event_fds, O_CLOEXEC));
537 if (result < 0) { 525 if (result < 0) {
538 return CleanupAndReturnError(); 526 return CleanupAndReturnError();
539 } 527 }
540 528
541 ProcessInfoList::AddProcess(pid, event_fds[1]); 529 ProcessInfoList::AddProcess(pid, event_fds[1]);
542 *exit_event_ = event_fds[0]; 530 *exit_event_ = event_fds[0];
543 FDUtils::SetNonBlocking(event_fds[0]); 531 FDUtils::SetNonBlocking(event_fds[0]);
544 return 0; 532 return 0;
545 } 533 }
546 534
547
548 int ReadExecResult() { 535 int ReadExecResult() {
549 int child_errno; 536 int child_errno;
550 int bytes_read = -1; 537 int bytes_read = -1;
551 // Read exec result from child. If no data is returned the exec was 538 // Read exec result from child. If no data is returned the exec was
552 // successful and the exec call closed the pipe. Otherwise the errno 539 // successful and the exec call closed the pipe. Otherwise the errno
553 // is written to the pipe. 540 // is written to the pipe.
554 bytes_read = FDUtils::ReadFromBlocking(exec_control_[0], &child_errno, 541 bytes_read = FDUtils::ReadFromBlocking(exec_control_[0], &child_errno,
555 sizeof(child_errno)); 542 sizeof(child_errno));
556 if (bytes_read == sizeof(child_errno)) { 543 if (bytes_read == sizeof(child_errno)) {
557 ReadChildError(); 544 ReadChildError();
558 return child_errno; 545 return child_errno;
559 } else if (bytes_read == -1) { 546 } else if (bytes_read == -1) {
560 return errno; 547 return errno;
561 } 548 }
562 return 0; 549 return 0;
563 } 550 }
564 551
565
566 int ReadDetachedExecResult(pid_t* pid) { 552 int ReadDetachedExecResult(pid_t* pid) {
567 int child_errno; 553 int child_errno;
568 int bytes_read = -1; 554 int bytes_read = -1;
569 // Read exec result from child. If only pid data is returned the exec was 555 // Read exec result from child. If only pid data is returned the exec was
570 // successful and the exec call closed the pipe. Otherwise the errno 556 // successful and the exec call closed the pipe. Otherwise the errno
571 // is written to the pipe as well. 557 // is written to the pipe as well.
572 int result[2]; 558 int result[2];
573 bytes_read = 559 bytes_read =
574 FDUtils::ReadFromBlocking(exec_control_[0], result, sizeof(result)); 560 FDUtils::ReadFromBlocking(exec_control_[0], result, sizeof(result));
575 if (bytes_read == sizeof(int)) { 561 if (bytes_read == sizeof(int)) {
576 *pid = result[0]; 562 *pid = result[0];
577 } else if (bytes_read == 2 * sizeof(int)) { 563 } else if (bytes_read == 2 * sizeof(int)) {
578 *pid = result[0]; 564 *pid = result[0];
579 child_errno = result[1]; 565 child_errno = result[1];
580 ReadChildError(); 566 ReadChildError();
581 return child_errno; 567 return child_errno;
582 } else if (bytes_read == -1) { 568 } else if (bytes_read == -1) {
583 return errno; 569 return errno;
584 } 570 }
585 return 0; 571 return 0;
586 } 572 }
587 573
588
589 void SetupDetached() { 574 void SetupDetached() {
590 ASSERT(mode_ == kDetached); 575 ASSERT(mode_ == kDetached);
591 576
592 // Close all open file descriptors except for exec_control_[1]. 577 // Close all open file descriptors except for exec_control_[1].
593 int max_fds = sysconf(_SC_OPEN_MAX); 578 int max_fds = sysconf(_SC_OPEN_MAX);
594 if (max_fds == -1) { 579 if (max_fds == -1) {
595 max_fds = _POSIX_OPEN_MAX; 580 max_fds = _POSIX_OPEN_MAX;
596 } 581 }
597 for (int fd = 0; fd < max_fds; fd++) { 582 for (int fd = 0; fd < max_fds; fd++) {
598 if (fd != exec_control_[1]) { 583 if (fd != exec_control_[1]) {
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
641 ReportChildError(); 626 ReportChildError();
642 } 627 }
643 VOID_TEMP_FAILURE_RETRY(close(read_in_[1])); 628 VOID_TEMP_FAILURE_RETRY(close(read_in_[1]));
644 629
645 if (TEMP_FAILURE_RETRY(dup2(read_err_[1], STDERR_FILENO)) == -1) { 630 if (TEMP_FAILURE_RETRY(dup2(read_err_[1], STDERR_FILENO)) == -1) {
646 ReportChildError(); 631 ReportChildError();
647 } 632 }
648 VOID_TEMP_FAILURE_RETRY(close(read_err_[1])); 633 VOID_TEMP_FAILURE_RETRY(close(read_err_[1]));
649 } 634 }
650 635
651
652 int CleanupAndReturnError() { 636 int CleanupAndReturnError() {
653 int actual_errno = errno; 637 int actual_errno = errno;
654 // If CleanupAndReturnError is called without an actual errno make 638 // If CleanupAndReturnError is called without an actual errno make
655 // sure to return an error anyway. 639 // sure to return an error anyway.
656 if (actual_errno == 0) { 640 if (actual_errno == 0) {
657 actual_errno = EPERM; 641 actual_errno = EPERM;
658 } 642 }
659 SetChildOsErrorMessage(); 643 SetChildOsErrorMessage();
660 CloseAllPipes(); 644 CloseAllPipes();
661 return actual_errno; 645 return actual_errno;
662 } 646 }
663 647
664
665 void SetChildOsErrorMessage() { 648 void SetChildOsErrorMessage() {
666 const int kBufferSize = 1024; 649 const int kBufferSize = 1024;
667 char* error_message = DartUtils::ScopedCString(kBufferSize); 650 char* error_message = DartUtils::ScopedCString(kBufferSize);
668 Utils::StrError(errno, error_message, kBufferSize); 651 Utils::StrError(errno, error_message, kBufferSize);
669 *os_error_message_ = error_message; 652 *os_error_message_ = error_message;
670 } 653 }
671 654
672
673 void ReportChildError() { 655 void ReportChildError() {
674 // In the case of failure in the child process write the errno and 656 // In the case of failure in the child process write the errno and
675 // the OS error message to the exec control pipe and exit. 657 // the OS error message to the exec control pipe and exit.
676 int child_errno = errno; 658 int child_errno = errno;
677 const int kBufferSize = 1024; 659 const int kBufferSize = 1024;
678 char os_error_message[kBufferSize]; 660 char os_error_message[kBufferSize];
679 Utils::StrError(errno, os_error_message, kBufferSize); 661 Utils::StrError(errno, os_error_message, kBufferSize);
680 int bytes_written = FDUtils::WriteToBlocking(exec_control_[1], &child_errno, 662 int bytes_written = FDUtils::WriteToBlocking(exec_control_[1], &child_errno,
681 sizeof(child_errno)); 663 sizeof(child_errno));
682 if (bytes_written == sizeof(child_errno)) { 664 if (bytes_written == sizeof(child_errno)) {
683 FDUtils::WriteToBlocking(exec_control_[1], os_error_message, 665 FDUtils::WriteToBlocking(exec_control_[1], os_error_message,
684 strlen(os_error_message) + 1); 666 strlen(os_error_message) + 1);
685 } 667 }
686 VOID_TEMP_FAILURE_RETRY(close(exec_control_[1])); 668 VOID_TEMP_FAILURE_RETRY(close(exec_control_[1]));
687 669
688 // We avoid running through registered atexit() handlers because that is 670 // We avoid running through registered atexit() handlers because that is
689 // unnecessary work. 671 // unnecessary work.
690 _exit(1); 672 _exit(1);
691 } 673 }
692 674
693
694 void ReportPid(int pid) { 675 void ReportPid(int pid) {
695 // In the case of starting a detached process the actual pid of that process 676 // In the case of starting a detached process the actual pid of that process
696 // is communicated using the exec control pipe. 677 // is communicated using the exec control pipe.
697 int bytes_written = 678 int bytes_written =
698 FDUtils::WriteToBlocking(exec_control_[1], &pid, sizeof(pid)); 679 FDUtils::WriteToBlocking(exec_control_[1], &pid, sizeof(pid));
699 ASSERT(bytes_written == sizeof(int)); 680 ASSERT(bytes_written == sizeof(int));
700 USE(bytes_written); 681 USE(bytes_written);
701 } 682 }
702 683
703
704 void ReadChildError() { 684 void ReadChildError() {
705 const int kMaxMessageSize = 256; 685 const int kMaxMessageSize = 256;
706 char* message = DartUtils::ScopedCString(kMaxMessageSize); 686 char* message = DartUtils::ScopedCString(kMaxMessageSize);
707 if (message != NULL) { 687 if (message != NULL) {
708 FDUtils::ReadFromBlocking(exec_control_[0], message, kMaxMessageSize); 688 FDUtils::ReadFromBlocking(exec_control_[0], message, kMaxMessageSize);
709 message[kMaxMessageSize - 1] = '\0'; 689 message[kMaxMessageSize - 1] = '\0';
710 *os_error_message_ = message; 690 *os_error_message_ = message;
711 } else { 691 } else {
712 // Could not get error message. It will be NULL. 692 // Could not get error message. It will be NULL.
713 ASSERT(*os_error_message_ == NULL); 693 ASSERT(*os_error_message_ == NULL);
714 } 694 }
715 } 695 }
716 696
717
718 void ClosePipe(int* fds) { 697 void ClosePipe(int* fds) {
719 for (int i = 0; i < 2; i++) { 698 for (int i = 0; i < 2; i++) {
720 if (fds[i] != -1) { 699 if (fds[i] != -1) {
721 VOID_TEMP_FAILURE_RETRY(close(fds[i])); 700 VOID_TEMP_FAILURE_RETRY(close(fds[i]));
722 fds[i] = -1; 701 fds[i] = -1;
723 } 702 }
724 } 703 }
725 } 704 }
726 705
727
728 void CloseAllPipes() { 706 void CloseAllPipes() {
729 ClosePipe(exec_control_); 707 ClosePipe(exec_control_);
730 ClosePipe(read_in_); 708 ClosePipe(read_in_);
731 ClosePipe(read_err_); 709 ClosePipe(read_err_);
732 ClosePipe(write_out_); 710 ClosePipe(write_out_);
733 } 711 }
734 712
735
736 int read_in_[2]; // Pipe for stdout to child process. 713 int read_in_[2]; // Pipe for stdout to child process.
737 int read_err_[2]; // Pipe for stderr to child process. 714 int read_err_[2]; // Pipe for stderr to child process.
738 int write_out_[2]; // Pipe for stdin to child process. 715 int write_out_[2]; // Pipe for stdin to child process.
739 int exec_control_[2]; // Pipe to get the result from exec. 716 int exec_control_[2]; // Pipe to get the result from exec.
740 717
741 char** program_arguments_; 718 char** program_arguments_;
742 char** program_environment_; 719 char** program_environment_;
743 720
744 const char* path_; 721 const char* path_;
745 const char* working_directory_; 722 const char* working_directory_;
746 ProcessStartMode mode_; 723 ProcessStartMode mode_;
747 intptr_t* in_; 724 intptr_t* in_;
748 intptr_t* out_; 725 intptr_t* out_;
749 intptr_t* err_; 726 intptr_t* err_;
750 intptr_t* id_; 727 intptr_t* id_;
751 intptr_t* exit_event_; 728 intptr_t* exit_event_;
752 char** os_error_message_; 729 char** os_error_message_;
753 730
754 DISALLOW_ALLOCATION(); 731 DISALLOW_ALLOCATION();
755 DISALLOW_IMPLICIT_CONSTRUCTORS(ProcessStarter); 732 DISALLOW_IMPLICIT_CONSTRUCTORS(ProcessStarter);
756 }; 733 };
757 734
758
759 int Process::Start(const char* path, 735 int Process::Start(const char* path,
760 char* arguments[], 736 char* arguments[],
761 intptr_t arguments_length, 737 intptr_t arguments_length,
762 const char* working_directory, 738 const char* working_directory,
763 char* environment[], 739 char* environment[],
764 intptr_t environment_length, 740 intptr_t environment_length,
765 ProcessStartMode mode, 741 ProcessStartMode mode,
766 intptr_t* in, 742 intptr_t* in,
767 intptr_t* out, 743 intptr_t* out,
768 intptr_t* err, 744 intptr_t* err,
769 intptr_t* id, 745 intptr_t* id,
770 intptr_t* exit_event, 746 intptr_t* exit_event,
771 char** os_error_message) { 747 char** os_error_message) {
772 ProcessStarter starter(path, arguments, arguments_length, working_directory, 748 ProcessStarter starter(path, arguments, arguments_length, working_directory,
773 environment, environment_length, mode, in, out, err, 749 environment, environment_length, mode, in, out, err,
774 id, exit_event, os_error_message); 750 id, exit_event, os_error_message);
775 return starter.Start(); 751 return starter.Start();
776 } 752 }
777 753
778
779 static bool CloseProcessBuffers(struct pollfd fds[3]) { 754 static bool CloseProcessBuffers(struct pollfd fds[3]) {
780 int e = errno; 755 int e = errno;
781 VOID_TEMP_FAILURE_RETRY(close(fds[0].fd)); 756 VOID_TEMP_FAILURE_RETRY(close(fds[0].fd));
782 VOID_TEMP_FAILURE_RETRY(close(fds[1].fd)); 757 VOID_TEMP_FAILURE_RETRY(close(fds[1].fd));
783 VOID_TEMP_FAILURE_RETRY(close(fds[2].fd)); 758 VOID_TEMP_FAILURE_RETRY(close(fds[2].fd));
784 errno = e; 759 errno = e;
785 return false; 760 return false;
786 } 761 }
787 762
788
789 bool Process::Wait(intptr_t pid, 763 bool Process::Wait(intptr_t pid,
790 intptr_t in, 764 intptr_t in,
791 intptr_t out, 765 intptr_t out,
792 intptr_t err, 766 intptr_t err,
793 intptr_t exit_event, 767 intptr_t exit_event,
794 ProcessResult* result) { 768 ProcessResult* result) {
795 // Close input to the process right away. 769 // Close input to the process right away.
796 VOID_TEMP_FAILURE_RETRY(close(in)); 770 VOID_TEMP_FAILURE_RETRY(close(in));
797 771
798 // There is no return from this function using Dart_PropagateError 772 // There is no return from this function using Dart_PropagateError
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
866 intptr_t exit_code = exit_code_data.ints[0]; 840 intptr_t exit_code = exit_code_data.ints[0];
867 intptr_t negative = exit_code_data.ints[1]; 841 intptr_t negative = exit_code_data.ints[1];
868 if (negative != 0) { 842 if (negative != 0) {
869 exit_code = -exit_code; 843 exit_code = -exit_code;
870 } 844 }
871 result->set_exit_code(exit_code); 845 result->set_exit_code(exit_code);
872 846
873 return true; 847 return true;
874 } 848 }
875 849
876
877 bool Process::Kill(intptr_t id, int signal) { 850 bool Process::Kill(intptr_t id, int signal) {
878 return (TEMP_FAILURE_RETRY(kill(id, signal)) != -1); 851 return (TEMP_FAILURE_RETRY(kill(id, signal)) != -1);
879 } 852 }
880 853
881
882 void Process::TerminateExitCodeHandler() { 854 void Process::TerminateExitCodeHandler() {
883 ExitCodeHandler::TerminateExitCodeThread(); 855 ExitCodeHandler::TerminateExitCodeThread();
884 } 856 }
885 857
886
887 intptr_t Process::CurrentProcessId() { 858 intptr_t Process::CurrentProcessId() {
888 return static_cast<intptr_t>(getpid()); 859 return static_cast<intptr_t>(getpid());
889 } 860 }
890 861
891
892 int64_t Process::CurrentRSS() { 862 int64_t Process::CurrentRSS() {
893 // The second value in /proc/self/statm is the current RSS in pages. 863 // The second value in /proc/self/statm is the current RSS in pages.
894 File* statm = File::Open("/proc/self/statm", File::kRead); 864 File* statm = File::Open("/proc/self/statm", File::kRead);
895 if (statm == NULL) { 865 if (statm == NULL) {
896 return -1; 866 return -1;
897 } 867 }
898 RefCntReleaseScope<File> releaser(statm); 868 RefCntReleaseScope<File> releaser(statm);
899 const intptr_t statm_length = 1 * KB; 869 const intptr_t statm_length = 1 * KB;
900 void* buffer = reinterpret_cast<void*>(Dart_ScopeAllocate(statm_length)); 870 void* buffer = reinterpret_cast<void*>(Dart_ScopeAllocate(statm_length));
901 const intptr_t statm_read = statm->Read(buffer, statm_length); 871 const intptr_t statm_read = statm->Read(buffer, statm_length);
902 if (statm_read <= 0) { 872 if (statm_read <= 0) {
903 return -1; 873 return -1;
904 } 874 }
905 int64_t current_rss_pages = 0; 875 int64_t current_rss_pages = 0;
906 int matches = sscanf(reinterpret_cast<char*>(buffer), "%*s%" Pd64 "", 876 int matches = sscanf(reinterpret_cast<char*>(buffer), "%*s%" Pd64 "",
907 &current_rss_pages); 877 &current_rss_pages);
908 if (matches != 1) { 878 if (matches != 1) {
909 return -1; 879 return -1;
910 } 880 }
911 return current_rss_pages * getpagesize(); 881 return current_rss_pages * getpagesize();
912 } 882 }
913 883
914
915 int64_t Process::MaxRSS() { 884 int64_t Process::MaxRSS() {
916 struct rusage usage; 885 struct rusage usage;
917 usage.ru_maxrss = 0; 886 usage.ru_maxrss = 0;
918 int r = getrusage(RUSAGE_SELF, &usage); 887 int r = getrusage(RUSAGE_SELF, &usage);
919 if (r < 0) { 888 if (r < 0) {
920 return -1; 889 return -1;
921 } 890 }
922 return usage.ru_maxrss * KB; 891 return usage.ru_maxrss * KB;
923 } 892 }
924 893
925
926 static Mutex* signal_mutex = new Mutex(); 894 static Mutex* signal_mutex = new Mutex();
927 static SignalInfo* signal_handlers = NULL; 895 static SignalInfo* signal_handlers = NULL;
928 static const int kSignalsCount = 7; 896 static const int kSignalsCount = 7;
929 static const int kSignals[kSignalsCount] = { 897 static const int kSignals[kSignalsCount] = {
930 SIGHUP, SIGINT, SIGTERM, SIGUSR1, SIGUSR2, SIGWINCH, 898 SIGHUP, SIGINT, SIGTERM, SIGUSR1, SIGUSR2, SIGWINCH,
931 SIGQUIT // Allow VMService to listen on SIGQUIT. 899 SIGQUIT // Allow VMService to listen on SIGQUIT.
932 }; 900 };
933 901
934
935 SignalInfo::~SignalInfo() { 902 SignalInfo::~SignalInfo() {
936 VOID_TEMP_FAILURE_RETRY(close(fd_)); 903 VOID_TEMP_FAILURE_RETRY(close(fd_));
937 } 904 }
938 905
939
940 static void SignalHandler(int signal) { 906 static void SignalHandler(int signal) {
941 MutexLocker lock(signal_mutex); 907 MutexLocker lock(signal_mutex);
942 const SignalInfo* handler = signal_handlers; 908 const SignalInfo* handler = signal_handlers;
943 while (handler != NULL) { 909 while (handler != NULL) {
944 if (handler->signal() == signal) { 910 if (handler->signal() == signal) {
945 int value = 0; 911 int value = 0;
946 VOID_TEMP_FAILURE_RETRY(write(handler->fd(), &value, 1)); 912 VOID_TEMP_FAILURE_RETRY(write(handler->fd(), &value, 1));
947 } 913 }
948 handler = handler->next(); 914 handler = handler->next();
949 } 915 }
950 } 916 }
951 917
952
953 intptr_t Process::SetSignalHandler(intptr_t signal) { 918 intptr_t Process::SetSignalHandler(intptr_t signal) {
954 bool found = false; 919 bool found = false;
955 for (int i = 0; i < kSignalsCount; i++) { 920 for (int i = 0; i < kSignalsCount; i++) {
956 if (kSignals[i] == signal) { 921 if (kSignals[i] == signal) {
957 found = true; 922 found = true;
958 break; 923 break;
959 } 924 }
960 } 925 }
961 if (!found) { 926 if (!found) {
962 return -1; 927 return -1;
(...skipping 30 matching lines...) Expand all
993 if (status < 0) { 958 if (status < 0) {
994 VOID_TEMP_FAILURE_RETRY(close(fds[0])); 959 VOID_TEMP_FAILURE_RETRY(close(fds[0]));
995 VOID_TEMP_FAILURE_RETRY(close(fds[1])); 960 VOID_TEMP_FAILURE_RETRY(close(fds[1]));
996 return -1; 961 return -1;
997 } 962 }
998 } 963 }
999 signal_handlers = new SignalInfo(fds[1], signal, signal_handlers); 964 signal_handlers = new SignalInfo(fds[1], signal, signal_handlers);
1000 return fds[0]; 965 return fds[0];
1001 } 966 }
1002 967
1003
1004 void Process::ClearSignalHandler(intptr_t signal, Dart_Port port) { 968 void Process::ClearSignalHandler(intptr_t signal, Dart_Port port) {
1005 // Either the port is illegal or there is no current isolate, but not both. 969 // Either the port is illegal or there is no current isolate, but not both.
1006 ASSERT((port != ILLEGAL_PORT) || (Dart_CurrentIsolate() == NULL)); 970 ASSERT((port != ILLEGAL_PORT) || (Dart_CurrentIsolate() == NULL));
1007 ASSERT((port == ILLEGAL_PORT) || (Dart_CurrentIsolate() != NULL)); 971 ASSERT((port == ILLEGAL_PORT) || (Dart_CurrentIsolate() != NULL));
1008 ThreadSignalBlocker blocker(kSignalsCount, kSignals); 972 ThreadSignalBlocker blocker(kSignalsCount, kSignals);
1009 MutexLocker lock(signal_mutex); 973 MutexLocker lock(signal_mutex);
1010 SignalInfo* handler = signal_handlers; 974 SignalInfo* handler = signal_handlers;
1011 bool unlisten = true; 975 bool unlisten = true;
1012 while (handler != NULL) { 976 while (handler != NULL) {
1013 bool remove = false; 977 bool remove = false;
(...skipping 21 matching lines...) Expand all
1035 VOID_NO_RETRY_EXPECTED(sigaction(signal, &act, NULL)); 999 VOID_NO_RETRY_EXPECTED(sigaction(signal, &act, NULL));
1036 } 1000 }
1037 } 1001 }
1038 1002
1039 } // namespace bin 1003 } // namespace bin
1040 } // namespace dart 1004 } // namespace dart
1041 1005
1042 #endif // defined(HOST_OS_ANDROID) 1006 #endif // defined(HOST_OS_ANDROID)
1043 1007
1044 #endif // !defined(DART_IO_DISABLED) 1008 #endif // !defined(DART_IO_DISABLED)
OLDNEW
« no previous file with comments | « runtime/bin/process.cc ('k') | runtime/bin/process_fuchsia.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698