| OLD | NEW |
| 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(HOST_OS_ANDROID) | 6 #if defined(HOST_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/directory.h" |
| 20 #include "bin/fdutils.h" | 21 #include "bin/fdutils.h" |
| 21 #include "bin/file.h" | 22 #include "bin/file.h" |
| 22 #include "bin/lockers.h" | 23 #include "bin/lockers.h" |
| 23 #include "bin/log.h" | 24 #include "bin/log.h" |
| 25 #include "bin/namespace.h" |
| 24 #include "bin/reference_counting.h" | 26 #include "bin/reference_counting.h" |
| 25 #include "bin/thread.h" | 27 #include "bin/thread.h" |
| 26 | 28 |
| 27 #include "platform/signal_blocker.h" | 29 #include "platform/signal_blocker.h" |
| 28 #include "platform/utils.h" | 30 #include "platform/utils.h" |
| 29 | 31 |
| 30 extern char** environ; | 32 extern char** environ; |
| 31 | 33 |
| 32 namespace dart { | 34 namespace dart { |
| 33 namespace bin { | 35 namespace bin { |
| (...skipping 201 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 235 DISALLOW_IMPLICIT_CONSTRUCTORS(ExitCodeHandler); | 237 DISALLOW_IMPLICIT_CONSTRUCTORS(ExitCodeHandler); |
| 236 }; | 238 }; |
| 237 | 239 |
| 238 bool ExitCodeHandler::running_ = false; | 240 bool ExitCodeHandler::running_ = false; |
| 239 int ExitCodeHandler::process_count_ = 0; | 241 int ExitCodeHandler::process_count_ = 0; |
| 240 bool ExitCodeHandler::terminate_done_ = false; | 242 bool ExitCodeHandler::terminate_done_ = false; |
| 241 Monitor* ExitCodeHandler::monitor_ = new Monitor(); | 243 Monitor* ExitCodeHandler::monitor_ = new Monitor(); |
| 242 | 244 |
| 243 class ProcessStarter { | 245 class ProcessStarter { |
| 244 public: | 246 public: |
| 245 ProcessStarter(const char* path, | 247 ProcessStarter(Namespace* namespc, |
| 248 const char* path, |
| 246 char* arguments[], | 249 char* arguments[], |
| 247 intptr_t arguments_length, | 250 intptr_t arguments_length, |
| 248 const char* working_directory, | 251 const char* working_directory, |
| 249 char* environment[], | 252 char* environment[], |
| 250 intptr_t environment_length, | 253 intptr_t environment_length, |
| 251 ProcessStartMode mode, | 254 ProcessStartMode mode, |
| 252 intptr_t* in, | 255 intptr_t* in, |
| 253 intptr_t* out, | 256 intptr_t* out, |
| 254 intptr_t* err, | 257 intptr_t* err, |
| 255 intptr_t* id, | 258 intptr_t* id, |
| 256 intptr_t* exit_event, | 259 intptr_t* exit_event, |
| 257 char** os_error_message) | 260 char** os_error_message) |
| 258 : path_(path), | 261 : namespc_(namespc), |
| 262 path_(path), |
| 259 working_directory_(working_directory), | 263 working_directory_(working_directory), |
| 260 mode_(mode), | 264 mode_(mode), |
| 261 in_(in), | 265 in_(in), |
| 262 out_(out), | 266 out_(out), |
| 263 err_(err), | 267 err_(err), |
| 264 id_(id), | 268 id_(id), |
| 265 exit_event_(exit_event), | 269 exit_event_(exit_event), |
| 266 os_error_message_(os_error_message) { | 270 os_error_message_(os_error_message) { |
| 267 read_in_[0] = -1; | 271 read_in_[0] = -1; |
| 268 read_in_[1] = -1; | 272 read_in_[1] = -1; |
| (...skipping 155 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 424 perror("Failed receiving notification message"); | 428 perror("Failed receiving notification message"); |
| 425 exit(1); | 429 exit(1); |
| 426 } | 430 } |
| 427 if (mode_ == kNormal) { | 431 if (mode_ == kNormal) { |
| 428 ExecProcess(); | 432 ExecProcess(); |
| 429 } else { | 433 } else { |
| 430 ExecDetachedProcess(); | 434 ExecDetachedProcess(); |
| 431 } | 435 } |
| 432 } | 436 } |
| 433 | 437 |
| 438 const char* ResolvePath() { |
| 439 const char* resolved_path = File::GetCanonicalPath(namespc_, path_); |
| 440 return resolved_path == NULL ? path_ : resolved_path; |
| 441 } |
| 442 |
| 434 void ExecProcess() { | 443 void ExecProcess() { |
| 435 if (TEMP_FAILURE_RETRY(dup2(write_out_[0], STDIN_FILENO)) == -1) { | 444 if (TEMP_FAILURE_RETRY(dup2(write_out_[0], STDIN_FILENO)) == -1) { |
| 436 ReportChildError(); | 445 ReportChildError(); |
| 437 } | 446 } |
| 438 | 447 |
| 439 if (TEMP_FAILURE_RETRY(dup2(read_in_[1], STDOUT_FILENO)) == -1) { | 448 if (TEMP_FAILURE_RETRY(dup2(read_in_[1], STDOUT_FILENO)) == -1) { |
| 440 ReportChildError(); | 449 ReportChildError(); |
| 441 } | 450 } |
| 442 | 451 |
| 443 if (TEMP_FAILURE_RETRY(dup2(read_err_[1], STDERR_FILENO)) == -1) { | 452 if (TEMP_FAILURE_RETRY(dup2(read_err_[1], STDERR_FILENO)) == -1) { |
| 444 ReportChildError(); | 453 ReportChildError(); |
| 445 } | 454 } |
| 446 | 455 |
| 447 if (working_directory_ != NULL && | 456 if (working_directory_ != NULL && |
| 448 TEMP_FAILURE_RETRY(chdir(working_directory_)) == -1) { | 457 !Directory::SetCurrent(namespc_, working_directory_)) { |
| 449 ReportChildError(); | 458 ReportChildError(); |
| 450 } | 459 } |
| 451 | 460 |
| 452 if (program_environment_ != NULL) { | 461 if (program_environment_ != NULL) { |
| 453 environ = program_environment_; | 462 environ = program_environment_; |
| 454 } | 463 } |
| 455 | 464 |
| 465 const char* resolved_path = ResolvePath(); |
| 456 VOID_TEMP_FAILURE_RETRY( | 466 VOID_TEMP_FAILURE_RETRY( |
| 457 execvp(path_, const_cast<char* const*>(program_arguments_))); | 467 execvp(resolved_path, const_cast<char* const*>(program_arguments_))); |
| 458 | 468 |
| 459 ReportChildError(); | 469 ReportChildError(); |
| 460 } | 470 } |
| 461 | 471 |
| 462 void ExecDetachedProcess() { | 472 void ExecDetachedProcess() { |
| 463 if (mode_ == kDetached) { | 473 if (mode_ == kDetached) { |
| 464 ASSERT(write_out_[0] == -1); | 474 ASSERT(write_out_[0] == -1); |
| 465 ASSERT(write_out_[1] == -1); | 475 ASSERT(write_out_[1] == -1); |
| 466 ASSERT(read_err_[0] == -1); | 476 ASSERT(read_err_[0] == -1); |
| 467 ASSERT(read_err_[1] == -1); | 477 ASSERT(read_err_[1] == -1); |
| (...skipping 21 matching lines...) Expand all Loading... |
| 489 if (pid < 0) { | 499 if (pid < 0) { |
| 490 ReportChildError(); | 500 ReportChildError(); |
| 491 } else if (pid == 0) { | 501 } else if (pid == 0) { |
| 492 if (mode_ == kDetached) { | 502 if (mode_ == kDetached) { |
| 493 SetupDetached(); | 503 SetupDetached(); |
| 494 } else { | 504 } else { |
| 495 SetupDetachedWithStdio(); | 505 SetupDetachedWithStdio(); |
| 496 } | 506 } |
| 497 | 507 |
| 498 if ((working_directory_ != NULL) && | 508 if ((working_directory_ != NULL) && |
| 499 (TEMP_FAILURE_RETRY(chdir(working_directory_)) == -1)) { | 509 !Directory::SetCurrent(namespc_, working_directory_)) { |
| 500 ReportChildError(); | 510 ReportChildError(); |
| 501 } | 511 } |
| 502 | 512 |
| 503 // Report the final PID and do the exec. | 513 // Report the final PID and do the exec. |
| 504 ReportPid(getpid()); // getpid cannot fail. | 514 ReportPid(getpid()); // getpid cannot fail. |
| 505 VOID_TEMP_FAILURE_RETRY( | 515 const char* resolved_path = ResolvePath(); |
| 506 execvp(path_, const_cast<char* const*>(program_arguments_))); | 516 VOID_TEMP_FAILURE_RETRY(execvp( |
| 517 resolved_path, const_cast<char* const*>(program_arguments_))); |
| 507 ReportChildError(); | 518 ReportChildError(); |
| 508 } else { | 519 } else { |
| 509 // Exit the intermediate process. | 520 // Exit the intermediate process. |
| 510 exit(0); | 521 exit(0); |
| 511 } | 522 } |
| 512 } | 523 } |
| 513 } else { | 524 } else { |
| 514 // Exit the intermediate process. | 525 // Exit the intermediate process. |
| 515 exit(0); | 526 exit(0); |
| 516 } | 527 } |
| (...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 648 char* error_message = DartUtils::ScopedCString(kBufferSize); | 659 char* error_message = DartUtils::ScopedCString(kBufferSize); |
| 649 Utils::StrError(errno, error_message, kBufferSize); | 660 Utils::StrError(errno, error_message, kBufferSize); |
| 650 *os_error_message_ = error_message; | 661 *os_error_message_ = error_message; |
| 651 } | 662 } |
| 652 | 663 |
| 653 void ReportChildError() { | 664 void ReportChildError() { |
| 654 // In the case of failure in the child process write the errno and | 665 // In the case of failure in the child process write the errno and |
| 655 // the OS error message to the exec control pipe and exit. | 666 // the OS error message to the exec control pipe and exit. |
| 656 int child_errno = errno; | 667 int child_errno = errno; |
| 657 const int kBufferSize = 1024; | 668 const int kBufferSize = 1024; |
| 658 char os_error_message[kBufferSize]; | 669 char error_buf[kBufferSize]; |
| 659 Utils::StrError(errno, os_error_message, kBufferSize); | 670 char* os_error_message = Utils::StrError(errno, error_buf, kBufferSize); |
| 660 int bytes_written = FDUtils::WriteToBlocking(exec_control_[1], &child_errno, | 671 int bytes_written = FDUtils::WriteToBlocking(exec_control_[1], &child_errno, |
| 661 sizeof(child_errno)); | 672 sizeof(child_errno)); |
| 662 if (bytes_written == sizeof(child_errno)) { | 673 if (bytes_written == sizeof(child_errno)) { |
| 663 FDUtils::WriteToBlocking(exec_control_[1], os_error_message, | 674 FDUtils::WriteToBlocking(exec_control_[1], os_error_message, |
| 664 strlen(os_error_message) + 1); | 675 strlen(os_error_message) + 1); |
| 665 } | 676 } |
| 666 VOID_TEMP_FAILURE_RETRY(close(exec_control_[1])); | 677 VOID_TEMP_FAILURE_RETRY(close(exec_control_[1])); |
| 667 | 678 |
| 668 // We avoid running through registered atexit() handlers because that is | 679 // We avoid running through registered atexit() handlers because that is |
| 669 // unnecessary work. | 680 // unnecessary work. |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 709 } | 720 } |
| 710 | 721 |
| 711 int read_in_[2]; // Pipe for stdout to child process. | 722 int read_in_[2]; // Pipe for stdout to child process. |
| 712 int read_err_[2]; // Pipe for stderr to child process. | 723 int read_err_[2]; // Pipe for stderr to child process. |
| 713 int write_out_[2]; // Pipe for stdin to child process. | 724 int write_out_[2]; // Pipe for stdin to child process. |
| 714 int exec_control_[2]; // Pipe to get the result from exec. | 725 int exec_control_[2]; // Pipe to get the result from exec. |
| 715 | 726 |
| 716 char** program_arguments_; | 727 char** program_arguments_; |
| 717 char** program_environment_; | 728 char** program_environment_; |
| 718 | 729 |
| 730 Namespace* namespc_; |
| 719 const char* path_; | 731 const char* path_; |
| 720 const char* working_directory_; | 732 const char* working_directory_; |
| 721 ProcessStartMode mode_; | 733 ProcessStartMode mode_; |
| 722 intptr_t* in_; | 734 intptr_t* in_; |
| 723 intptr_t* out_; | 735 intptr_t* out_; |
| 724 intptr_t* err_; | 736 intptr_t* err_; |
| 725 intptr_t* id_; | 737 intptr_t* id_; |
| 726 intptr_t* exit_event_; | 738 intptr_t* exit_event_; |
| 727 char** os_error_message_; | 739 char** os_error_message_; |
| 728 | 740 |
| 729 DISALLOW_ALLOCATION(); | 741 DISALLOW_ALLOCATION(); |
| 730 DISALLOW_IMPLICIT_CONSTRUCTORS(ProcessStarter); | 742 DISALLOW_IMPLICIT_CONSTRUCTORS(ProcessStarter); |
| 731 }; | 743 }; |
| 732 | 744 |
| 733 int Process::Start(const char* path, | 745 int Process::Start(Namespace* namespc, |
| 746 const char* path, |
| 734 char* arguments[], | 747 char* arguments[], |
| 735 intptr_t arguments_length, | 748 intptr_t arguments_length, |
| 736 const char* working_directory, | 749 const char* working_directory, |
| 737 char* environment[], | 750 char* environment[], |
| 738 intptr_t environment_length, | 751 intptr_t environment_length, |
| 739 ProcessStartMode mode, | 752 ProcessStartMode mode, |
| 740 intptr_t* in, | 753 intptr_t* in, |
| 741 intptr_t* out, | 754 intptr_t* out, |
| 742 intptr_t* err, | 755 intptr_t* err, |
| 743 intptr_t* id, | 756 intptr_t* id, |
| 744 intptr_t* exit_event, | 757 intptr_t* exit_event, |
| 745 char** os_error_message) { | 758 char** os_error_message) { |
| 746 ProcessStarter starter(path, arguments, arguments_length, working_directory, | 759 ProcessStarter starter(namespc, path, arguments, arguments_length, |
| 747 environment, environment_length, mode, in, out, err, | 760 working_directory, environment, environment_length, |
| 748 id, exit_event, os_error_message); | 761 mode, in, out, err, id, exit_event, os_error_message); |
| 749 return starter.Start(); | 762 return starter.Start(); |
| 750 } | 763 } |
| 751 | 764 |
| 752 static bool CloseProcessBuffers(struct pollfd fds[3]) { | 765 static bool CloseProcessBuffers(struct pollfd fds[3]) { |
| 753 int e = errno; | 766 int e = errno; |
| 754 VOID_TEMP_FAILURE_RETRY(close(fds[0].fd)); | 767 VOID_TEMP_FAILURE_RETRY(close(fds[0].fd)); |
| 755 VOID_TEMP_FAILURE_RETRY(close(fds[1].fd)); | 768 VOID_TEMP_FAILURE_RETRY(close(fds[1].fd)); |
| 756 VOID_TEMP_FAILURE_RETRY(close(fds[2].fd)); | 769 VOID_TEMP_FAILURE_RETRY(close(fds[2].fd)); |
| 757 errno = e; | 770 errno = e; |
| 758 return false; | 771 return false; |
| (...skipping 238 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 997 bzero(&act, sizeof(act)); | 1010 bzero(&act, sizeof(act)); |
| 998 act.sa_handler = SIG_DFL; | 1011 act.sa_handler = SIG_DFL; |
| 999 VOID_NO_RETRY_EXPECTED(sigaction(signal, &act, NULL)); | 1012 VOID_NO_RETRY_EXPECTED(sigaction(signal, &act, NULL)); |
| 1000 } | 1013 } |
| 1001 } | 1014 } |
| 1002 | 1015 |
| 1003 } // namespace bin | 1016 } // namespace bin |
| 1004 } // namespace dart | 1017 } // namespace dart |
| 1005 | 1018 |
| 1006 #endif // defined(HOST_OS_ANDROID) | 1019 #endif // defined(HOST_OS_ANDROID) |
| OLD | NEW |