| 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(TARGET_OS_MACOS) | 6 #if defined(TARGET_OS_MACOS) |
| 7 | 7 |
| 8 #include "bin/process.h" | 8 #include "bin/process.h" |
| 9 | 9 |
| 10 #if !TARGET_OS_IOS | 10 #if !TARGET_OS_IOS |
| 11 #include <crt_externs.h> // NOLINT | 11 #include <crt_externs.h> // NOLINT |
| 12 #endif | 12 #endif |
| 13 #include <errno.h> // NOLINT | 13 #include <errno.h> // NOLINT |
| 14 #include <fcntl.h> // NOLINT | 14 #include <fcntl.h> // NOLINT |
| 15 #include <poll.h> // NOLINT | 15 #include <poll.h> // NOLINT |
| 16 #include <signal.h> // NOLINT | 16 #include <signal.h> // NOLINT |
| 17 #include <stdio.h> // NOLINT | 17 #include <stdio.h> // NOLINT |
| 18 #include <stdlib.h> // NOLINT | 18 #include <stdlib.h> // NOLINT |
| 19 #include <string.h> // NOLINT | 19 #include <string.h> // NOLINT |
| 20 #include <unistd.h> // NOLINT | 20 #include <unistd.h> // NOLINT |
| 21 | 21 |
| 22 #include "bin/dartutils.h" |
| 22 #include "bin/fdutils.h" | 23 #include "bin/fdutils.h" |
| 23 #include "bin/lockers.h" | 24 #include "bin/lockers.h" |
| 24 #include "bin/log.h" | 25 #include "bin/log.h" |
| 25 #include "bin/thread.h" | 26 #include "bin/thread.h" |
| 26 | 27 |
| 27 #include "platform/signal_blocker.h" | 28 #include "platform/signal_blocker.h" |
| 28 #include "platform/utils.h" | 29 #include "platform/utils.h" |
| 29 | 30 |
| 30 | 31 |
| 31 | 32 |
| (...skipping 253 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 285 | 286 |
| 286 ~ProcessStarter() { | 287 ~ProcessStarter() { |
| 287 delete[] program_arguments_; | 288 delete[] program_arguments_; |
| 288 delete[] program_environment_; | 289 delete[] program_environment_; |
| 289 } | 290 } |
| 290 | 291 |
| 291 | 292 |
| 292 int Start() { | 293 int Start() { |
| 293 // Create pipes required. | 294 // Create pipes required. |
| 294 int err = CreatePipes(); | 295 int err = CreatePipes(); |
| 295 if (err != 0) return err; | 296 if (err != 0) { |
| 297 return err; |
| 298 } |
| 296 | 299 |
| 297 // Fork to create the new process. | 300 // Fork to create the new process. |
| 298 pid_t pid = TEMP_FAILURE_RETRY(fork()); | 301 pid_t pid = TEMP_FAILURE_RETRY(fork()); |
| 299 if (pid < 0) { | 302 if (pid < 0) { |
| 300 // Failed to fork. | 303 // Failed to fork. |
| 301 return CleanupAndReturnError(); | 304 return CleanupAndReturnError(); |
| 302 } else if (pid == 0) { | 305 } else if (pid == 0) { |
| 303 // This runs in the new process. | 306 // This runs in the new process. |
| 304 NewProcess(); | 307 NewProcess(); |
| 305 } | 308 } |
| 306 | 309 |
| 307 // This runs in the original process. | 310 // This runs in the original process. |
| 308 | 311 |
| 309 // Be sure to listen for exit-codes, now we have a child-process. | 312 // Be sure to listen for exit-codes, now we have a child-process. |
| 310 ExitCodeHandler::ProcessStarted(); | 313 ExitCodeHandler::ProcessStarted(); |
| 311 | 314 |
| 312 // Register the child process if not detached. | 315 // Register the child process if not detached. |
| 313 if (mode_ == kNormal) { | 316 if (mode_ == kNormal) { |
| 314 err = RegisterProcess(pid); | 317 err = RegisterProcess(pid); |
| 315 if (err != 0) return err; | 318 if (err != 0) { |
| 319 return err; |
| 320 } |
| 316 } | 321 } |
| 317 | 322 |
| 318 // Notify child process to start. This is done to delay the call to exec | 323 // 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 | 324 // until the process is registered above, and we are ready to receive the |
| 320 // exit code. | 325 // exit code. |
| 321 char msg = '1'; | 326 char msg = '1'; |
| 322 int bytes_written = | 327 int bytes_written = |
| 323 FDUtils::WriteToBlocking(read_in_[1], &msg, sizeof(msg)); | 328 FDUtils::WriteToBlocking(read_in_[1], &msg, sizeof(msg)); |
| 324 if (bytes_written != sizeof(msg)) { | 329 if (bytes_written != sizeof(msg)) { |
| 325 return CleanupAndReturnError(); | 330 return CleanupAndReturnError(); |
| (...skipping 318 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 644 ReportChildError(); | 649 ReportChildError(); |
| 645 } | 650 } |
| 646 VOID_TEMP_FAILURE_RETRY(close(read_err_[1])); | 651 VOID_TEMP_FAILURE_RETRY(close(read_err_[1])); |
| 647 } | 652 } |
| 648 | 653 |
| 649 | 654 |
| 650 int CleanupAndReturnError() { | 655 int CleanupAndReturnError() { |
| 651 int actual_errno = errno; | 656 int actual_errno = errno; |
| 652 // If CleanupAndReturnError is called without an actual errno make | 657 // If CleanupAndReturnError is called without an actual errno make |
| 653 // sure to return an error anyway. | 658 // sure to return an error anyway. |
| 654 if (actual_errno == 0) actual_errno = EPERM; | 659 if (actual_errno == 0) { |
| 660 actual_errno = EPERM; |
| 661 } |
| 655 SetChildOsErrorMessage(); | 662 SetChildOsErrorMessage(); |
| 656 CloseAllPipes(); | 663 CloseAllPipes(); |
| 657 return actual_errno; | 664 return actual_errno; |
| 658 } | 665 } |
| 659 | 666 |
| 660 | 667 |
| 661 void SetChildOsErrorMessage() { | 668 void SetChildOsErrorMessage() { |
| 662 const int kBufferSize = 1024; | 669 const int kBufferSize = 1024; |
| 663 char error_message[kBufferSize]; | 670 char* error_message = DartUtils::ScopedCString(kBufferSize); |
| 664 Utils::StrError(errno, error_message, kBufferSize); | 671 Utils::StrError(errno, error_message, kBufferSize); |
| 665 *os_error_message_ = strdup(error_message); | 672 *os_error_message_ = error_message; |
| 666 } | 673 } |
| 667 | 674 |
| 668 | 675 |
| 669 void ReportChildError() { | 676 void ReportChildError() { |
| 670 // In the case of failure in the child process write the errno and | 677 // In the case of failure in the child process write the errno and |
| 671 // the OS error message to the exec control pipe and exit. | 678 // the OS error message to the exec control pipe and exit. |
| 672 int child_errno = errno; | 679 int child_errno = errno; |
| 673 const int kBufferSize = 1024; | 680 const int kBufferSize = 1024; |
| 674 char os_error_message[kBufferSize]; | 681 char os_error_message[kBufferSize]; |
| 675 Utils::StrError(errno, os_error_message, kBufferSize); | 682 Utils::StrError(errno, os_error_message, kBufferSize); |
| (...skipping 14 matching lines...) Expand all Loading... |
| 690 // is communicated using the exec control pipe. | 697 // is communicated using the exec control pipe. |
| 691 int bytes_written = | 698 int bytes_written = |
| 692 FDUtils::WriteToBlocking(exec_control_[1], &pid, sizeof(pid)); | 699 FDUtils::WriteToBlocking(exec_control_[1], &pid, sizeof(pid)); |
| 693 ASSERT(bytes_written == sizeof(int)); | 700 ASSERT(bytes_written == sizeof(int)); |
| 694 USE(bytes_written); | 701 USE(bytes_written); |
| 695 } | 702 } |
| 696 | 703 |
| 697 | 704 |
| 698 void ReadChildError() { | 705 void ReadChildError() { |
| 699 const int kMaxMessageSize = 256; | 706 const int kMaxMessageSize = 256; |
| 700 char* message = static_cast<char*>(malloc(kMaxMessageSize)); | 707 char* message = DartUtils::ScopedCString(kMaxMessageSize); |
| 701 if (message != NULL) { | 708 if (message != NULL) { |
| 702 FDUtils::ReadFromBlocking(exec_control_[0], message, kMaxMessageSize); | 709 FDUtils::ReadFromBlocking(exec_control_[0], message, kMaxMessageSize); |
| 703 message[kMaxMessageSize - 1] = '\0'; | 710 message[kMaxMessageSize - 1] = '\0'; |
| 704 *os_error_message_ = message; | 711 *os_error_message_ = message; |
| 705 } else { | 712 } else { |
| 706 // Could not get error message. It will be NULL. | 713 // Could not get error message. It will be NULL. |
| 707 ASSERT(*os_error_message_ == NULL); | 714 ASSERT(*os_error_message_ == NULL); |
| 708 } | 715 } |
| 709 } | 716 } |
| 710 | 717 |
| (...skipping 352 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1063 bzero(&act, sizeof(act)); | 1070 bzero(&act, sizeof(act)); |
| 1064 act.sa_handler = SIG_DFL; | 1071 act.sa_handler = SIG_DFL; |
| 1065 VOID_NO_RETRY_EXPECTED(sigaction(signal, &act, NULL)); | 1072 VOID_NO_RETRY_EXPECTED(sigaction(signal, &act, NULL)); |
| 1066 } | 1073 } |
| 1067 } | 1074 } |
| 1068 | 1075 |
| 1069 } // namespace bin | 1076 } // namespace bin |
| 1070 } // namespace dart | 1077 } // namespace dart |
| 1071 | 1078 |
| 1072 #endif // defined(TARGET_OS_MACOS) | 1079 #endif // defined(TARGET_OS_MACOS) |
| OLD | NEW |