/* * Copyright (C) 2008 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "dumpstate.h" /* prints the contents of a file */ int dump_file(const char* path) { char buffer[32768]; int fd, amount_read; int ret = 0; fd = open(path, O_RDONLY); if (fd < 0) return fd; do { ret = read(fd, buffer, sizeof(buffer)); if (ret > 0) ret = write(STDOUT_FILENO, buffer, ret); } while (ret > 0); buffer[0] = '\n'; write(STDOUT_FILENO, buffer, 1); close(fd); return ret; } /* prints the contents of all files in a directory */ void dump_files(const char* path) { DIR* dir; struct dirent* entry; char buffer[PATH_MAX]; dir = opendir(path); if (!dir) { fprintf(stderr, "could not open directory %s\n", path); return; } while ((entry = readdir(dir))) { if (entry->d_type == DT_REG) { snprintf(buffer, sizeof(buffer), "%s/%s", path, entry->d_name); dump_file(path); printf("\n"); } } closedir(dir); } /* prints the name and value of a system property */ int print_property(const char* name) { char value[PROP_VALUE_MAX]; __system_property_get(name, value); printf("%s=%s\n", name, value); return 0; } static pid_t alarm_pid = 0; static int timed_out = 0; static void sig_alarm(int sig) { if (alarm_pid) { kill(alarm_pid, SIGKILL); timed_out = 1; alarm_pid = 0; } } /* forks a command and waits for it to finish */ int run_command(struct Command* cmd, int timeout) { struct sigaction sa; pid_t pid; int status; pid = fork(); /* handle error case */ if (pid < 0) return pid; /* handle child case */ if (pid == 0) { int ret = execv(cmd->path, cmd->args); if (ret) fprintf(stderr, "execv %s returned %d\n", cmd->path, ret); exit(ret); } /* handle parent case */ timed_out = 0; if (timeout) { memset(&sa, 0, sizeof(sa)); sa.sa_flags = SA_RESETHAND; sa.sa_handler = sig_alarm; sigaction(SIGALRM, &sa, NULL); /* set an alarm so we don't hang forever */ alarm_pid = pid; alarm(timeout); } waitpid(pid, &status, 0); if (timed_out) printf("ERROR: command %s timed out\n", cmd->path); return status; } /* reads the current time into tm */ void get_time(struct tm *tm) { time_t t; tzset(); time(&t); localtime_r(&t, tm); } /* prints the date in tm */ void print_date(const char* prompt, struct tm *tm) { char strbuf[260]; strftime(strbuf, sizeof(strbuf), "%a %b %e %H:%M:%S %Z %Y", tm); printf("%s%s\n", prompt, strbuf); } static void print_prop(const char *key, const char *name, void *user __attribute__((unused))) { printf("[%s]: [%s]\n", key, name); } /* prints all the system properties */ void print_properties() { property_list(print_prop, NULL); } /* creates directories as needed for the given path */ void create_directories(char *path) { char *chp = path; /* skip initial slash */ if (chp[0] == '/') chp++; while (chp && chp[0]) { chp = strchr(chp, '/'); if (chp) { *chp = 0; mkdir(path, S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH); *chp = '/'; chp++; } } } /* runs the vibrator using the given pattern */ void vibrate_pattern(int fd, int* pattern) { struct timespec tm; char buffer[10]; while (*pattern) { /* read vibrate on time */ int on_time = *pattern++; snprintf(buffer, sizeof(buffer), "%d", on_time); write(fd, buffer, strlen(buffer)); /* read vibrate off time */ int delay = *pattern++; if (delay) { delay += on_time; tm.tv_sec = delay / 1000; tm.tv_nsec = (delay % 1000) * 1000000; nanosleep(&tm, NULL); } else break; } } /* prevents the OOM killer from killing us */ void protect_from_oom_killer() { int fd; fd = open("/proc/self/oom_adj", O_WRONLY); if (fd >= 0) { // -17 should make us immune to OOM const char* text = "-17"; write(fd, text, strlen(text)); close(fd); } }