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 <cutils/klog.h>
     24 #include <log/log.h>
     25 #include <logwrap/logwrap.h>
     26 
     27 void fatal(const char *msg) {
     28     fprintf(stderr, "%s", msg);
     29     ALOG(LOG_ERROR, "logwrapper", "%s", msg);
     30     exit(-1);
     31 }
     32 
     33 void usage() {
     34     fatal(
     35         "Usage: logwrapper [-a] [-d] [-k] BINARY [ARGS ...]\n"
     36         "\n"
     37         "Forks and executes BINARY ARGS, redirecting stdout and stderr to\n"
     38         "the Android logging system. Tag is set to BINARY, priority is\n"
     39         "always LOG_INFO.\n"
     40         "\n"
     41         "-a: Causes logwrapper to do abbreviated logging.\n"
     42         "    This logs up to the first 4K and last 4K of the command\n"
     43         "    being run, and logs the output when the command exits\n"
     44         "-d: Causes logwrapper to SIGSEGV when BINARY terminates\n"
     45         "    fault address is set to the status of wait()\n"
     46         "-k: Causes logwrapper to log to the kernel log instead of\n"
     47         "    the Android system log\n");
     48 }
     49 
     50 int main(int argc, char* argv[]) {
     51     int seg_fault_on_exit = 0;
     52     int log_target = LOG_ALOG;
     53     bool abbreviated = false;
     54     int ch;
     55     int status = 0xAAAA;
     56     int rc;
     57 
     58     while ((ch = getopt(argc, argv, "adk")) != -1) {
     59         switch (ch) {
     60             case 'a':
     61                 abbreviated = true;
     62                 break;
     63             case 'd':
     64                 seg_fault_on_exit = 1;
     65                 break;
     66             case 'k':
     67                 log_target = LOG_KLOG;
     68                 klog_set_level(6);
     69                 break;
     70             case '?':
     71             default:
     72               usage();
     73         }
     74     }
     75     argc -= optind;
     76     argv += optind;
     77 
     78     if (argc < 1) {
     79         usage();
     80     }
     81 
     82     rc = android_fork_execvp_ext(argc, &argv[0], &status, true,
     83                                  log_target, abbreviated, NULL, NULL, 0);
     84     if (!rc) {
     85         if (WIFEXITED(status))
     86             rc = WEXITSTATUS(status);
     87         else
     88             rc = -ECHILD;
     89     }
     90 
     91     if (seg_fault_on_exit) {
     92         uintptr_t fault_address = (uintptr_t) status;
     93         *(int *) fault_address = 0;  // causes SIGSEGV with fault_address = status
     94     }
     95 
     96     return rc;
     97 }
     98