Skip to content

Commit

Permalink
Clean up process spawning.
Browse files Browse the repository at this point in the history
Pass environment as argument to execvpe and use _exit instead of exit
(so fork/vfork can be used interchangeable).

BUG=
R=sgjesse@google.com

Review URL: https://codereview.chromium.org//1156313004.
  • Loading branch information
Anders Johnsen committed Jun 10, 2015
1 parent 6a85394 commit bbdc57e
Show file tree
Hide file tree
Showing 4 changed files with 83 additions and 124 deletions.
62 changes: 26 additions & 36 deletions runtime/bin/process_android.cc
Expand Up @@ -24,9 +24,6 @@
#include "platform/signal_blocker.h"


extern char **environ;


namespace dart {
namespace bin {

Expand Down Expand Up @@ -154,7 +151,7 @@ class ExitCodeHandler {

// Fork to wake up waitpid.
if (TEMP_FAILURE_RETRY(fork()) == 0) {
exit(0);
_exit(0);
}

monitor_->Notify();
Expand Down Expand Up @@ -414,7 +411,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();
Expand Down Expand Up @@ -443,12 +440,14 @@ class ProcessStarter {
}

if (program_environment_ != NULL) {
environ = program_environment_;
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_)));
}

VOID_TEMP_FAILURE_RETRY(
execvp(path_, const_cast<char* const*>(program_arguments_)));

ReportChildError();
}

Expand Down Expand Up @@ -500,13 +499,13 @@ class ProcessStarter {
execvp(path_, const_cast<char* const*>(program_arguments_)));
ReportChildError();
} else {
// Exit the intermeiate process.
exit(0);
// Exit the intermediate process.
_exit(0);
}
}
} else {
// Exit the intermeiate process.
exit(0);
// Exit the intermediate process.
_exit(0);
}
}

Expand Down Expand Up @@ -536,7 +535,7 @@ class ProcessStarter {
FDUtils::ReadFromBlocking(
exec_control_[0], &child_errno, sizeof(child_errno));
if (bytes_read == sizeof(child_errno)) {
ReadChildError();
SetOSErrorMessage(child_errno);
return child_errno;
} else if (bytes_read == -1) {
return errno;
Expand All @@ -560,7 +559,7 @@ class ProcessStarter {
} else if (bytes_read == 2 * sizeof(int)) {
*pid = result[0];
child_errno = result[1];
ReadChildError();
SetOSErrorMessage(child_errno);
return child_errno;
} else if (bytes_read == -1) {
return errno;
Expand Down Expand Up @@ -650,21 +649,12 @@ class ProcessStarter {


void ReportChildError() {
// In the case of failure in the child process write the errno and
// the OS error message to the exec control pipe and exit.
// In the case of failure in the child process write the errno to the exec
// control pipe and exit.
int child_errno = errno;
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);
FDUtils::WriteToBlocking(
exec_control_[1], &child_errno, sizeof(child_errno));
_exit(1);
}


Expand All @@ -678,16 +668,16 @@ class ProcessStarter {
}


void ReadChildError() {
void SetOSErrorMessage(int child_errno) {
const int kMaxMessageSize = 256;
char* message = static_cast<char*>(malloc(kMaxMessageSize));
if (message != NULL) {
FDUtils::ReadFromBlocking(exec_control_[0], message, kMaxMessageSize);
message[kMaxMessageSize - 1] = '\0';
char* message = static_cast<char*>(calloc(kMaxMessageSize, 0));
char* os_error_message = strerror_r(
child_errno, message, kMaxMessageSize - 1);
if (message == os_error_message) {
*os_error_message_ = message;
} else {
// Could not get error message. It will be NULL.
ASSERT(*os_error_message_ == NULL);
free(message);
*os_error_message_ = strdup(os_error_message);
}
}

Expand Down
62 changes: 26 additions & 36 deletions runtime/bin/process_linux.cc
Expand Up @@ -23,9 +23,6 @@
#include "bin/thread.h"


extern char **environ;


namespace dart {
namespace bin {

Expand Down Expand Up @@ -153,7 +150,7 @@ class ExitCodeHandler {

// Fork to wake up waitpid.
if (TEMP_FAILURE_RETRY(fork()) == 0) {
exit(0);
_exit(0);
}

monitor_->Notify();
Expand Down Expand Up @@ -413,7 +410,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();
Expand Down Expand Up @@ -442,12 +439,14 @@ class ProcessStarter {
}

if (program_environment_ != NULL) {
environ = program_environment_;
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_)));
}

VOID_TEMP_FAILURE_RETRY(
execvp(path_, const_cast<char* const*>(program_arguments_)));

ReportChildError();
}

Expand Down Expand Up @@ -499,13 +498,13 @@ class ProcessStarter {
execvp(path_, const_cast<char* const*>(program_arguments_)));
ReportChildError();
} else {
// Exit the intermeiate process.
exit(0);
// Exit the intermediate process.
_exit(0);
}
}
} else {
// Exit the intermeiate process.
exit(0);
// Exit the intermediate process.
_exit(0);
}
}

Expand Down Expand Up @@ -535,7 +534,7 @@ class ProcessStarter {
FDUtils::ReadFromBlocking(
exec_control_[0], &child_errno, sizeof(child_errno));
if (bytes_read == sizeof(child_errno)) {
ReadChildError();
SetOSErrorMessage(child_errno);
return child_errno;
} else if (bytes_read == -1) {
return errno;
Expand All @@ -559,7 +558,7 @@ class ProcessStarter {
} else if (bytes_read == 2 * sizeof(int)) {
*pid = result[0];
child_errno = result[1];
ReadChildError();
SetOSErrorMessage(child_errno);
return child_errno;
} else if (bytes_read == -1) {
return errno;
Expand Down Expand Up @@ -648,21 +647,12 @@ class ProcessStarter {


void ReportChildError() {
// In the case of failure in the child process write the errno and
// the OS error message to the exec control pipe and exit.
// In the case of failure in the child process write the errno to the exec
// control pipe and exit.
int child_errno = errno;
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);
FDUtils::WriteToBlocking(
exec_control_[1], &child_errno, sizeof(child_errno));
_exit(1);
}


Expand All @@ -676,16 +666,16 @@ class ProcessStarter {
}


void ReadChildError() {
void SetOSErrorMessage(int child_errno) {
const int kMaxMessageSize = 256;
char* message = static_cast<char*>(malloc(kMaxMessageSize));
if (message != NULL) {
FDUtils::ReadFromBlocking(exec_control_[0], message, kMaxMessageSize);
message[kMaxMessageSize - 1] = '\0';
char* message = static_cast<char*>(calloc(kMaxMessageSize, 0));
char* os_error_message = strerror_r(
child_errno, message, kMaxMessageSize - 1);
if (message == os_error_message) {
*os_error_message_ = message;
} else {
// Could not get error message. It will be NULL.
ASSERT(*os_error_message_ == NULL);
free(message);
*os_error_message_ = strdup(os_error_message);
}
}

Expand Down

0 comments on commit bbdc57e

Please sign in to comment.