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

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

Issue 1182423003: Revert "Clean up process spawning." (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Created 5 years, 6 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 | « no previous file | runtime/bin/process_linux.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 #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/fdutils.h" 19 #include "bin/fdutils.h"
20 #include "bin/lockers.h" 20 #include "bin/lockers.h"
21 #include "bin/log.h" 21 #include "bin/log.h"
22 #include "bin/thread.h" 22 #include "bin/thread.h"
23 23
24 #include "platform/signal_blocker.h" 24 #include "platform/signal_blocker.h"
25 25
26 26
27 extern char **environ;
28
29
27 namespace dart { 30 namespace dart {
28 namespace bin { 31 namespace bin {
29 32
30 // 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
31 // 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.
32 // ProcessInfo objects are kept in the static singly-linked 35 // ProcessInfo objects are kept in the static singly-linked
33 // ProcessInfoList. 36 // ProcessInfoList.
34 class ProcessInfo { 37 class ProcessInfo {
35 public: 38 public:
36 ProcessInfo(pid_t pid, intptr_t fd) : pid_(pid), fd_(fd) { } 39 ProcessInfo(pid_t pid, intptr_t fd) : pid_(pid), fd_(fd) { }
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after
144 if (!running_) { 147 if (!running_) {
145 return; 148 return;
146 } 149 }
147 150
148 // Set terminate_done_ to false, so we can use it as a guard for our 151 // Set terminate_done_ to false, so we can use it as a guard for our
149 // monitor. 152 // monitor.
150 running_ = false; 153 running_ = false;
151 154
152 // Fork to wake up waitpid. 155 // Fork to wake up waitpid.
153 if (TEMP_FAILURE_RETRY(fork()) == 0) { 156 if (TEMP_FAILURE_RETRY(fork()) == 0) {
154 _exit(0); 157 exit(0);
155 } 158 }
156 159
157 monitor_->Notify(); 160 monitor_->Notify();
158 161
159 while (!terminate_done_) { 162 while (!terminate_done_) {
160 monitor_->Wait(Monitor::kNoTimeout); 163 monitor_->Wait(Monitor::kNoTimeout);
161 } 164 }
162 } 165 }
163 166
164 private: 167 private:
(...skipping 239 matching lines...) Expand 10 before | Expand all | Expand 10 after
404 return 0; 407 return 0;
405 } 408 }
406 409
407 410
408 void NewProcess() { 411 void NewProcess() {
409 // Wait for parent process before setting up the child process. 412 // Wait for parent process before setting up the child process.
410 char msg; 413 char msg;
411 int bytes_read = FDUtils::ReadFromBlocking(read_in_[0], &msg, sizeof(msg)); 414 int bytes_read = FDUtils::ReadFromBlocking(read_in_[0], &msg, sizeof(msg));
412 if (bytes_read != sizeof(msg)) { 415 if (bytes_read != sizeof(msg)) {
413 perror("Failed receiving notification message"); 416 perror("Failed receiving notification message");
414 _exit(1); 417 exit(1);
415 } 418 }
416 if (mode_ == kNormal) { 419 if (mode_ == kNormal) {
417 ExecProcess(); 420 ExecProcess();
418 } else { 421 } else {
419 ExecDetachedProcess(); 422 ExecDetachedProcess();
420 } 423 }
421 } 424 }
422 425
423 426
424 void ExecProcess() { 427 void ExecProcess() {
425 if (TEMP_FAILURE_RETRY(dup2(write_out_[0], STDIN_FILENO)) == -1) { 428 if (TEMP_FAILURE_RETRY(dup2(write_out_[0], STDIN_FILENO)) == -1) {
426 ReportChildError(); 429 ReportChildError();
427 } 430 }
428 431
429 if (TEMP_FAILURE_RETRY(dup2(read_in_[1], STDOUT_FILENO)) == -1) { 432 if (TEMP_FAILURE_RETRY(dup2(read_in_[1], STDOUT_FILENO)) == -1) {
430 ReportChildError(); 433 ReportChildError();
431 } 434 }
432 435
433 if (TEMP_FAILURE_RETRY(dup2(read_err_[1], STDERR_FILENO)) == -1) { 436 if (TEMP_FAILURE_RETRY(dup2(read_err_[1], STDERR_FILENO)) == -1) {
434 ReportChildError(); 437 ReportChildError();
435 } 438 }
436 439
437 if (working_directory_ != NULL && 440 if (working_directory_ != NULL &&
438 TEMP_FAILURE_RETRY(chdir(working_directory_)) == -1) { 441 TEMP_FAILURE_RETRY(chdir(working_directory_)) == -1) {
439 ReportChildError(); 442 ReportChildError();
440 } 443 }
441 444
442 if (program_environment_ != NULL) { 445 if (program_environment_ != NULL) {
443 VOID_TEMP_FAILURE_RETRY( 446 environ = program_environment_;
444 execvpe(path_, const_cast<char* const*>(program_arguments_),
445 program_environment_));
446 } else {
447 VOID_TEMP_FAILURE_RETRY(
448 execvp(path_, const_cast<char* const*>(program_arguments_)));
449 } 447 }
450 448
449 VOID_TEMP_FAILURE_RETRY(
450 execvp(path_, const_cast<char* const*>(program_arguments_)));
451
451 ReportChildError(); 452 ReportChildError();
452 } 453 }
453 454
454 455
455 void ExecDetachedProcess() { 456 void ExecDetachedProcess() {
456 if (mode_ == kDetached) { 457 if (mode_ == kDetached) {
457 ASSERT(write_out_[0] == -1); 458 ASSERT(write_out_[0] == -1);
458 ASSERT(write_out_[1] == -1); 459 ASSERT(write_out_[1] == -1);
459 ASSERT(read_err_[0] == -1); 460 ASSERT(read_err_[0] == -1);
460 ASSERT(read_err_[1] == -1); 461 ASSERT(read_err_[1] == -1);
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
492 TEMP_FAILURE_RETRY(chdir(working_directory_)) == -1) { 493 TEMP_FAILURE_RETRY(chdir(working_directory_)) == -1) {
493 ReportChildError(); 494 ReportChildError();
494 } 495 }
495 496
496 // Report the final PID and do the exec. 497 // Report the final PID and do the exec.
497 ReportPid(getpid()); // getpid cannot fail. 498 ReportPid(getpid()); // getpid cannot fail.
498 VOID_TEMP_FAILURE_RETRY( 499 VOID_TEMP_FAILURE_RETRY(
499 execvp(path_, const_cast<char* const*>(program_arguments_))); 500 execvp(path_, const_cast<char* const*>(program_arguments_)));
500 ReportChildError(); 501 ReportChildError();
501 } else { 502 } else {
502 // Exit the intermediate process. 503 // Exit the intermeiate process.
503 _exit(0); 504 exit(0);
504 } 505 }
505 } 506 }
506 } else { 507 } else {
507 // Exit the intermediate process. 508 // Exit the intermeiate process.
508 _exit(0); 509 exit(0);
509 } 510 }
510 } 511 }
511 512
512 513
513 int RegisterProcess(pid_t pid) { 514 int RegisterProcess(pid_t pid) {
514 int result; 515 int result;
515 int event_fds[2]; 516 int event_fds[2];
516 result = TEMP_FAILURE_RETRY(pipe2(event_fds, O_CLOEXEC)); 517 result = TEMP_FAILURE_RETRY(pipe2(event_fds, O_CLOEXEC));
517 if (result < 0) { 518 if (result < 0) {
518 return CleanupAndReturnError(); 519 return CleanupAndReturnError();
519 } 520 }
520 521
521 ProcessInfoList::AddProcess(pid, event_fds[1]); 522 ProcessInfoList::AddProcess(pid, event_fds[1]);
522 *exit_event_ = event_fds[0]; 523 *exit_event_ = event_fds[0];
523 FDUtils::SetNonBlocking(event_fds[0]); 524 FDUtils::SetNonBlocking(event_fds[0]);
524 return 0; 525 return 0;
525 } 526 }
526 527
527 528
528 int ReadExecResult() { 529 int ReadExecResult() {
529 int child_errno; 530 int child_errno;
530 int bytes_read = -1; 531 int bytes_read = -1;
531 // Read exec result from child. If no data is returned the exec was 532 // Read exec result from child. If no data is returned the exec was
532 // successful and the exec call closed the pipe. Otherwise the errno 533 // successful and the exec call closed the pipe. Otherwise the errno
533 // is written to the pipe. 534 // is written to the pipe.
534 bytes_read = 535 bytes_read =
535 FDUtils::ReadFromBlocking( 536 FDUtils::ReadFromBlocking(
536 exec_control_[0], &child_errno, sizeof(child_errno)); 537 exec_control_[0], &child_errno, sizeof(child_errno));
537 if (bytes_read == sizeof(child_errno)) { 538 if (bytes_read == sizeof(child_errno)) {
538 SetOSErrorMessage(child_errno); 539 ReadChildError();
539 return child_errno; 540 return child_errno;
540 } else if (bytes_read == -1) { 541 } else if (bytes_read == -1) {
541 return errno; 542 return errno;
542 } 543 }
543 return 0; 544 return 0;
544 } 545 }
545 546
546 547
547 int ReadDetachedExecResult(pid_t *pid) { 548 int ReadDetachedExecResult(pid_t *pid) {
548 int child_errno; 549 int child_errno;
549 int bytes_read = -1; 550 int bytes_read = -1;
550 // Read exec result from child. If only pid data is returned the exec was 551 // Read exec result from child. If only pid data is returned the exec was
551 // successful and the exec call closed the pipe. Otherwise the errno 552 // successful and the exec call closed the pipe. Otherwise the errno
552 // is written to the pipe as well. 553 // is written to the pipe as well.
553 int result[2]; 554 int result[2];
554 bytes_read = 555 bytes_read =
555 FDUtils::ReadFromBlocking( 556 FDUtils::ReadFromBlocking(
556 exec_control_[0], result, sizeof(result)); 557 exec_control_[0], result, sizeof(result));
557 if (bytes_read == sizeof(int)) { 558 if (bytes_read == sizeof(int)) {
558 *pid = result[0]; 559 *pid = result[0];
559 } else if (bytes_read == 2 * sizeof(int)) { 560 } else if (bytes_read == 2 * sizeof(int)) {
560 *pid = result[0]; 561 *pid = result[0];
561 child_errno = result[1]; 562 child_errno = result[1];
562 SetOSErrorMessage(child_errno); 563 ReadChildError();
563 return child_errno; 564 return child_errno;
564 } else if (bytes_read == -1) { 565 } else if (bytes_read == -1) {
565 return errno; 566 return errno;
566 } 567 }
567 return 0; 568 return 0;
568 } 569 }
569 570
570 571
571 void SetupDetached() { 572 void SetupDetached() {
572 ASSERT(mode_ == kDetached); 573 ASSERT(mode_ == kDetached);
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
642 643
643 void SetChildOsErrorMessage() { 644 void SetChildOsErrorMessage() {
644 const int kBufferSize = 1024; 645 const int kBufferSize = 1024;
645 char error_message[kBufferSize]; 646 char error_message[kBufferSize];
646 strerror_r(errno, error_message, kBufferSize); 647 strerror_r(errno, error_message, kBufferSize);
647 *os_error_message_ = strdup(error_message); 648 *os_error_message_ = strdup(error_message);
648 } 649 }
649 650
650 651
651 void ReportChildError() { 652 void ReportChildError() {
652 // In the case of failure in the child process write the errno to the exec 653 // In the case of failure in the child process write the errno and
653 // control pipe and exit. 654 // the OS error message to the exec control pipe and exit.
654 int child_errno = errno; 655 int child_errno = errno;
655 FDUtils::WriteToBlocking( 656 const int kBufferSize = 1024;
656 exec_control_[1], &child_errno, sizeof(child_errno)); 657 char os_error_message[kBufferSize];
657 _exit(1); 658 strerror_r(errno, os_error_message, kBufferSize);
659 int bytes_written =
660 FDUtils::WriteToBlocking(
661 exec_control_[1], &child_errno, sizeof(child_errno));
662 if (bytes_written == sizeof(child_errno)) {
663 FDUtils::WriteToBlocking(
664 exec_control_[1], os_error_message, strlen(os_error_message) + 1);
665 }
666 VOID_TEMP_FAILURE_RETRY(close(exec_control_[1]));
667 exit(1);
658 } 668 }
659 669
660 670
661 void ReportPid(int pid) { 671 void ReportPid(int pid) {
662 // In the case of starting a detached process the actual pid of that process 672 // In the case of starting a detached process the actual pid of that process
663 // is communicated using the exec control pipe. 673 // is communicated using the exec control pipe.
664 int bytes_written = 674 int bytes_written =
665 FDUtils::WriteToBlocking(exec_control_[1], &pid, sizeof(pid)); 675 FDUtils::WriteToBlocking(exec_control_[1], &pid, sizeof(pid));
666 ASSERT(bytes_written == sizeof(int)); 676 ASSERT(bytes_written == sizeof(int));
667 USE(bytes_written); 677 USE(bytes_written);
668 } 678 }
669 679
670 680
671 void SetOSErrorMessage(int child_errno) { 681 void ReadChildError() {
672 const int kMaxMessageSize = 256; 682 const int kMaxMessageSize = 256;
673 char* message = static_cast<char*>(calloc(kMaxMessageSize, 0)); 683 char* message = static_cast<char*>(malloc(kMaxMessageSize));
674 char* os_error_message = strerror_r( 684 if (message != NULL) {
675 child_errno, message, kMaxMessageSize - 1); 685 FDUtils::ReadFromBlocking(exec_control_[0], message, kMaxMessageSize);
676 if (message == os_error_message) { 686 message[kMaxMessageSize - 1] = '\0';
677 *os_error_message_ = message; 687 *os_error_message_ = message;
678 } else { 688 } else {
679 free(message); 689 // Could not get error message. It will be NULL.
680 *os_error_message_ = strdup(os_error_message); 690 ASSERT(*os_error_message_ == NULL);
681 } 691 }
682 } 692 }
683 693
684 694
685 void ClosePipe(int* fds) { 695 void ClosePipe(int* fds) {
686 for (int i = 0; i < 2; i++) { 696 for (int i = 0; i < 2; i++) {
687 if (fds[i] != -1) { 697 if (fds[i] != -1) {
688 VOID_TEMP_FAILURE_RETRY(close(fds[i])); 698 VOID_TEMP_FAILURE_RETRY(close(fds[i]));
689 fds[i] = -1; 699 fds[i] = -1;
690 } 700 }
(...skipping 297 matching lines...) Expand 10 before | Expand all | Expand 10 after
988 bzero(&act, sizeof(act)); 998 bzero(&act, sizeof(act));
989 act.sa_handler = SIG_DFL; 999 act.sa_handler = SIG_DFL;
990 VOID_NO_RETRY_EXPECTED(sigaction(signal, &act, NULL)); 1000 VOID_NO_RETRY_EXPECTED(sigaction(signal, &act, NULL));
991 } 1001 }
992 } 1002 }
993 1003
994 } // namespace bin 1004 } // namespace bin
995 } // namespace dart 1005 } // namespace dart
996 1006
997 #endif // defined(TARGET_OS_ANDROID) 1007 #endif // defined(TARGET_OS_ANDROID)
OLDNEW
« no previous file with comments | « no previous file | runtime/bin/process_linux.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698