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 #include <crt_externs.h> // NOLINT | 10 #include <crt_externs.h> // NOLINT |
(...skipping 434 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
445 if (TEMP_FAILURE_RETRY(dup2(read_err_[1], STDERR_FILENO)) == -1) { | 445 if (TEMP_FAILURE_RETRY(dup2(read_err_[1], STDERR_FILENO)) == -1) { |
446 ReportChildError(); | 446 ReportChildError(); |
447 } | 447 } |
448 | 448 |
449 if (working_directory_ != NULL && | 449 if (working_directory_ != NULL && |
450 TEMP_FAILURE_RETRY(chdir(working_directory_)) == -1) { | 450 TEMP_FAILURE_RETRY(chdir(working_directory_)) == -1) { |
451 ReportChildError(); | 451 ReportChildError(); |
452 } | 452 } |
453 | 453 |
454 if (program_environment_ != NULL) { | 454 if (program_environment_ != NULL) { |
455 environ = program_environment_; | 455 // On MacOS you have to do a bit of magic to get to the |
| 456 // environment strings. |
| 457 char*** environ = _NSGetEnviron(); |
| 458 *environ = program_environment_; |
456 } | 459 } |
457 | 460 |
458 VOID_TEMP_FAILURE_RETRY( | 461 VOID_TEMP_FAILURE_RETRY( |
459 execvp(path_, const_cast<char* const*>(program_arguments_))); | 462 execvp(path_, const_cast<char* const*>(program_arguments_))); |
460 | 463 |
461 ReportChildError(); | 464 ReportChildError(); |
462 } | 465 } |
463 | 466 |
464 | 467 |
465 void ExecDetachedProcess() { | 468 void ExecDetachedProcess() { |
(...skipping 180 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
646 // If CleanupAndReturnError is called without an actual errno make | 649 // If CleanupAndReturnError is called without an actual errno make |
647 // sure to return an error anyway. | 650 // sure to return an error anyway. |
648 if (actual_errno == 0) actual_errno = EPERM; | 651 if (actual_errno == 0) actual_errno = EPERM; |
649 SetChildOsErrorMessage(); | 652 SetChildOsErrorMessage(); |
650 CloseAllPipes(); | 653 CloseAllPipes(); |
651 return actual_errno; | 654 return actual_errno; |
652 } | 655 } |
653 | 656 |
654 | 657 |
655 void SetChildOsErrorMessage() { | 658 void SetChildOsErrorMessage() { |
656 const int kBufferSize = 1024; | 659 SetOSErrorMessage(errno); |
657 char error_message[kBufferSize]; | |
658 strerror_r(errno, error_message, kBufferSize); | |
659 *os_error_message_ = strdup(error_message); | |
660 } | 660 } |
661 | 661 |
662 | 662 |
663 void ReportChildError() { | 663 void ReportChildError() { |
664 // In the case of failure in the child process write the errno to the exec | 664 // In the case of failure in the child process write the errno to the exec |
665 // control pipe and exit. | 665 // control pipe and exit. |
666 int child_errno = errno; | 666 int child_errno = errno; |
667 FDUtils::WriteToBlocking( | 667 FDUtils::WriteToBlocking( |
668 exec_control_[1], &child_errno, sizeof(child_errno)); | 668 exec_control_[1], &child_errno, sizeof(child_errno)); |
669 _exit(1); | 669 _exit(1); |
670 } | 670 } |
671 | 671 |
672 | 672 |
673 void ReportPid(int pid) { | 673 void ReportPid(int pid) { |
674 // In the case of starting a detached process the actual pid of that process | 674 // In the case of starting a detached process the actual pid of that process |
675 // is communicated using the exec control pipe. | 675 // is communicated using the exec control pipe. |
676 int bytes_written = | 676 int bytes_written = |
677 FDUtils::WriteToBlocking(exec_control_[1], &pid, sizeof(pid)); | 677 FDUtils::WriteToBlocking(exec_control_[1], &pid, sizeof(pid)); |
678 ASSERT(bytes_written == sizeof(int)); | 678 ASSERT(bytes_written == sizeof(int)); |
679 USE(bytes_written); | 679 USE(bytes_written); |
680 } | 680 } |
681 | 681 |
682 | 682 |
683 void SetOSErrorMessage(int child_errno) { | 683 void SetOSErrorMessage(int child_errno) { |
684 const int kMaxMessageSize = 256; | 684 const int kBufferSize = 1024; |
685 char* message = static_cast<char*>(calloc(kMaxMessageSize, 0)); | 685 char error_message[kBufferSize]; |
686 strerror_r(child_errno, message, kMaxMessageSize - 1); | 686 strerror_r(child_errno, error_message, kBufferSize); |
687 *os_error_message_ = message; | 687 *os_error_message_ = strdup(error_message); |
688 } | 688 } |
689 | 689 |
690 | 690 |
691 void ClosePipe(int* fds) { | 691 void ClosePipe(int* fds) { |
692 for (int i = 0; i < 2; i++) { | 692 for (int i = 0; i < 2; i++) { |
693 if (fds[i] != -1) { | 693 if (fds[i] != -1) { |
694 VOID_TEMP_FAILURE_RETRY(close(fds[i])); | 694 VOID_TEMP_FAILURE_RETRY(close(fds[i])); |
695 fds[i] = -1; | 695 fds[i] = -1; |
696 } | 696 } |
697 } | 697 } |
(...skipping 344 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1042 bzero(&act, sizeof(act)); | 1042 bzero(&act, sizeof(act)); |
1043 act.sa_handler = SIG_DFL; | 1043 act.sa_handler = SIG_DFL; |
1044 VOID_NO_RETRY_EXPECTED(sigaction(signal, &act, NULL)); | 1044 VOID_NO_RETRY_EXPECTED(sigaction(signal, &act, NULL)); |
1045 } | 1045 } |
1046 } | 1046 } |
1047 | 1047 |
1048 } // namespace bin | 1048 } // namespace bin |
1049 } // namespace dart | 1049 } // namespace dart |
1050 | 1050 |
1051 #endif // defined(TARGET_OS_MACOS) | 1051 #endif // defined(TARGET_OS_MACOS) |
OLD | NEW |