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

Commit b0bbc97b authored by Tom Cherry's avatar Tom Cherry Committed by android-build-merger
Browse files

logwrap: convert to C++, rename function logwrap_fork_execvp().

am: ff7d067f

Change-Id: I2ee848ca9fabc69b22b563e098b3dcc81d00a7e4
parents a5e0b3b3 ff7d067f
Loading
Loading
Loading
Loading
+5 −3
Original line number Diff line number Diff line
@@ -13,11 +13,12 @@ cc_library {
    name: "liblogwrap",
    defaults: ["logwrapper_defaults"],
    recovery_available: true,
    srcs: ["logwrap.c"],
    srcs: ["logwrap.cpp"],
    shared_libs: [
        "libcutils",
        "liblog",
    ],
    header_libs: ["libbase_headers"],
    export_include_dirs: ["include"],
    local_include_dirs: ["include"],
}
@@ -31,9 +32,10 @@ cc_defaults {
    defaults: ["logwrapper_defaults"],
    local_include_dirs: ["include"],
    srcs: [
        "logwrap.c",
        "logwrapper.c",
        "logwrap.cpp",
        "logwrapper.cpp",
    ],
    header_libs: ["libbase_headers"],
    shared_libs: ["libcutils", "liblog"],
}

+10 −18
Original line number Diff line number Diff line
@@ -17,11 +17,6 @@

#pragma once

#include <stdbool.h>
#include <stdint.h>

__BEGIN_DECLS

/*
 * Run a command while logging its stdout and stderr
 *
@@ -56,35 +51,32 @@ __BEGIN_DECLS
 *
 */

/* Values for the log_target parameter android_fork_execvp_ext() */
/* Values for the log_target parameter logwrap_fork_execvp() */
#define LOG_NONE        0
#define LOG_ALOG        1
#define LOG_KLOG        2
#define LOG_FILE        4

int android_fork_execvp_ext2(int argc, char* argv[], int* status, bool forward_signals,
                             int log_target, bool abbreviated, char* file_path);
int logwrap_fork_execvp(int argc, const char* const* argv, int* status, bool forward_signals,
                        int log_target, bool abbreviated, const char* file_path);

// TODO: Actually deprecate this and the below.
static inline int android_fork_execvp_ext(int argc, char* argv[], int* status, bool ignore_int_quit,
                                          int log_target, bool abbreviated, char* file_path,
                                          int log_target, bool abbreviated, const char* file_path,
                                          void* unused_opts, int unused_opts_len) {
    (void)ignore_int_quit;
    (void)unused_opts;
    (void)unused_opts_len;
    return android_fork_execvp_ext2(argc, argv, status, false, log_target, abbreviated, file_path);
    return logwrap_fork_execvp(argc, argv, status, false, log_target, abbreviated, file_path);
}

/* Similar to above, except abbreviated logging is not available, and if logwrap
 * is true, logging is to the Android system log, and if false, there is no
 * logging.
 */
