Index: runtime/bin/process_linux.cc |
diff --git a/runtime/bin/process_linux.cc b/runtime/bin/process_linux.cc |
index 879c973c5a318b15badb764a7f365cd7c373b3f9..cd9c639b9fa6abdb9bee4784a50faa7c8e3996cd 100644 |
--- a/runtime/bin/process_linux.cc |
+++ b/runtime/bin/process_linux.cc |
@@ -23,6 +23,9 @@ |
#include "bin/thread.h" |
+extern char **environ; |
+ |
+ |
namespace dart { |
namespace bin { |
@@ -150,7 +153,7 @@ class ExitCodeHandler { |
// Fork to wake up waitpid. |
if (TEMP_FAILURE_RETRY(fork()) == 0) { |
- _exit(0); |
+ exit(0); |
} |
monitor_->Notify(); |
@@ -410,7 +413,7 @@ class ProcessStarter { |
int bytes_read = FDUtils::ReadFromBlocking(read_in_[0], &msg, sizeof(msg)); |
if (bytes_read != sizeof(msg)) { |
perror("Failed receiving notification message"); |
- _exit(1); |
+ exit(1); |
} |
if (mode_ == kNormal) { |
ExecProcess(); |
@@ -439,14 +442,12 @@ class ProcessStarter { |
} |
if (program_environment_ != NULL) { |
- VOID_TEMP_FAILURE_RETRY( |
- execvpe(path_, const_cast<char* const*>(program_arguments_), |
- program_environment_)); |
- } else { |
- VOID_TEMP_FAILURE_RETRY( |
- execvp(path_, const_cast<char* const*>(program_arguments_))); |
+ environ = program_environment_; |
} |
+ VOID_TEMP_FAILURE_RETRY( |
+ execvp(path_, const_cast<char* const*>(program_arguments_))); |
+ |
ReportChildError(); |
} |
@@ -498,13 +499,13 @@ class ProcessStarter { |
execvp(path_, const_cast<char* const*>(program_arguments_))); |
ReportChildError(); |
} else { |
- // Exit the intermediate process. |
- _exit(0); |
+ // Exit the intermeiate process. |
+ exit(0); |
} |
} |
} else { |
- // Exit the intermediate process. |
- _exit(0); |
+ // Exit the intermeiate process. |
+ exit(0); |
} |
} |
@@ -534,7 +535,7 @@ class ProcessStarter { |
FDUtils::ReadFromBlocking( |
exec_control_[0], &child_errno, sizeof(child_errno)); |
if (bytes_read == sizeof(child_errno)) { |
- SetOSErrorMessage(child_errno); |
+ ReadChildError(); |
return child_errno; |
} else if (bytes_read == -1) { |
return errno; |
@@ -558,7 +559,7 @@ class ProcessStarter { |
} else if (bytes_read == 2 * sizeof(int)) { |
*pid = result[0]; |
child_errno = result[1]; |
- SetOSErrorMessage(child_errno); |
+ ReadChildError(); |
return child_errno; |
} else if (bytes_read == -1) { |
return errno; |
@@ -647,12 +648,21 @@ class ProcessStarter { |
void ReportChildError() { |
- // In the case of failure in the child process write the errno to the exec |
- // control pipe and exit. |
+ // In the case of failure in the child process write the errno and |
+ // the OS error message to the exec control pipe and exit. |
int child_errno = errno; |
- FDUtils::WriteToBlocking( |
- exec_control_[1], &child_errno, sizeof(child_errno)); |
- _exit(1); |
+ const int kBufferSize = 1024; |
+ char error_buf[kBufferSize]; |
+ char* os_error_message = strerror_r(errno, error_buf, kBufferSize); |
+ int bytes_written = |
+ FDUtils::WriteToBlocking( |
+ exec_control_[1], &child_errno, sizeof(child_errno)); |
+ if (bytes_written == sizeof(child_errno)) { |
+ FDUtils::WriteToBlocking( |
+ exec_control_[1], os_error_message, strlen(os_error_message) + 1); |
+ } |
+ VOID_TEMP_FAILURE_RETRY(close(exec_control_[1])); |
+ exit(1); |
} |
@@ -666,16 +676,16 @@ class ProcessStarter { |
} |
- void SetOSErrorMessage(int child_errno) { |
+ void ReadChildError() { |
const int kMaxMessageSize = 256; |
- char* message = static_cast<char*>(calloc(kMaxMessageSize, 0)); |
- char* os_error_message = strerror_r( |
- child_errno, message, kMaxMessageSize - 1); |
- if (message == os_error_message) { |
+ char* message = static_cast<char*>(malloc(kMaxMessageSize)); |
+ if (message != NULL) { |
+ FDUtils::ReadFromBlocking(exec_control_[0], message, kMaxMessageSize); |
+ message[kMaxMessageSize - 1] = '\0'; |
*os_error_message_ = message; |
} else { |
- free(message); |
- *os_error_message_ = strdup(os_error_message); |
+ // Could not get error message. It will be NULL. |
+ ASSERT(*os_error_message_ == NULL); |
} |
} |