Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 590cf284 authored by Alex Klyubin's avatar Alex Klyubin Committed by android-build-merger
Browse files

Merge "Log stderr of secilc"

am: 8b4e7fe4

Change-Id: Ifb78f10609d36e4f20a45745f77e075d439ed861
parents 63b22a3e 8b4e7fe4
Loading
Loading
Loading
Loading
+46 −0
Original line number Diff line number Diff line
@@ -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;