Merge "Log stderr of secilc" am: 8b4e7fe486 am: 590cf28434
am: c27f611ea6
Change-Id: I70fd5c8e3ecdb45e60c35d3637fc1c032d7d15e8
This commit is contained in:
commit
194bc63db4
1 changed files with 46 additions and 0 deletions
|
|
@ -621,11 +621,21 @@ static int audit_callback(void *data, security_class_t /*cls*/, char *buf, size_
|
|||
|
||||
/*
|
||||
* Forks, executes the provided program in the child, and waits for the completion in the parent.
|
||||
* Child's stderr is captured and logged using LOG(ERROR).
|
||||
*
|
||||
* Returns true if the child exited with status code 0, returns false otherwise.
|
||||
*/
|
||||
static bool fork_execve_and_wait_for_completion(const char* filename, char* const argv[],
|
||||
char* const envp[]) {
|
||||
// Create a pipe used for redirecting child process's output.
|
||||
// * pipe_fds[0] is the FD the parent will use for reading.
|
||||
// * pipe_fds[1] is the FD the child will use for writing.
|
||||
int pipe_fds[2];
|
||||
if (pipe(pipe_fds) == -1) {
|
||||
PLOG(ERROR) << "Failed to create pipe";
|
||||
return false;
|
||||
}
|
||||
|
||||
pid_t child_pid = fork();
|
||||
if (child_pid == -1) {
|
||||
PLOG(ERROR) << "Failed to fork for " << filename;
|
||||
|
|
@ -634,6 +644,18 @@ static bool fork_execve_and_wait_for_completion(const char* filename, char* cons
|
|||
|
||||
if (child_pid == 0) {
|
||||
// fork succeeded -- this is executing in the child process
|
||||
|
||||
// Close the pipe FD not used by this process
|
||||
TEMP_FAILURE_RETRY(close(pipe_fds[0]));
|
||||
|
||||
// Redirect stderr to the pipe FD provided by the parent
|
||||
if (TEMP_FAILURE_RETRY(dup2(pipe_fds[1], STDERR_FILENO)) == -1) {
|
||||
PLOG(ERROR) << "Failed to redirect stderr of " << filename;
|
||||
_exit(127);
|
||||
return false;
|
||||
}
|
||||
TEMP_FAILURE_RETRY(close(pipe_fds[1]));
|
||||
|
||||
if (execve(filename, argv, envp) == -1) {
|
||||
PLOG(ERROR) << "Failed to execve " << filename;
|
||||
return false;
|
||||
|
|
@ -644,6 +666,30 @@ static bool fork_execve_and_wait_for_completion(const char* filename, char* cons
|
|||
return false;
|
||||
} else {
|
||||
// fork succeeded -- this is executing in the original/parent process
|
||||
|
||||
// Close the pipe FD not used by this process
|
||||
TEMP_FAILURE_RETRY(close(pipe_fds[1]));
|
||||
|
||||
// Log the redirected output of the child process.
|
||||
// It's unfortunate that there's no standard way to obtain an istream for a file descriptor.
|
||||
// As a result, we're buffering all output and logging it in one go at the end of the
|
||||
// invocation, instead of logging it as it comes in.
|
||||
const int child_out_fd = pipe_fds[0];
|
||||
std::string child_output;
|
||||
if (!android::base::ReadFdToString(child_out_fd, &child_output)) {
|
||||
PLOG(ERROR) << "Failed to capture full output of " << filename;
|
||||
}
|
||||
TEMP_FAILURE_RETRY(close(child_out_fd));
|
||||
if (!child_output.empty()) {
|
||||
// Log captured output, line by line, because LOG expects to be invoked for each line
|
||||
std::istringstream in(child_output);
|
||||
std::string line;
|
||||
while (std::getline(in, line)) {
|
||||
LOG(ERROR) << filename << ": " << line;
|
||||
}
|
||||
}
|
||||
|
||||
// Wait for child to terminate
|
||||
int status;
|
||||
if (TEMP_FAILURE_RETRY(waitpid(child_pid, &status, 0)) != child_pid) {
|
||||
PLOG(ERROR) << "Failed to wait for " << filename;
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue