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

Side by Side Diff: runtime/bin/process_android.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_ANDROID) 6 #if defined(TARGET_OS_ANDROID)
7 7
8 #include "bin/process.h" 8 #include "bin/process.h"
9 9
10 #include <errno.h> // NOLINT 10 #include <errno.h> // NOLINT
11 #include <fcntl.h> // NOLINT 11 #include <fcntl.h> // NOLINT
12 #include <poll.h> // NOLINT 12 #include <poll.h> // NOLINT
13 #include <stdio.h> // NOLINT 13 #include <stdio.h> // NOLINT
14 #include <stdlib.h> // NOLINT 14 #include <stdlib.h> // NOLINT
15 #include <string.h> // NOLINT 15 #include <string.h> // NOLINT
16 #include <sys/wait.h> // NOLINT 16 #include <sys/wait.h> // NOLINT
17 #include <unistd.h> // NOLINT 17 #include <unistd.h> // NOLINT
18 18
19 #include "bin/dartutils.h" 19 #include "bin/dartutils.h"
20 #include "bin/fdutils.h" 20 #include "bin/fdutils.h"
21 #include "bin/lockers.h" 21 #include "bin/lockers.h"
22 #include "bin/log.h" 22 #include "bin/log.h"
23 #include "bin/thread.h" 23 #include "bin/thread.h"
24 24
25 #include "platform/signal_blocker.h" 25 #include "platform/signal_blocker.h"
26 #include "platform/utils.h" 26 #include "platform/utils.h"
27 27
28
29 extern char **environ; 28 extern char **environ;
30 29
31
32 namespace dart { 30 namespace dart {
33 namespace bin { 31 namespace bin {
34 32
35 // ProcessInfo is used to map a process id to the file descriptor for 33 // ProcessInfo is used to map a process id to the file descriptor for
36 // the pipe used to communicate the exit code of the process to Dart. 34 // the pipe used to communicate the exit code of the process to Dart.
37 // ProcessInfo objects are kept in the static singly-linked 35 // ProcessInfo objects are kept in the static singly-linked
38 // ProcessInfoList. 36 // ProcessInfoList.
39 class ProcessInfo { 37 class ProcessInfo {
40 public: 38 public:
41 ProcessInfo(pid_t pid, intptr_t fd) : pid_(pid), fd_(fd) { } 39 ProcessInfo(pid_t pid, intptr_t fd) : pid_(pid), fd_(fd) { }
42 ~ProcessInfo() { 40 ~ProcessInfo() {
43 int closed = TEMP_FAILURE_RETRY(close(fd_)); 41 int closed = TEMP_FAILURE_RETRY(close(fd_));
44 if (closed != 0) { 42 if (closed != 0) {
45 FATAL("Failed to close process exit code pipe"); 43 FATAL("Failed to close process exit code pipe");
46 } 44 }
47 } 45 }
48 pid_t pid() { return pid_; } 46 pid_t pid() { return pid_; }
49 intptr_t fd() { return fd_; } 47 intptr_t fd() { return fd_; }
50 ProcessInfo* next() { return next_; } 48 ProcessInfo* next() { return next_; }
51 void set_next(ProcessInfo* info) { next_ = info; } 49 void set_next(ProcessInfo* info) { next_ = info; }
52 50
53 private: 51 private:
54 pid_t pid_; 52 pid_t pid_;
55 intptr_t fd_; 53 intptr_t fd_;
56 ProcessInfo* next_; 54 ProcessInfo* next_;
55
56 DISALLOW_COPY_AND_ASSIGN(ProcessInfo);
57 }; 57 };
58 58
59 59
60 // Singly-linked list of ProcessInfo objects for all active processes 60 // Singly-linked list of ProcessInfo objects for all active processes
61 // started from Dart. 61 // started from Dart.
62 class ProcessInfoList { 62 class ProcessInfoList {
63 public: 63 public:
64 static void AddProcess(pid_t pid, intptr_t fd) { 64 static void AddProcess(pid_t pid, intptr_t fd) {
65 MutexLocker locker(mutex_); 65 MutexLocker locker(mutex_);
66 ProcessInfo* info = new ProcessInfo(pid, fd); 66 ProcessInfo* info = new ProcessInfo(pid, fd);
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
101 } 101 }
102 } 102 }
103 103
104 private: 104 private:
105 // Linked list of ProcessInfo objects for all active processes 105 // Linked list of ProcessInfo objects for all active processes
106 // started from Dart code. 106 // started from Dart code.
107 static ProcessInfo* active_processes_; 107 static ProcessInfo* active_processes_;
108 // Mutex protecting all accesses to the linked list of active 108 // Mutex protecting all accesses to the linked list of active
109 // processes. 109 // processes.
110 static Mutex* mutex_; 110 static Mutex* mutex_;
111
112 DISALLOW_ALLOCATION();
113 DISALLOW_IMPLICIT_CONSTRUCTORS(ProcessInfoList);
111 }; 114 };
112 115
113 116
114 ProcessInfo* ProcessInfoList::active_processes_ = NULL; 117 ProcessInfo* ProcessInfoList::active_processes_ = NULL;
115 Mutex* ProcessInfoList::mutex_ = new Mutex(); 118 Mutex* ProcessInfoList::mutex_ = new Mutex();
116 119
117 120
118 // The exit code handler sets up a separate thread which waits for child 121 // The exit code handler sets up a separate thread which waits for child
119 // processes to terminate. That separate thread can then get the exit code from 122 // processes to terminate. That separate thread can then get the exit code from
120 // processes that have exited and communicate it to Dart through the 123 // processes that have exited and communicate it to Dart through the
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
168 171
169 private: 172 private:
170 // Entry point for the separate exit code handler thread started by 173 // Entry point for the separate exit code handler thread started by
171 // the ExitCodeHandler. 174 // the ExitCodeHandler.
172 static void ExitCodeHandlerEntry(uword param) { 175 static void ExitCodeHandlerEntry(uword param) {
173 pid_t pid = 0; 176 pid_t pid = 0;
174 int status = 0; 177 int status = 0;
175 while (true) { 178 while (true) {
176 { 179 {
177 MonitorLocker locker(monitor_); 180 MonitorLocker locker(monitor_);
178 while (running_ && process_count_ == 0) { 181 while (running_ && (process_count_ == 0)) {
179 monitor_->Wait(Monitor::kNoTimeout); 182 monitor_->Wait(Monitor::kNoTimeout);
180 } 183 }
181 if (!running_) { 184 if (!running_) {
182 terminate_done_ = true; 185 terminate_done_ = true;
183 monitor_->Notify(); 186 monitor_->Notify();
184 return; 187 return;
185 } 188 }
186 } 189 }
187 190
188 if ((pid = TEMP_FAILURE_RETRY(wait(&status))) > 0) { 191 if ((pid = TEMP_FAILURE_RETRY(wait(&status))) > 0) {
189 int exit_code = 0; 192 int exit_code = 0;
190 int negative = 0; 193 int negative = 0;
191 if (WIFEXITED(status)) { 194 if (WIFEXITED(status)) {
192 exit_code = WEXITSTATUS(status); 195 exit_code = WEXITSTATUS(status);
193 } 196 }
194 if (WIFSIGNALED(status)) { 197 if (WIFSIGNALED(status)) {
195 exit_code = WTERMSIG(status); 198 exit_code = WTERMSIG(status);
196 negative = 1; 199 negative = 1;
197 } 200 }
198 intptr_t exit_code_fd = ProcessInfoList::LookupProcessExitFd(pid); 201 intptr_t exit_code_fd = ProcessInfoList::LookupProcessExitFd(pid);
199 if (exit_code_fd != 0) { 202 if (exit_code_fd != 0) {
200 int message[2] = { exit_code, negative }; 203 int message[2] = { exit_code, negative };
201 ssize_t result = 204 ssize_t result =
202 FDUtils::WriteToBlocking(exit_code_fd, &message, sizeof(message)); 205 FDUtils::WriteToBlocking(exit_code_fd, &message, sizeof(message));
203 // If the process has been closed, the read end of the exit 206 // If the process has been closed, the read end of the exit
204 // pipe has been closed. It is therefore not a problem that 207 // pipe has been closed. It is therefore not a problem that
205 // write fails with a broken pipe error. Other errors should 208 // write fails with a broken pipe error. Other errors should
206 // not happen. 209 // not happen.
207 if (result != -1 && result != sizeof(message)) { 210 if ((result != -1) && (result != sizeof(message))) {
208 FATAL("Failed to write entire process exit message"); 211 FATAL("Failed to write entire process exit message");
209 } else if (result == -1 && errno != EPIPE) { 212 } else if ((result == -1) && (errno != EPIPE)) {
210 FATAL1("Failed to write exit code: %d", errno); 213 FATAL1("Failed to write exit code: %d", errno);
211 } 214 }
212 ProcessInfoList::RemoveProcess(pid); 215 ProcessInfoList::RemoveProcess(pid);
213 { 216 {
214 MonitorLocker locker(monitor_); 217 MonitorLocker locker(monitor_);
215 process_count_--; 218 process_count_--;
216 } 219 }
217 } 220 }
218 } 221 }
219 } 222 }
220 } 223 }
221 224
222 static bool terminate_done_; 225 static bool terminate_done_;
223 static int process_count_; 226 static int process_count_;
224 static bool running_; 227 static bool running_;
225 static Monitor* monitor_; 228 static Monitor* monitor_;
229
230 DISALLOW_ALLOCATION();
231 DISALLOW_IMPLICIT_CONSTRUCTORS(ExitCodeHandler);
226 }; 232 };
227 233
228 234
229 bool ExitCodeHandler::running_ = false; 235 bool ExitCodeHandler::running_ = false;
230 int ExitCodeHandler::process_count_ = 0; 236 int ExitCodeHandler::process_count_ = 0;
231 bool ExitCodeHandler::terminate_done_ = false; 237 bool ExitCodeHandler::terminate_done_ = false;
232 Monitor* ExitCodeHandler::monitor_ = new Monitor(); 238 Monitor* ExitCodeHandler::monitor_ = new Monitor();
233 239
234 240
235 class ProcessStarter { 241 class ProcessStarter {
(...skipping 22 matching lines...) Expand all
258 os_error_message_(os_error_message) { 264 os_error_message_(os_error_message) {
259 read_in_[0] = -1; 265 read_in_[0] = -1;
260 read_in_[1] = -1; 266 read_in_[1] = -1;
261 read_err_[0] = -1; 267 read_err_[0] = -1;
262 read_err_[1] = -1; 268 read_err_[1] = -1;
263 write_out_[0] = -1; 269 write_out_[0] = -1;
264 write_out_[1] = -1; 270 write_out_[1] = -1;
265 exec_control_[0] = -1; 271 exec_control_[0] = -1;
266 exec_control_[1] = -1; 272 exec_control_[1] = -1;
267 273
268 program_arguments_ = new char*[arguments_length + 2]; 274 program_arguments_ = reinterpret_cast<char**>(Dart_ScopeAllocate(
zra 2016/03/15 18:12:29 Made this scope allocated.
275 (arguments_length + 2) * sizeof(*program_arguments_)));
269 program_arguments_[0] = const_cast<char*>(path_); 276 program_arguments_[0] = const_cast<char*>(path_);
270 for (int i = 0; i < arguments_length; i++) { 277 for (int i = 0; i < arguments_length; i++) {
271 program_arguments_[i + 1] = arguments[i]; 278 program_arguments_[i + 1] = arguments[i];
272 } 279 }
273 program_arguments_[arguments_length + 1] = NULL; 280 program_arguments_[arguments_length + 1] = NULL;
274 281
275 program_environment_ = NULL; 282 program_environment_ = NULL;
276 if (environment != NULL) { 283 if (environment != NULL) {
277 program_environment_ = new char*[environment_length + 1]; 284 program_environment_ = reinterpret_cast<char**>(Dart_ScopeAllocate(
zra 2016/03/15 18:12:29 ditto.
285 (environment_length + 1) * sizeof(*program_environment_)));
278 for (int i = 0; i < environment_length; i++) { 286 for (int i = 0; i < environment_length; i++) {
279 program_environment_[i] = environment[i]; 287 program_environment_[i] = environment[i];
280 } 288 }
281 program_environment_[environment_length] = NULL; 289 program_environment_[environment_length] = NULL;
282 } 290 }
283 } 291 }
284 292
285 293
286 ~ProcessStarter() {
287 delete[] program_arguments_;
288 delete[] program_environment_;
289 }
290
291
292 int Start() { 294 int Start() {
293 // Create pipes required. 295 // Create pipes required.
294 int err = CreatePipes(); 296 int err = CreatePipes();
295 if (err != 0) return err; 297 if (err != 0) {
298 return err;
299 }
296 300
297 // Fork to create the new process. 301 // Fork to create the new process.
298 pid_t pid = TEMP_FAILURE_RETRY(fork()); 302 pid_t pid = TEMP_FAILURE_RETRY(fork());
299 if (pid < 0) { 303 if (pid < 0) {
300 // Failed to fork. 304 // Failed to fork.
301 return CleanupAndReturnError(); 305 return CleanupAndReturnError();
302 } else if (pid == 0) { 306 } else if (pid == 0) {
303 // This runs in the new process. 307 // This runs in the new process.
304 NewProcess(); 308 NewProcess();
305 } 309 }
306 310
307 // This runs in the original process. 311 // This runs in the original process.
308 312
309 // Be sure to listen for exit-codes, now we have a child-process. 313 // Be sure to listen for exit-codes, now we have a child-process.
310 ExitCodeHandler::ProcessStarted(); 314 ExitCodeHandler::ProcessStarted();
311 315
312 // Register the child process if not detached. 316 // Register the child process if not detached.
313 if (mode_ == kNormal) { 317 if (mode_ == kNormal) {
314 err = RegisterProcess(pid); 318 err = RegisterProcess(pid);
315 if (err != 0) return err; 319 if (err != 0) {
320 return err;
321 }
316 } 322 }
317 323
318 // Notify child process to start. This is done to delay the call to exec 324 // Notify child process to start. This is done to delay the call to exec
319 // until the process is registered above, and we are ready to receive the 325 // until the process is registered above, and we are ready to receive the
320 // exit code. 326 // exit code.
321 char msg = '1'; 327 char msg = '1';
322 int bytes_written = 328 int bytes_written =
323 FDUtils::WriteToBlocking(read_in_[1], &msg, sizeof(msg)); 329 FDUtils::WriteToBlocking(read_in_[1], &msg, sizeof(msg));
324 if (bytes_written != sizeof(msg)) { 330 if (bytes_written != sizeof(msg)) {
325 return CleanupAndReturnError(); 331 return CleanupAndReturnError();
(...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after
484 pid = TEMP_FAILURE_RETRY(fork()); 490 pid = TEMP_FAILURE_RETRY(fork());
485 if (pid < 0) { 491 if (pid < 0) {
486 ReportChildError(); 492 ReportChildError();
487 } else if (pid == 0) { 493 } else if (pid == 0) {
488 if (mode_ == kDetached) { 494 if (mode_ == kDetached) {
489 SetupDetached(); 495 SetupDetached();
490 } else { 496 } else {
491 SetupDetachedWithStdio(); 497 SetupDetachedWithStdio();
492 } 498 }
493 499
494 if (working_directory_ != NULL && 500 if ((working_directory_ != NULL) &&
495 TEMP_FAILURE_RETRY(chdir(working_directory_)) == -1) { 501 (TEMP_FAILURE_RETRY(chdir(working_directory_)) == -1)) {
496 ReportChildError(); 502 ReportChildError();
497 } 503 }
498 504
499 // Report the final PID and do the exec. 505 // Report the final PID and do the exec.
500 ReportPid(getpid()); // getpid cannot fail. 506 ReportPid(getpid()); // getpid cannot fail.
501 VOID_TEMP_FAILURE_RETRY( 507 VOID_TEMP_FAILURE_RETRY(
502 execvp(path_, const_cast<char* const*>(program_arguments_))); 508 execvp(path_, const_cast<char* const*>(program_arguments_)));
503 ReportChildError(); 509 ReportChildError();
504 } else { 510 } else {
505 // Exit the intermeiate process. 511 // Exit the intermeiate process.
(...skipping 21 matching lines...) Expand all
527 return 0; 533 return 0;
528 } 534 }
529 535
530 536
531 int ReadExecResult() { 537 int ReadExecResult() {
532 int child_errno; 538 int child_errno;
533 int bytes_read = -1; 539 int bytes_read = -1;
534 // Read exec result from child. If no data is returned the exec was 540 // Read exec result from child. If no data is returned the exec was
535 // successful and the exec call closed the pipe. Otherwise the errno 541 // successful and the exec call closed the pipe. Otherwise the errno
536 // is written to the pipe. 542 // is written to the pipe.
537 bytes_read = 543 bytes_read = FDUtils::ReadFromBlocking(
538 FDUtils::ReadFromBlocking( 544 exec_control_[0], &child_errno, sizeof(child_errno));
539 exec_control_[0], &child_errno, sizeof(child_errno));
540 if (bytes_read == sizeof(child_errno)) { 545 if (bytes_read == sizeof(child_errno)) {
541 ReadChildError(); 546 ReadChildError();
542 return child_errno; 547 return child_errno;
543 } else if (bytes_read == -1) { 548 } else if (bytes_read == -1) {
544 return errno; 549 return errno;
545 } 550 }
546 return 0; 551 return 0;
547 } 552 }
548 553
549 554
550 int ReadDetachedExecResult(pid_t *pid) { 555 int ReadDetachedExecResult(pid_t *pid) {
551 int child_errno; 556 int child_errno;
552 int bytes_read = -1; 557 int bytes_read = -1;
553 // Read exec result from child. If only pid data is returned the exec was 558 // Read exec result from child. If only pid data is returned the exec was
554 // successful and the exec call closed the pipe. Otherwise the errno 559 // successful and the exec call closed the pipe. Otherwise the errno
555 // is written to the pipe as well. 560 // is written to the pipe as well.
556 int result[2]; 561 int result[2];
557 bytes_read = 562 bytes_read =
558 FDUtils::ReadFromBlocking( 563 FDUtils::ReadFromBlocking(exec_control_[0], result, sizeof(result));
559 exec_control_[0], result, sizeof(result));
560 if (bytes_read == sizeof(int)) { 564 if (bytes_read == sizeof(int)) {
561 *pid = result[0]; 565 *pid = result[0];
562 } else if (bytes_read == 2 * sizeof(int)) { 566 } else if (bytes_read == 2 * sizeof(int)) {
563 *pid = result[0]; 567 *pid = result[0];
564 child_errno = result[1]; 568 child_errno = result[1];
565 ReadChildError(); 569 ReadChildError();
566 return child_errno; 570 return child_errno;
567 } else if (bytes_read == -1) { 571 } else if (bytes_read == -1) {
568 return errno; 572 return errno;
569 } 573 }
570 return 0; 574 return 0;
571 } 575 }
572 576
573 577
574 void SetupDetached() { 578 void SetupDetached() {
575 ASSERT(mode_ == kDetached); 579 ASSERT(mode_ == kDetached);
576 580
577 // Close all open file descriptors except for exec_control_[1]. 581 // Close all open file descriptors except for exec_control_[1].
578 int max_fds = sysconf(_SC_OPEN_MAX); 582 int max_fds = sysconf(_SC_OPEN_MAX);
579 if (max_fds == -1) max_fds = _POSIX_OPEN_MAX; 583 if (max_fds == -1) {
584 max_fds = _POSIX_OPEN_MAX;
585 }
580 for (int fd = 0; fd < max_fds; fd++) { 586 for (int fd = 0; fd < max_fds; fd++) {
581 if (fd != exec_control_[1]) { 587 if (fd != exec_control_[1]) {
582 VOID_TEMP_FAILURE_RETRY(close(fd)); 588 VOID_TEMP_FAILURE_RETRY(close(fd));
583 } 589 }
584 } 590 }
585 591
586 // Re-open stdin, stdout and stderr and connect them to /dev/null. 592 // Re-open stdin, stdout and stderr and connect them to /dev/null.
587 // The loop above should already have closed all of them, so 593 // The loop above should already have closed all of them, so
588 // creating new file descriptors should start at STDIN_FILENO. 594 // creating new file descriptors should start at STDIN_FILENO.
589 int fd = TEMP_FAILURE_RETRY(open("/dev/null", O_RDWR)); 595 int fd = TEMP_FAILURE_RETRY(open("/dev/null", O_RDWR));
590 if (fd != STDIN_FILENO) { 596 if (fd != STDIN_FILENO) {
591 ReportChildError(); 597 ReportChildError();
592 } 598 }
593 if (TEMP_FAILURE_RETRY(dup2(STDIN_FILENO, STDOUT_FILENO)) != 599 if (TEMP_FAILURE_RETRY(dup2(STDIN_FILENO, STDOUT_FILENO)) !=
594 STDOUT_FILENO) { 600 STDOUT_FILENO) {
595 ReportChildError(); 601 ReportChildError();
596 } 602 }
597 if (TEMP_FAILURE_RETRY(dup2(STDIN_FILENO, STDERR_FILENO)) != 603 if (TEMP_FAILURE_RETRY(dup2(STDIN_FILENO, STDERR_FILENO)) !=
598 STDERR_FILENO) { 604 STDERR_FILENO) {
599 ReportChildError(); 605 ReportChildError();
600 } 606 }
601 } 607 }
602 608
603 void SetupDetachedWithStdio() { 609 void SetupDetachedWithStdio() {
604 // Close all open file descriptors except for 610 // Close all open file descriptors except for
605 // exec_control_[1], write_out_[0], read_in_[1] and 611 // exec_control_[1], write_out_[0], read_in_[1] and
606 // read_err_[1]. 612 // read_err_[1].
607 int max_fds = sysconf(_SC_OPEN_MAX); 613 int max_fds = sysconf(_SC_OPEN_MAX);
608 if (max_fds == -1) max_fds = _POSIX_OPEN_MAX; 614 if (max_fds == -1) {
615 max_fds = _POSIX_OPEN_MAX;
616 }
609 for (int fd = 0; fd < max_fds; fd++) { 617 for (int fd = 0; fd < max_fds; fd++) {
610 if (fd != exec_control_[1] && 618 if ((fd != exec_control_[1]) &&
611 fd != write_out_[0] && 619 (fd != write_out_[0]) &&
612 fd != read_in_[1] && 620 (fd != read_in_[1]) &&
613 fd != read_err_[1]) { 621 (fd != read_err_[1])) {
614 VOID_TEMP_FAILURE_RETRY(close(fd)); 622 VOID_TEMP_FAILURE_RETRY(close(fd));
615 } 623 }
616 } 624 }
617 625
618 if (TEMP_FAILURE_RETRY(dup2(write_out_[0], STDIN_FILENO)) == -1) { 626 if (TEMP_FAILURE_RETRY(dup2(write_out_[0], STDIN_FILENO)) == -1) {
619 ReportChildError(); 627 ReportChildError();
620 } 628 }
621 VOID_TEMP_FAILURE_RETRY(close(write_out_[0])); 629 VOID_TEMP_FAILURE_RETRY(close(write_out_[0]));
622 630
623 if (TEMP_FAILURE_RETRY(dup2(read_in_[1], STDOUT_FILENO)) == -1) { 631 if (TEMP_FAILURE_RETRY(dup2(read_in_[1], STDOUT_FILENO)) == -1) {
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after
724 732
725 const char* path_; 733 const char* path_;
726 const char* working_directory_; 734 const char* working_directory_;
727 ProcessStartMode mode_; 735 ProcessStartMode mode_;
728 intptr_t* in_; 736 intptr_t* in_;
729 intptr_t* out_; 737 intptr_t* out_;
730 intptr_t* err_; 738 intptr_t* err_;
731 intptr_t* id_; 739 intptr_t* id_;
732 intptr_t* exit_event_; 740 intptr_t* exit_event_;
733 char** os_error_message_; 741 char** os_error_message_;
742
743 DISALLOW_ALLOCATION();
744 DISALLOW_IMPLICIT_CONSTRUCTORS(ProcessStarter);
734 }; 745 };
735 746
736 747
737 int Process::Start(const char* path, 748 int Process::Start(const char* path,
738 char* arguments[], 749 char* arguments[],
739 intptr_t arguments_length, 750 intptr_t arguments_length,
740 const char* working_directory, 751 const char* working_directory,
741 char* environment[], 752 char* environment[],
742 intptr_t environment_length, 753 intptr_t environment_length,
743 ProcessStartMode mode, 754 ProcessStartMode mode,
(...skipping 15 matching lines...) Expand all
759 err, 770 err,
760 id, 771 id,
761 exit_event, 772 exit_event,
762 os_error_message); 773 os_error_message);
763 return starter.Start(); 774 return starter.Start();
764 } 775 }
765 776
766 777
767 class BufferList: public BufferListBase { 778 class BufferList: public BufferListBase {
768 public: 779 public:
780 BufferList() {}
781
769 bool Read(int fd, intptr_t available) { 782 bool Read(int fd, intptr_t available) {
770 // Read all available bytes. 783 // Read all available bytes.
771 while (available > 0) { 784 while (available > 0) {
772 if (free_size_ == 0) Allocate(); 785 if (free_size_ == 0) {
786 Allocate();
787 }
773 ASSERT(free_size_ > 0); 788 ASSERT(free_size_ > 0);
774 ASSERT(free_size_ <= kBufferSize); 789 ASSERT(free_size_ <= kBufferSize);
775 intptr_t block_size = dart::Utils::Minimum(free_size_, available); 790 intptr_t block_size = dart::Utils::Minimum(free_size_, available);
776 intptr_t bytes = TEMP_FAILURE_RETRY(read( 791 intptr_t bytes = TEMP_FAILURE_RETRY(read(
777 fd, 792 fd,
778 reinterpret_cast<void*>(FreeSpaceAddress()), 793 reinterpret_cast<void*>(FreeSpaceAddress()),
779 block_size)); 794 block_size));
780 if (bytes < 0) return false; 795 if (bytes < 0) {
796 return false;
797 }
781 data_size_ += bytes; 798 data_size_ += bytes;
782 free_size_ -= bytes; 799 free_size_ -= bytes;
783 available -= bytes; 800 available -= bytes;
784 } 801 }
785 return true; 802 return true;
786 } 803 }
804
805 private:
806 DISALLOW_COPY_AND_ASSIGN(BufferList);
787 }; 807 };
788 808
789 809
790 static bool CloseProcessBuffers(struct pollfd fds[3]) { 810 static bool CloseProcessBuffers(struct pollfd fds[3]) {
791 int e = errno; 811 int e = errno;
792 VOID_TEMP_FAILURE_RETRY(close(fds[0].fd)); 812 VOID_TEMP_FAILURE_RETRY(close(fds[0].fd));
793 VOID_TEMP_FAILURE_RETRY(close(fds[1].fd)); 813 VOID_TEMP_FAILURE_RETRY(close(fds[1].fd));
794 VOID_TEMP_FAILURE_RETRY(close(fds[2].fd)); 814 VOID_TEMP_FAILURE_RETRY(close(fds[2].fd));
795 errno = e; 815 errno = e;
796 return false; 816 return false;
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
828 int alive = 3; 848 int alive = 3;
829 while (alive > 0) { 849 while (alive > 0) {
830 // Blocking call waiting for events from the child process. 850 // Blocking call waiting for events from the child process.
831 if (TEMP_FAILURE_RETRY(poll(fds, alive, -1)) <= 0) { 851 if (TEMP_FAILURE_RETRY(poll(fds, alive, -1)) <= 0) {
832 return CloseProcessBuffers(fds); 852 return CloseProcessBuffers(fds);
833 } 853 }
834 854
835 // Process incoming data. 855 // Process incoming data.
836 int current_alive = alive; 856 int current_alive = alive;
837 for (int i = 0; i < current_alive; i++) { 857 for (int i = 0; i < current_alive; i++) {
838 if (fds[i].revents & POLLIN) { 858 if ((fds[i].revents & POLLIN) != 0) {
839 intptr_t avail = FDUtils::AvailableBytes(fds[i].fd); 859 intptr_t avail = FDUtils::AvailableBytes(fds[i].fd);
840 if (fds[i].fd == out) { 860 if (fds[i].fd == out) {
841 if (!out_data.Read(out, avail)) { 861 if (!out_data.Read(out, avail)) {
842 return CloseProcessBuffers(fds); 862 return CloseProcessBuffers(fds);
843 } 863 }
844 } else if (fds[i].fd == err) { 864 } else if (fds[i].fd == err) {
845 if (!err_data.Read(err, avail)) { 865 if (!err_data.Read(err, avail)) {
846 return CloseProcessBuffers(fds); 866 return CloseProcessBuffers(fds);
847 } 867 }
848 } else if (fds[i].fd == exit_event) { 868 } else if (fds[i].fd == exit_event) {
849 if (avail == 8) { 869 if (avail == 8) {
850 intptr_t b = TEMP_FAILURE_RETRY(read(exit_event, 870 intptr_t b = TEMP_FAILURE_RETRY(read(exit_event,
851 exit_code_data.bytes, 8)); 871 exit_code_data.bytes, 8));
852 if (b != 8) { 872 if (b != 8) {
853 return CloseProcessBuffers(fds); 873 return CloseProcessBuffers(fds);
854 } 874 }
855 } 875 }
856 } else { 876 } else {
857 UNREACHABLE(); 877 UNREACHABLE();
858 } 878 }
859 } 879 }
860 if (fds[i].revents & POLLHUP) { 880 if ((fds[i].revents & POLLHUP) != 0) {
861 VOID_TEMP_FAILURE_RETRY(close(fds[i].fd)); 881 VOID_TEMP_FAILURE_RETRY(close(fds[i].fd));
862 alive--; 882 alive--;
863 if (i < alive) { 883 if (i < alive) {
864 fds[i] = fds[alive]; 884 fds[i] = fds[alive];
865 } 885 }
866 } 886 }
867 } 887 }
868 } 888 }
869 889
870 // All handles closed and all data read. 890 // All handles closed and all data read.
871 result->set_stdout_data(out_data.GetData()); 891 result->set_stdout_data(out_data.GetData());
872 result->set_stderr_data(err_data.GetData()); 892 result->set_stderr_data(err_data.GetData());
873 893
874 // Calculate the exit code. 894 // Calculate the exit code.
875 intptr_t exit_code = exit_code_data.ints[0]; 895 intptr_t exit_code = exit_code_data.ints[0];
876 intptr_t negative = exit_code_data.ints[1]; 896 intptr_t negative = exit_code_data.ints[1];
877 if (negative) exit_code = -exit_code; 897 if (negative) {
898 exit_code = -exit_code;
899 }
878 result->set_exit_code(exit_code); 900 result->set_exit_code(exit_code);
879 901
880 return true; 902 return true;
881 } 903 }
882 904
883 905
884 bool Process::Kill(intptr_t id, int signal) { 906 bool Process::Kill(intptr_t id, int signal) {
885 return (TEMP_FAILURE_RETRY(kill(id, signal)) != -1); 907 return (TEMP_FAILURE_RETRY(kill(id, signal)) != -1);
886 } 908 }
887 909
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
929 951
930 952
931 intptr_t Process::SetSignalHandler(intptr_t signal) { 953 intptr_t Process::SetSignalHandler(intptr_t signal) {
932 bool found = false; 954 bool found = false;
933 for (int i = 0; i < kSignalsCount; i++) { 955 for (int i = 0; i < kSignalsCount; i++) {
934 if (kSignals[i] == signal) { 956 if (kSignals[i] == signal) {
935 found = true; 957 found = true;
936 break; 958 break;
937 } 959 }
938 } 960 }
939 if (!found) return -1; 961 if (!found) {
962 return -1;
963 }
940 int fds[2]; 964 int fds[2];
941 if (NO_RETRY_EXPECTED(pipe2(fds, O_CLOEXEC)) != 0) { 965 if (NO_RETRY_EXPECTED(pipe2(fds, O_CLOEXEC)) != 0) {
942 return -1; 966 return -1;
943 } 967 }
944 if (!FDUtils::SetNonBlocking(fds[0])) { 968 if (!FDUtils::SetNonBlocking(fds[0])) {
945 VOID_TEMP_FAILURE_RETRY(close(fds[0])); 969 VOID_TEMP_FAILURE_RETRY(close(fds[0]));
946 VOID_TEMP_FAILURE_RETRY(close(fds[1])); 970 VOID_TEMP_FAILURE_RETRY(close(fds[1]));
947 return -1; 971 return -1;
948 } 972 }
949 ThreadSignalBlocker blocker(kSignalsCount, kSignals); 973 ThreadSignalBlocker blocker(kSignalsCount, kSignals);
(...skipping 29 matching lines...) Expand all
979 1003
980 void Process::ClearSignalHandler(intptr_t signal) { 1004 void Process::ClearSignalHandler(intptr_t signal) {
981 ThreadSignalBlocker blocker(kSignalsCount, kSignals); 1005 ThreadSignalBlocker blocker(kSignalsCount, kSignals);
982 MutexLocker lock(signal_mutex); 1006 MutexLocker lock(signal_mutex);
983 SignalInfo* handler = signal_handlers; 1007 SignalInfo* handler = signal_handlers;
984 bool unlisten = true; 1008 bool unlisten = true;
985 while (handler != NULL) { 1009 while (handler != NULL) {
986 bool remove = false; 1010 bool remove = false;
987 if (handler->signal() == signal) { 1011 if (handler->signal() == signal) {
988 if (handler->port() == Dart_GetMainPortId()) { 1012 if (handler->port() == Dart_GetMainPortId()) {
989 if (signal_handlers == handler) signal_handlers = handler->next(); 1013 if (signal_handlers == handler) {
1014 signal_handlers = handler->next();
1015 }
990 handler->Unlink(); 1016 handler->Unlink();
991 remove = true; 1017 remove = true;
992 } else { 1018 } else {
993 unlisten = false; 1019 unlisten = false;
994 } 1020 }
995 } 1021 }
996 SignalInfo* next = handler->next(); 1022 SignalInfo* next = handler->next();
997 if (remove) delete handler; 1023 if (remove) {
1024 delete handler;
1025 }
998 handler = next; 1026 handler = next;
999 } 1027 }
1000 if (unlisten) { 1028 if (unlisten) {
1001 struct sigaction act; 1029 struct sigaction act;
1002 bzero(&act, sizeof(act)); 1030 bzero(&act, sizeof(act));
1003 act.sa_handler = SIG_DFL; 1031 act.sa_handler = SIG_DFL;
1004 VOID_NO_RETRY_EXPECTED(sigaction(signal, &act, NULL)); 1032 VOID_NO_RETRY_EXPECTED(sigaction(signal, &act, NULL));
1005 } 1033 }
1006 } 1034 }
1007 1035
1008 } // namespace bin 1036 } // namespace bin
1009 } // namespace dart 1037 } // namespace dart
1010 1038
1011 #endif // defined(TARGET_OS_ANDROID) 1039 #endif // defined(TARGET_OS_ANDROID)
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698