Index: runtime/bin/process_android.cc |
diff --git a/runtime/bin/process_android.cc b/runtime/bin/process_android.cc |
index b1dea83787bd8485469d9d6a9d30dd58bea9e4c2..9265531678c6c13bfaac87b8373f01d897e41a4b 100644 |
--- a/runtime/bin/process_android.cc |
+++ b/runtime/bin/process_android.cc |
@@ -24,6 +24,9 @@ |
#include "platform/signal_blocker.h" |
+extern char **environ; |
+ |
+ |
namespace dart { |
namespace bin { |
@@ -151,7 +154,7 @@ class ExitCodeHandler { |
// Fork to wake up waitpid. |
if (TEMP_FAILURE_RETRY(fork()) == 0) { |
- _exit(0); |
+ exit(0); |
} |
monitor_->Notify(); |
@@ -411,7 +414,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(); |
@@ -440,14 +443,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(); |
} |
@@ -499,13 +500,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); |
} |
} |
@@ -535,7 +536,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; |
@@ -559,7 +560,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; |
@@ -649,12 +650,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 os_error_message[kBufferSize]; |
+ strerror_r(errno, os_error_message, 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); |
} |
@@ -668,16 +678,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); |
} |
} |