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 |