static inline int android_fork_execvp(int argc, char* argv[], int *status,
                                     bool ignore_int_quit, bool logwrap)
{
    return android_fork_execvp_ext(argc, argv, status, ignore_int_quit,
                                   (logwrap ? LOG_ALOG : LOG_NONE), false, NULL,
                                   NULL, 0);
static inline int android_fork_execvp(int argc, char* argv[], int* status, bool ignore_int_quit,
                                      bool logwrap) {
    (void)ignore_int_quit;
    return logwrap_fork_execvp(argc, argv, status, false, (logwrap ? LOG_ALOG : LOG_NONE), false,
                               nullptr);
}

__END_DECLS
+86 −95
Original line number Diff line number Diff line
@@ -19,7 +19,6 @@
#include <libgen.h>
#include <poll.h>
#include <pthread.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -28,13 +27,13 @@
#include <sys/wait.h>
#include <unistd.h>

#include <algorithm>

#include <android-base/macros.h>
#include <cutils/klog.h>
#include <log/log.h>
#include <logwrap/logwrap.h>

#define ARRAY_SIZE(x)   (sizeof(x) / sizeof(*(x)))
#define MIN(a,b) (((a)<(b))?(a):(b))

static pthread_mutex_t fd_mutex = PTHREAD_MUTEX_INITIALIZER;
// Protected by fd_mutex.  These signals must be blocked while modifying as well.
static pid_t child_pid;
@@ -95,7 +94,7 @@ struct abbr_buf {
struct log_info {
    int log_target;
    char klog_fmt[MAX_KLOG_TAG * 2];
    char *btag;
    const char* btag;
    bool abbreviated;
    FILE* fp;
    struct abbr_buf a_buf;
@@ -105,9 +104,7 @@ struct log_info {
static void add_line_to_abbr_buf(struct abbr_buf* a_buf, char* linebuf, int linelen);

/* Return 0 on success, and 1 when full */
static int add_line_to_linear_buf(struct beginning_buf *b_buf,
                                   char *line, ssize_t line_len)
{
static int add_line_to_linear_buf(struct beginning_buf* b_buf, char* line, ssize_t line_len) {
    int full = 0;

    if ((line_len + b_buf->used_len) > b_buf->buf_size) {
@@ -121,14 +118,12 @@ static int add_line_to_linear_buf(struct beginning_buf *b_buf,
    return full;
}

static void add_line_to_circular_buf(struct ending_buf *e_buf,
                                     char *line, ssize_t line_len)
{
static void add_line_to_circular_buf(struct ending_buf* e_buf, char* line, ssize_t line_len) {
    ssize_t free_len;
    ssize_t needed_space;
    int cnt;

    if (e_buf->buf == NULL) {
    if (e_buf->buf == nullptr) {
        return;
    }

@@ -149,7 +144,7 @@ static void add_line_to_circular_buf(struct ending_buf *e_buf,
    /* Copy the line into the circular buffer, dealing with possible
     * wraparound.
     */
    cnt = MIN(line_len, e_buf->buf_size - e_buf->write);
    cnt = std::min(line_len, e_buf->buf_size - e_buf->write);
    memcpy(e_buf->buf + e_buf->write, line, cnt);
    if (cnt < line_len) {
        memcpy(e_buf->buf, line + cnt, line_len - cnt);
@@ -159,7 +154,7 @@ static void add_line_to_circular_buf(struct ending_buf *e_buf,
}

/* Log directly to the specified log */
static void do_log_line(struct log_info *log_info, char *line) {
static void do_log_line(struct log_info* log_info, const char* line) {
    if (log_info->log_target & LOG_KLOG) {
        klog_write(6, log_info->klog_fmt, line);
    }
@@ -189,8 +184,7 @@ static void log_line(struct log_info *log_info, char *line, int len) {
 * than buf_size (the usable size of the buffer) to make sure there is
 * room to temporarily stuff a null byte to terminate a line for logging.
 */
static void print_buf_lines(struct log_info *log_info, char *buf, int buf_size)
{
static void print_buf_lines(struct log_info* log_info, char* buf, int buf_size) {
    char* line_start;
    char c;
    int i;
@@ -221,13 +215,13 @@ static void init_abbr_buf(struct abbr_buf *a_buf) {
    char* new_buf;

    memset(a_buf, 0, sizeof(struct abbr_buf));
    new_buf = malloc(BEGINNING_BUF_SIZE);
    new_buf = static_cast<char*>(malloc(BEGINNING_BUF_SIZE));
    if (new_buf) {
        a_buf->b_buf.buf = new_buf;
        a_buf->b_buf.alloc_len = BEGINNING_BUF_SIZE;
        a_buf->b_buf.buf_size = BEGINNING_BUF_SIZE - 1;
    }
    new_buf = malloc(ENDING_BUF_SIZE);
    new_buf = static_cast<char*>(malloc(ENDING_BUF_SIZE));
    if (new_buf) {
        a_buf->e_buf.buf = new_buf;
        a_buf->e_buf.alloc_len = ENDING_BUF_SIZE;
@@ -242,8 +236,7 @@ static void free_abbr_buf(struct abbr_buf *a_buf) {

static void add_line_to_abbr_buf(struct abbr_buf* a_buf, char* linebuf, int linelen) {
    if (!a_buf->beginning_buf_full) {
        a_buf->beginning_buf_full =
            add_line_to_linear_buf(&a_buf->b_buf, linebuf, linelen);
        a_buf->beginning_buf_full = add_line_to_linear_buf(&a_buf->b_buf, linebuf, linelen);
    }
    if (a_buf->beginning_buf_full) {
        add_line_to_circular_buf(&a_buf->e_buf, linebuf, linelen);
@@ -274,14 +267,13 @@ static void print_abbr_buf(struct log_info *log_info) {
     * and then cal print_buf_lines on it */
    if (a_buf->e_buf.read < a_buf->e_buf.write) {
        /* no wrap around, just print it */
        print_buf_lines(log_info, a_buf->e_buf.buf + a_buf->e_buf.read,
                        a_buf->e_buf.used_len);
        print_buf_lines(log_info, a_buf->e_buf.buf + a_buf->e_buf.read, a_buf->e_buf.used_len);
    } else {
        /* The circular buffer will always have at least 1 byte unused,
         * so by allocating alloc_len here we will have at least
         * 1 byte of space available as required by print_buf_lines().
         */
        char * nbuf = malloc(a_buf->e_buf.alloc_len);
        char* nbuf = static_cast<char*>(malloc(a_buf->e_buf.alloc_len));
        if (!nbuf) {
            return;
        }
@@ -307,7 +299,7 @@ static void block_signals(sigset_t* oldset) {
}

static void unblock_signals(sigset_t* oldset) {
    pthread_sigmask(SIG_SETMASK, oldset, NULL);
    pthread_sigmask(SIG_SETMASK, oldset, nullptr);
}

static void setup_signal_handlers(pid_t pid) {
@@ -320,9 +312,9 @@ static void setup_signal_handlers(pid_t pid) {
}

static void restore_signal_handlers() {
    sigaction(SIGINT, &old_int, NULL);
    sigaction(SIGQUIT, &old_quit, NULL);
    sigaction(SIGHUP, &old_hup, NULL);
    sigaction(SIGINT, &old_int, nullptr);
    sigaction(SIGQUIT, &old_quit, nullptr);
    sigaction(SIGHUP, &old_hup, nullptr);
    child_pid = 0;
}

@@ -334,11 +326,11 @@ static void signal_handler(int signal_num) {
}

static int parent(const char* tag, int parent_read, pid_t pid, int* chld_sts, int log_target,
                  bool abbreviated, char* file_path, bool forward_signals) {
                  bool abbreviated, const char* file_path, bool forward_signals) {
    int status = 0;
    char buffer[4096];
    struct pollfd poll_fds[] = {
        [0] = {
            {
                    .fd = parent_read,
                    .events = POLLIN,
            },
@@ -361,7 +353,7 @@ static int parent(const char* tag, int parent_read, pid_t pid, int* chld_sts, in

    log_info.btag = basename(tag);
    if (!log_info.btag) {
        log_info.btag = (char*) tag;
        log_info.btag = tag;
    }

    if (abbreviated && (log_target == LOG_NONE)) {
@@ -372,8 +364,8 @@ static int parent(const char* tag, int parent_read, pid_t pid, int* chld_sts, in
    }

    if (log_target & LOG_KLOG) {
        snprintf(log_info.klog_fmt, sizeof(log_info.klog_fmt),
                 "<6>%.*s: %%s\n", MAX_KLOG_TAG, log_info.btag);
        snprintf(log_info.klog_fmt, sizeof(log_info.klog_fmt), "<6>%.*s: %%s\n", MAX_KLOG_TAG,
                 log_info.btag);
    }

    if ((log_target & LOG_FILE) && !file_path) {
@@ -397,7 +389,7 @@ static int parent(const char* tag, int parent_read, pid_t pid, int* chld_sts, in

    while (!found_child) {
        int timeout = received_messages ? -1 : 1000;
        if (TEMP_FAILURE_RETRY(poll(poll_fds, ARRAY_SIZE(poll_fds), timeout)) < 0) {
        if (TEMP_FAILURE_RETRY(poll(poll_fds, arraysize(poll_fds), timeout)) < 0) {
            ERROR("poll failed\n");
            rc = -1;
            goto err_poll;
@@ -405,8 +397,7 @@ static int parent(const char* tag, int parent_read, pid_t pid, int* chld_sts, in

        if (poll_fds[0].revents & POLLIN) {
            received_messages = true;
            sz = TEMP_FAILURE_RETRY(
                read(parent_read, &buffer[b], sizeof(buffer) - 1 - b));
            sz = TEMP_FAILURE_RETRY(read(parent_read, &buffer[b], sizeof(buffer) - 1 - b));

            sz += b;
            // Log one line at a time
@@ -479,7 +470,7 @@ static int parent(const char* tag, int parent_read, pid_t pid, int* chld_sts, in
        }
    }

    if (chld_sts != NULL) {
    if (chld_sts != nullptr) {
        *chld_sts = status;
    } else {
        if (WIFEXITED(status))
@@ -501,18 +492,18 @@ static int parent(const char* tag, int parent_read, pid_t pid, int* chld_sts, in

    if (WIFEXITED(status)) {
        if (WEXITSTATUS(status)) {
        snprintf(tmpbuf, sizeof(tmpbuf),
                 "%s terminated by exit(%d)\n", log_info.btag, WEXITSTATUS(status));
            snprintf(tmpbuf, sizeof(tmpbuf), "%s terminated by exit(%d)\n", log_info.btag,
                     WEXITSTATUS(status));
            do_log_line(&log_info, tmpbuf);
        }
    } else {
        if (WIFSIGNALED(status)) {
        snprintf(tmpbuf, sizeof(tmpbuf),
                       "%s terminated by signal %d\n", log_info.btag, WTERMSIG(status));
            snprintf(tmpbuf, sizeof(tmpbuf), "%s terminated by signal %d\n", log_info.btag,
                     WTERMSIG(status));
            do_log_line(&log_info, tmpbuf);
        } else if (WIFSTOPPED(status)) {
        snprintf(tmpbuf, sizeof(tmpbuf),
                       "%s stopped by signal %d\n", log_info.btag, WSTOPSIG(status));
            snprintf(tmpbuf, sizeof(tmpbuf), "%s stopped by signal %d\n", log_info.btag,
                     WSTOPSIG(status));
            do_log_line(&log_info, tmpbuf);
        }
    }
@@ -528,23 +519,21 @@ err_poll:
    return rc;
}

static void child(int argc, char* argv[]) {
static void child(int argc, const char* const* argv) {
    // create null terminated argv_child array
    char* argv_child[argc + 1];
    memcpy(argv_child, argv, argc * sizeof(char*));
    argv_child[argc] = NULL;
    argv_child[argc] = nullptr;

    if (execvp(argv_child[0], argv_child)) {
        FATAL_CHILD("executing %s failed: %s\n", argv_child[0],
                strerror(errno));
        FATAL_CHILD("executing %s failed: %s\n", argv_child[0], strerror(errno));
    }
}

int android_fork_execvp_ext2(int argc, char* argv[], int* status, bool forward_signals,
                             int log_target, bool abbreviated, char* file_path) {
int logwrap_fork_execvp(int argc, const char* const* argv, int* status, bool forward_signals,
                        int log_target, bool abbreviated, const char* file_path) {
    pid_t pid;
    int parent_ptty;
    sigset_t blockset;
    sigset_t oldset;
    int rc = 0;

@@ -582,7 +571,9 @@ int android_fork_execvp_ext2(int argc, char* argv[], int* status, bool forward_s
        goto err_fork;
    } else if (pid == 0) {
        pthread_mutex_unlock(&fd_mutex);
        if (forward_signals) {
            unblock_signals(&oldset);
        }

        setsid();

+18 −19
Original line number Diff line number Diff line
@@ -31,8 +31,7 @@ void fatal(const char *msg) {
}

void usage() {
    fatal(
        "Usage: logwrapper [-a] [-d] [-k] BINARY [ARGS ...]\n"
    fatal("Usage: logwrapper [-a] [-d] [-k] BINARY [ARGS ...]\n"
          "\n"
          "Forks and executes BINARY ARGS, redirecting stdout and stderr to\n"
          "the Android logging system. Tag is set to BINARY, priority is\n"
@@ -79,7 +78,7 @@ int main(int argc, char* argv[]) {
        usage();
    }

    rc = android_fork_execvp_ext2(argc, &argv[0], &status, true, log_target, abbreviated, NULL);
    rc = logwrap_fork_execvp(argc, &argv[0], &status, true, log_target, abbreviated, nullptr);
    if (!rc) {
        if (WIFEXITED(status))
            rc = WEXITSTATUS(status);