dumpstate.c revision 9066cfe9886ac131c34d59ed0e2d287b0e3c0087
19066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/*
29066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Copyright (C) 2008 The Android Open Source Project
39066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
49066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License");
59066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * you may not use this file except in compliance with the License.
69066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * You may obtain a copy of the License at
79066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
89066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *      http://www.apache.org/licenses/LICENSE-2.0
99066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Unless required by applicable law or agreed to in writing, software
119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS,
129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * See the License for the specific language governing permissions and
149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * limitations under the License.
159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */
169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <stdio.h>
189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <stdlib.h>
199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <string.h>
209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <unistd.h>
219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <sys/stat.h>
229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <limits.h>
239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <fcntl.h>
249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <sys/time.h>
259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <sys/resource.h>
269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include "private/android_filesystem_config.h"
289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include "dumpstate.h"
309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic char* const gzip_args[] = { "gzip", "-6", 0 };
329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic int start_pattern[] = { 150, 0 };
339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic int end_pattern[] = { 75, 50, 75, 50, 75, 0 };
349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic struct tm now;
369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/* dumps the current system state to stdout */
389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic void dumpstate(int full) {
399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (full) {
409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        PRINT("========================================================");
419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        PRINT("== dumpstate");
429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        PRINT("========================================================");
439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        PRINT("------ MEMORY INFO ------");
449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        DUMP("/proc/meminfo");
459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        PRINT("------ CPU INFO ------");
469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        EXEC7("top", "-n", "1", "-d", "1", "-m", "30", "-t");
479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        PRINT("------ PROCRANK ------");
489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        EXEC_XBIN("procrank");
499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        PRINT("------ VIRTUAL MEMORY STATS ------");
509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        DUMP("/proc/vmstat");
519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        PRINT("------ SLAB INFO ------");
529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        DUMP("/proc/slabinfo");
539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        PRINT("------ ZONEINFO ------");
549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        DUMP("/proc/zoneinfo");
559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        PRINT("------ SYSTEM LOG ------");
569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        EXEC4("logcat", "-v", "time", "-d", "*:v");
579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        PRINT("------ VM TRACES ------");
589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        DUMP("/data/anr/traces.txt");
599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        PRINT("------ EVENT LOG TAGS ------");
609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        DUMP("/etc/event-log-tags");
619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        PRINT("------ EVENT LOG ------");
629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        EXEC6("logcat", "-b", "events", "-v", "time", "-d", "*:v");
639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        PRINT("------ RADIO LOG ------");
649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        EXEC6("logcat", "-b", "radio", "-v", "time", "-d", "*:v");
659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        PRINT("------ NETWORK STATE ------");
669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        PRINT("Interfaces:");
679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        EXEC("netcfg");
689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        PRINT("");
699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        PRINT("Routes:");
709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        DUMP("/proc/net/route");
719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        PRINT("------ SYSTEM PROPERTIES ------");
729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        print_properties();
739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        PRINT("------ KERNEL LOG ------");
749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        EXEC("dmesg");
759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        PRINT("------ KERNEL WAKELOCKS ------");
769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        DUMP("/proc/wakelocks");
779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        PRINT("");
789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        PRINT("------ PROCESSES ------");
799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        EXEC("ps");
809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        PRINT("------ PROCESSES AND THREADS ------");
819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        EXEC2("ps", "-t", "-p");
829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        PRINT("------ LIBRANK ------");
839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        EXEC_XBIN("librank");
849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        PRINT("------ BINDER FAILED TRANSACTION LOG ------");
859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        DUMP("/proc/binder/failed_transaction_log");
869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        PRINT("");
879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        PRINT("------ BINDER TRANSACTION LOG ------");
889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        DUMP("/proc/binder/transaction_log");
899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        PRINT("");
909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        PRINT("------ BINDER TRANSACTIONS ------");
919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        DUMP("/proc/binder/transactions");
929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        PRINT("");
939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        PRINT("------ BINDER STATS ------");
949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        DUMP("/proc/binder/stats");
959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        PRINT("");
969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        PRINT("------ BINDER PROCESS STATE: $i ------");
979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        DUMP_FILES("/proc/binder/proc");
989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        PRINT("------ FILESYSTEMS ------");
999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        EXEC("df");
1009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        PRINT("------ PACKAGE SETTINGS ------");
1019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        DUMP("/data/system/packages.xml");
1029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        PRINT("------ PACKAGE UID ERRORS ------");
1039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        DUMP("/data/system/uiderrors.txt");
1049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        PRINT("------ LAST KERNEL LOG ------");
1059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        DUMP("/proc/last_kmsg");
1069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    PRINT("========================================================");
1089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    PRINT("== build.prop");
1099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    PRINT("========================================================");
1109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /* the crash server parses key-value pairs between the VERSION INFO and
1129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * END lines so we can aggregate crash reports based on this data.
1139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
1149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    PRINT("------ VERSION INFO ------");
1159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    print_date("currenttime=", &now);
1169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    DUMP_PROMPT("kernel.version=", "/proc/version");
1179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    DUMP_PROMPT("kernel.cmdline=", "/proc/cmdline");
1189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    DUMP("/system/build.prop");
1199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    PROPERTY("gsm.version.ril-impl");
1209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    PROPERTY("gsm.version.baseband");
1219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    PROPERTY("gsm.imei");
1229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    PROPERTY("gsm.sim.operator.numeric");
1239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    PROPERTY("gsm.operator.alpha");
1249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    PRINT("------ END ------");
1259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (full) {
1279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        PRINT("========================================================");
1289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        PRINT("== dumpsys");
1299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        PRINT("========================================================");
1309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        EXEC("dumpsys");
1319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
1339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/* used to check the file name passed via argv[0] */
1359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic int check_command_name(const char* name, const char* test) {
1369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    int name_length, test_length;
1379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (!strcmp(name, test))
1399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return 1;
1409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    name_length = strlen(name);
1429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    test_length = strlen(test);
1439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (name_length > test_length + 2) {
1459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        name += (name_length - test_length);
1469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (name[-1] != '/')
1479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return 0;
1489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (!strcmp(name, test))
1499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return 1;
1509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return 0;
1539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
1549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectint main(int argc, char *argv[]) {
1569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    int dumpcrash = check_command_name(argv[0], "dumpcrash");
1579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    int bugreport = check_command_name(argv[0], "bugreport");
1589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    int add_date = 0;
1599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    char* outfile = 0;
1609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    int vibrate = 0;
1619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    int compress = 0;
1629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    int c, fd, vibrate_fd, fds[2];
1639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    char path[PATH_MAX];
1649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    pid_t   pid;
1659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /* set as high priority, and protect from OOM killer */
1679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    setpriority(PRIO_PROCESS, 0, -20);
1689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    protect_from_oom_killer();
1699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    get_time(&now);
1719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (bugreport) {
1739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        do {
1749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            c = getopt(argc, argv, "do:vz");
1759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (c == EOF)
1769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                break;
1779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            switch (c) {
1789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                case 'd':
1799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    add_date = 1;
1809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    break;
1819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                case 'o':
1829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    outfile = optarg;
1839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    break;
1849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                case 'v':
1859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    vibrate = 1;
1869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    break;
1879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                case 'z':
1889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    compress = 1;
1899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    break;
1909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                case '?':
1919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                fprintf(stderr, "%s: invalid option -%c\n",
1929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    argv[0], optopt);
1939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    exit(1);
1949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
1959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } while (1);
1969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /* open vibrator before switching user */
1999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (vibrate) {
2009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        vibrate_fd = open("/sys/class/timed_output/vibrator/enable", O_WRONLY);
2019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (vibrate_fd > 0)
2029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            fcntl(vibrate_fd, F_SETFD, FD_CLOEXEC);
2039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    } else
2049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        vibrate_fd = -1;
2059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /* switch to non-root user and group */
2079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    setgid(AID_LOG);
2089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    setuid(AID_SHELL);
2099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /* make it safe to use both printf and STDOUT_FILENO */
2119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    setvbuf(stdout, 0, _IONBF, 0);
2129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (outfile) {
2149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (strlen(outfile) > sizeof(path) - 100)
2159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            exit(1);
2169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        strcpy(path, outfile);
2189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (add_date) {
2199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            char date[260];
2209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            strftime(date, sizeof(date),
2219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                "-%Y-%m-%d-%H-%M-%S",
2229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                &now);
2239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            strcat(path, date);
2249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
2259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (compress)
2269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            strcat(path, ".gz");
2279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        else
2289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            strcat(path, ".txt");
2299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        /* ensure that all directories in the path exist */
2319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        create_directories(path);
2329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        fd = open(path, O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
2339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (fd < 0)
2349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return fd;
2359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (compress) {
2379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            pipe(fds);
2389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            /* redirect our stdout to the pipe */
2409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            dup2(fds[1], STDOUT_FILENO);
2419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            close(fds[1]);
2429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if ((pid = fork()) < 0)
2449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            {
2459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                fprintf(stderr, "fork error\n");
2469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                exit(1);
2479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
2489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (pid) {
2509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                /* parent case */
2519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                /* close our copy of the input to gzip */
2539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                close(fds[0]);
2549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                /* close our copy of the output file */
2559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                close(fd);
2569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            } else {
2579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                /* child case */
2589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project               /* redirect our input pipe to stdin */
2609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                dup2(fds[0], STDIN_FILENO);
2619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                close(fds[0]);
2629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                /* redirect stdout to the output file */
2649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                dup2(fd, STDOUT_FILENO);
2659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                close(fd);
2669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                /* run gzip to postprocess our output */
2689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                execv("/system/bin/gzip", gzip_args);
2699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                fprintf(stderr, "execv returned\n");
2709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
2719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else {
2729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            /* redirect stdout to the output file */
2739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            dup2(fd, STDOUT_FILENO);
2749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            close(fd);
2759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
2769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /* else everything will print to stdout */
2789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (vibrate) {
2809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        vibrate_pattern(vibrate_fd, start_pattern);
2819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    dumpstate(!dumpcrash);
2839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (vibrate) {
2849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        vibrate_pattern(vibrate_fd, end_pattern);
2859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        close(vibrate_fd);
2869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /* so gzip will terminate */
2899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    close(STDOUT_FILENO);
2909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return 0;
2929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
2939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
294