Home | History | Annotate | Download | only in logwrapper
      1 /*
      2  * Copyright (C) 2008 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 #include <errno.h>
     18 #include <stdio.h>
     19 #include <stdlib.h>
     20 #include <sys/wait.h>
     21 #include <unistd.h>
     22 
     23 #include <logwrap/logwrap.h>
     24 #include <cutils/klog.h>
     25 
     26 #include "cutils/log.h"
     27 
     28 void fatal(const char *msg) {
     29     fprintf(stderr, "%s", msg);
     30     ALOG(LOG_ERROR, "logwrapper", "%s", msg);
     31     exit(-1);
     32 }
     33 
     34 void usage() {
     35     fatal(
     36         "Usage: logwrapper [-a] [-d] [-k] BINARY [ARGS ...]\n"
     37         "\n"
     38         "Forks and executes BINARY ARGS, redirecting stdout and stderr to\n"
     39         "the Android logging system. Tag is set to BINARY, priority is\n"
     40         "always LOG_INFO.\n"
     41         "\n"
     42         "-a: Causes logwrapper to do abbreviated logging.\n"
     43         "    This logs up to the first 4K and last 4K of the command\n"
     44         "    being run, and logs the output when the command exits\n"
     45         "-d: Causes logwrapper to SIGSEGV when BINARY terminates\n"
     46         "    fault address is set to the status of wait()\n"
     47         "-k: Causes logwrapper to log to the kernel log instead of\n"
     48         "    the Android system log\n");
     49 }
     50 
     51 int main(int argc, char* argv[]) {
     52     int seg_fault_on_exit = 0;
     53     int log_target = LOG_ALOG;
     54     bool abbreviated = false;
     55     int ch;
     56     int status = 0xAAAA;
     57     int rc;
     58 
     59     while ((ch = getopt(argc, argv, "adk")) != -1) {
     60         switch (ch) {
     61             case 'a':
     62                 abbreviated = true;
     63                 break;
     64             case 'd':
     65                 seg_fault_on_exit = 1;
     66                 break;
     67             case 'k':
     68                 log_target = LOG_KLOG;
     69                 klog_set_level(6);
     70                 break;
     71             case '?':
     72             default:
     73               usage();
     74         }
     75     }
     76     argc -= optind;
     77     argv += optind;
     78 
     79     if (argc < 1) {
     80         usage();
     81     }
     82 
     83     rc = android_fork_execvp_ext(argc, &argv[0], &status, true,
     84                                  log_target, abbreviated, NULL);
     85     if (!rc) {
     86         if (WIFEXITED(status))
     87             rc = WEXITSTATUS(status);
     88         else
     89             rc = -ECHILD;
     90     }
     91 
     92     if (seg_fault_on_exit) {
     93         uintptr_t fault_address = (uintptr_t) status;
     94         *(int *) fault_address = 0;  // causes SIGSEGV with fault_address = status
     95     }
     96 
     97     return rc;
     98 }
     99