| OLD | NEW |
| 1 // Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2016, 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(TARGET_OS_FUCHSIA) | 8 #if defined(TARGET_OS_FUCHSIA) |
| 9 | 9 |
| 10 #include "bin/process.h" | 10 #include "bin/process.h" |
| (...skipping 619 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 630 | 630 |
| 631 program_environment_ = NULL; | 631 program_environment_ = NULL; |
| 632 if (environment != NULL) { | 632 if (environment != NULL) { |
| 633 program_environment_ = reinterpret_cast<char**>(Dart_ScopeAllocate( | 633 program_environment_ = reinterpret_cast<char**>(Dart_ScopeAllocate( |
| 634 (environment_length + 1) * sizeof(*program_environment_))); | 634 (environment_length + 1) * sizeof(*program_environment_))); |
| 635 for (int i = 0; i < environment_length; i++) { | 635 for (int i = 0; i < environment_length; i++) { |
| 636 program_environment_[i] = environment[i]; | 636 program_environment_[i] = environment[i]; |
| 637 } | 637 } |
| 638 program_environment_[environment_length] = NULL; | 638 program_environment_[environment_length] = NULL; |
| 639 } | 639 } |
| 640 | |
| 641 binary_vmo_ = MX_HANDLE_INVALID; | |
| 642 launchpad_ = NULL; | |
| 643 } | 640 } |
| 644 | 641 |
| 645 ~ProcessStarter() { | 642 ~ProcessStarter() { |
| 646 if (binary_vmo_ != MX_HANDLE_INVALID) { | |
| 647 mx_handle_close(binary_vmo_); | |
| 648 } | |
| 649 if (launchpad_ != NULL) { | |
| 650 launchpad_destroy(launchpad_); | |
| 651 } | |
| 652 if (read_in_ != -1) { | 643 if (read_in_ != -1) { |
| 653 close(read_in_); | 644 close(read_in_); |
| 654 } | 645 } |
| 655 if (read_err_ != -1) { | 646 if (read_err_ != -1) { |
| 656 close(read_err_); | 647 close(read_err_); |
| 657 } | 648 } |
| 658 if (write_out_ != -1) { | 649 if (write_out_ != -1) { |
| 659 close(write_out_); | 650 close(write_out_); |
| 660 } | 651 } |
| 661 } | 652 } |
| 662 | 653 |
| 663 int Start() { | 654 int Start() { |
| 664 LOG_INFO("ProcessStarter: Start()\n"); | 655 LOG_INFO("ProcessStarter: Start()\n"); |
| 665 int exit_pipe_fds[2]; | 656 int exit_pipe_fds[2]; |
| 666 intptr_t result = NO_RETRY_EXPECTED(pipe(exit_pipe_fds)); | 657 intptr_t result = NO_RETRY_EXPECTED(pipe(exit_pipe_fds)); |
| 667 if (result != 0) { | 658 if (result != 0) { |
| 668 *os_error_message_ = DartUtils::ScopedCopyCString( | 659 *os_error_message_ = DartUtils::ScopedCopyCString( |
| 669 "Failed to create exit code pipe for process start."); | 660 "Failed to create exit code pipe for process start."); |
| 670 return result; | 661 return result; |
| 671 } | 662 } |
| 672 LOG_INFO("ProcessStarter: Start() set up exit_pipe_fds (%d, %d)\n", | 663 LOG_INFO("ProcessStarter: Start() set up exit_pipe_fds (%d, %d)\n", |
| 673 exit_pipe_fds[0], exit_pipe_fds[1]); | 664 exit_pipe_fds[0], exit_pipe_fds[1]); |
| 674 | 665 |
| 675 mx_status_t status = SetupLaunchpad(); | 666 // Set up a launchpad. |
| 667 launchpad_t* lp = NULL; |
| 668 mx_status_t status = SetupLaunchpad(&lp); |
| 676 if (status != NO_ERROR) { | 669 if (status != NO_ERROR) { |
| 677 close(exit_pipe_fds[0]); | 670 close(exit_pipe_fds[0]); |
| 678 close(exit_pipe_fds[1]); | 671 close(exit_pipe_fds[1]); |
| 679 return status; | 672 return status; |
| 680 } | 673 } |
| 674 ASSERT(lp != NULL); |
| 681 | 675 |
| 676 // Launch it. |
| 682 LOG_INFO("ProcessStarter: Start() Calling launchpad_start\n"); | 677 LOG_INFO("ProcessStarter: Start() Calling launchpad_start\n"); |
| 683 mx_handle_t process = launchpad_start(launchpad_); | 678 mx_handle_t process = MX_HANDLE_INVALID; |
| 684 launchpad_destroy(launchpad_); | 679 const char* errormsg = NULL; |
| 685 launchpad_ = NULL; | 680 status = launchpad_go(lp, &process, &errormsg); |
| 686 if (process < 0) { | 681 lp = NULL; // launchpad_go() calls launchpad_destroy() on the launchpad. |
| 682 if (status < 0) { |
| 687 LOG_INFO("ProcessStarter: Start() launchpad_start failed\n"); | 683 LOG_INFO("ProcessStarter: Start() launchpad_start failed\n"); |
| 688 const intptr_t kMaxMessageSize = 256; | 684 const intptr_t kMaxMessageSize = 256; |
| 689 close(exit_pipe_fds[0]); | 685 close(exit_pipe_fds[0]); |
| 690 close(exit_pipe_fds[1]); | 686 close(exit_pipe_fds[1]); |
| 691 char* message = DartUtils::ScopedCString(kMaxMessageSize); | 687 char* message = DartUtils::ScopedCString(kMaxMessageSize); |
| 692 snprintf(message, kMaxMessageSize, "%s:%d: launchpad_start failed: %s\n", | 688 snprintf(message, kMaxMessageSize, "%s:%d: launchpad_start failed: %s\n", |
| 693 __FILE__, __LINE__, mx_status_get_string(process)); | 689 __FILE__, __LINE__, errormsg); |
| 694 *os_error_message_ = message; | 690 *os_error_message_ = message; |
| 695 return process; | 691 return status; |
| 696 } | 692 } |
| 697 | 693 |
| 698 LOG_INFO("ProcessStarter: Start() adding %ld to list with exit_pipe %d\n", | 694 LOG_INFO("ProcessStarter: Start() adding %ld to list with exit_pipe %d\n", |
| 699 process, exit_pipe_fds[1]); | 695 process, exit_pipe_fds[1]); |
| 700 ProcessInfoList::AddProcess(process, exit_pipe_fds[1]); | 696 ProcessInfoList::AddProcess(process, exit_pipe_fds[1]); |
| 701 ExitCodeHandler::Start(); | 697 ExitCodeHandler::Start(); |
| 702 ExitCodeHandler::Add(process); | 698 ExitCodeHandler::Add(process); |
| 703 | 699 |
| 704 *id_ = process; | 700 *id_ = process; |
| 705 FDUtils::SetNonBlocking(read_in_); | 701 FDUtils::SetNonBlocking(read_in_); |
| (...skipping 14 matching lines...) Expand all Loading... |
| 720 #define CHECK_FOR_ERROR(status, msg) \ | 716 #define CHECK_FOR_ERROR(status, msg) \ |
| 721 if (status < 0) { \ | 717 if (status < 0) { \ |
| 722 const intptr_t kMaxMessageSize = 256; \ | 718 const intptr_t kMaxMessageSize = 256; \ |
| 723 char* message = DartUtils::ScopedCString(kMaxMessageSize); \ | 719 char* message = DartUtils::ScopedCString(kMaxMessageSize); \ |
| 724 snprintf(message, kMaxMessageSize, "%s:%d: %s: %s\n", __FILE__, __LINE__, \ | 720 snprintf(message, kMaxMessageSize, "%s:%d: %s: %s\n", __FILE__, __LINE__, \ |
| 725 msg, mx_status_get_string(status)); \ | 721 msg, mx_status_get_string(status)); \ |
| 726 *os_error_message_ = message; \ | 722 *os_error_message_ = message; \ |
| 727 return status; \ | 723 return status; \ |
| 728 } | 724 } |
| 729 | 725 |
| 730 mx_status_t SetupLaunchpad() { | 726 mx_status_t SetupLaunchpad(launchpad_t** launchpad) { |
| 727 // Set up a vmo for the binary. |
| 731 mx_handle_t binary_vmo = launchpad_vmo_from_file(path_); | 728 mx_handle_t binary_vmo = launchpad_vmo_from_file(path_); |
| 732 CHECK_FOR_ERROR(binary_vmo, "launchpad_vmo_from_file"); | 729 CHECK_FOR_ERROR(binary_vmo, "launchpad_vmo_from_file"); |
| 733 binary_vmo_ = binary_vmo; | |
| 734 | 730 |
| 735 launchpad_t* lp; | 731 // Run the child process in the same "job". |
| 736 mx_status_t status; | |
| 737 | |
| 738 mx_handle_t job = MX_HANDLE_INVALID; | 732 mx_handle_t job = MX_HANDLE_INVALID; |
| 739 status = mx_handle_duplicate(mx_job_default(), MX_RIGHT_SAME_RIGHTS, &job); | 733 mx_status_t status = |
| 734 mx_handle_duplicate(mx_job_default(), MX_RIGHT_SAME_RIGHTS, &job); |
| 735 if (status != NO_ERROR) { |
| 736 mx_handle_close(binary_vmo); |
| 737 } |
| 740 CHECK_FOR_ERROR(status, "mx_handle_duplicate"); | 738 CHECK_FOR_ERROR(status, "mx_handle_duplicate"); |
| 741 | 739 |
| 742 status = launchpad_create(job, program_arguments_[0], &lp); | 740 // Set up the launchpad. |
| 743 CHECK_FOR_ERROR(status, "launchpad_create"); | 741 launchpad_t* lp = NULL; |
| 744 launchpad_ = lp; | 742 launchpad_create(job, program_arguments_[0], &lp); |
| 745 | 743 launchpad_arguments(lp, program_arguments_count_, program_arguments_); |
| 746 status = | 744 launchpad_environ(lp, program_environment_); |
| 747 launchpad_arguments(lp, program_arguments_count_, program_arguments_); | 745 launchpad_clone_mxio_root(lp); |
| 748 CHECK_FOR_ERROR(status, "launchpad_arguments"); | |
| 749 | |
| 750 status = launchpad_environ(lp, program_environment_); | |
| 751 CHECK_FOR_ERROR(status, "launchpad_environ"); | |
| 752 | |
| 753 // TODO(zra): Use the supplied working directory when launchpad adds an | 746 // TODO(zra): Use the supplied working directory when launchpad adds an |
| 754 // API to set it. | 747 // API to set it. |
| 755 | 748 launchpad_clone_mxio_cwd(lp); |
| 756 status = launchpad_clone_mxio_root(lp); | 749 launchpad_add_pipe(lp, &write_out_, 0); |
| 757 CHECK_FOR_ERROR(status, "launchpad_clone_mxio_root"); | 750 launchpad_add_pipe(lp, &read_in_, 1); |
| 758 | 751 launchpad_add_pipe(lp, &read_err_, 2); |
| 759 status = launchpad_add_pipe(lp, &write_out_, 0); | 752 launchpad_add_vdso_vmo(lp); |
| 760 CHECK_FOR_ERROR(status, "launchpad_add_pipe"); | 753 launchpad_elf_load(lp, binary_vmo); |
| 761 | 754 launchpad_load_vdso(lp, MX_HANDLE_INVALID); |
| 762 status = launchpad_add_pipe(lp, &read_in_, 1); | 755 *launchpad = lp; |
| 763 CHECK_FOR_ERROR(status, "launchpad_add_pipe"); | |
| 764 | |
| 765 status = launchpad_add_pipe(lp, &read_err_, 2); | |
| 766 CHECK_FOR_ERROR(status, "launchpad_add_pipe"); | |
| 767 | |
| 768 status = launchpad_add_vdso_vmo(lp); | |
| 769 CHECK_FOR_ERROR(status, "launchpad_add_vdso_vmo"); | |
| 770 | |
| 771 status = launchpad_elf_load(lp, binary_vmo); | |
| 772 CHECK_FOR_ERROR(status, "launchpad_elf_load"); | |
| 773 binary_vmo_ = MX_HANDLE_INVALID; // launchpad_elf_load consumes the handle. | |
| 774 | |
| 775 status = launchpad_load_vdso(lp, MX_HANDLE_INVALID); | |
| 776 CHECK_FOR_ERROR(status, "launchpad_load_vdso"); | |
| 777 | |
| 778 status = launchpad_clone_mxio_cwd(lp); | |
| 779 CHECK_FOR_ERROR(status, "launchpad_clone_mxio_cwd"); | |
| 780 | |
| 781 return NO_ERROR; | 756 return NO_ERROR; |
| 782 } | 757 } |
| 783 | 758 |
| 784 #undef CHECK_FOR_ERROR | 759 #undef CHECK_FOR_ERROR |
| 785 | 760 |
| 786 int read_in_; // Pipe for stdout to child process. | 761 int read_in_; // Pipe for stdout to child process. |
| 787 int read_err_; // Pipe for stderr to child process. | 762 int read_err_; // Pipe for stderr to child process. |
| 788 int write_out_; // Pipe for stdin to child process. | 763 int write_out_; // Pipe for stdin to child process. |
| 789 | 764 |
| 790 char** program_arguments_; | 765 char** program_arguments_; |
| 791 intptr_t program_arguments_count_; | 766 intptr_t program_arguments_count_; |
| 792 char** program_environment_; | 767 char** program_environment_; |
| 793 | 768 |
| 794 mx_handle_t binary_vmo_; | |
| 795 launchpad_t* launchpad_; | |
| 796 | |
| 797 const char* path_; | 769 const char* path_; |
| 798 const char* working_directory_; | 770 const char* working_directory_; |
| 799 ProcessStartMode mode_; | 771 ProcessStartMode mode_; |
| 800 intptr_t* in_; | 772 intptr_t* in_; |
| 801 intptr_t* out_; | 773 intptr_t* out_; |
| 802 intptr_t* err_; | 774 intptr_t* err_; |
| 803 intptr_t* id_; | 775 intptr_t* id_; |
| 804 intptr_t* exit_event_; | 776 intptr_t* exit_event_; |
| 805 char** os_error_message_; | 777 char** os_error_message_; |
| 806 | 778 |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 843 void Process::ClearSignalHandler(intptr_t signal) { | 815 void Process::ClearSignalHandler(intptr_t signal) { |
| 844 UNIMPLEMENTED(); | 816 UNIMPLEMENTED(); |
| 845 } | 817 } |
| 846 | 818 |
| 847 } // namespace bin | 819 } // namespace bin |
| 848 } // namespace dart | 820 } // namespace dart |
| 849 | 821 |
| 850 #endif // defined(TARGET_OS_FUCHSIA) | 822 #endif // defined(TARGET_OS_FUCHSIA) |
| 851 | 823 |
| 852 #endif // !defined(DART_IO_DISABLED) | 824 #endif // !defined(DART_IO_DISABLED) |
| OLD | NEW |