init.c revision 770354d7e6cd471daed426fcf04bf7246e7cb18b
1dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/* 2dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * Copyright (C) 2008 The Android Open Source Project 3dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * 4dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License"); 5dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * you may not use this file except in compliance with the License. 6dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * You may obtain a copy of the License at 7dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * 8dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 9dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * 10dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * Unless required by applicable law or agreed to in writing, software 11dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, 12dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * See the License for the specific language governing permissions and 14dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * limitations under the License. 15dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project */ 16dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 17dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <stdio.h> 18dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <stdlib.h> 19dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <string.h> 20dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <unistd.h> 21dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <fcntl.h> 22dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <ctype.h> 23dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <signal.h> 24dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <sys/wait.h> 25dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <sys/mount.h> 26dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <sys/stat.h> 27dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <sys/poll.h> 28dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <time.h> 29dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <errno.h> 30dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <stdarg.h> 31dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <mtd/mtd-user.h> 32dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <sys/types.h> 33dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <sys/socket.h> 34dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <sys/un.h> 35dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <sys/reboot.h> 36dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 37dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <cutils/sockets.h> 38dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <termios.h> 39dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <linux/kd.h> 40dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <linux/keychord.h> 41dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 42dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <sys/system_properties.h> 43dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 44dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include "devices.h" 45dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include "init.h" 46dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include "property_service.h" 47dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include "bootchart.h" 48dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 49dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic int property_triggers_enabled = 0; 50dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 51dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#if BOOTCHART 52dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic int bootchart_count; 53dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#endif 54dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 55dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic char console[32]; 56dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic char serialno[32]; 57dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic char bootmode[32]; 58dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic char baseband[32]; 59dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic char carrier[32]; 60dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic char bootloader[32]; 61dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic char hardware[32]; 62dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic unsigned revision = 0; 63dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic char qemu[32]; 64dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic struct input_keychord *keychords = 0; 65dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic int keychords_count = 0; 66dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic int keychords_length = 0; 67dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 68dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic void drain_action_queue(void); 69dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 70dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic void notify_service_state(const char *name, const char *state) 71dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 72dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project char pname[PROP_NAME_MAX]; 73dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int len = strlen(name); 74dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if ((len + 10) > PROP_NAME_MAX) 75dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return; 76dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project snprintf(pname, sizeof(pname), "init.svc.%s", name); 77dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project property_set(pname, state); 78dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 79dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 80dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic int have_console; 81dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic char *console_name = "/dev/console"; 82dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic time_t process_needs_restart; 83dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 84dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic const char *ENV[32]; 85dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 86dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/* add_environment - add "key=value" to the current environment */ 87dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectint add_environment(const char *key, const char *val) 88dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 89dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int n; 90dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 91dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project for (n = 0; n < 31; n++) { 92dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (!ENV[n]) { 93dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project size_t len = strlen(key) + strlen(val) + 2; 94dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project char *entry = malloc(len); 95dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project snprintf(entry, len, "%s=%s", key, val); 96dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ENV[n] = entry; 97dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return 0; 98dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 99dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 100dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 101dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return 1; 102dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 103dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 104dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic void zap_stdio(void) 105dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 106dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int fd; 107dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fd = open("/dev/null", O_RDWR); 108dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project dup2(fd, 0); 109dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project dup2(fd, 1); 110dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project dup2(fd, 2); 111dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project close(fd); 112dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 113dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 114dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic void open_console() 115dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 116dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int fd; 117dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if ((fd = open(console_name, O_RDWR)) < 0) { 118dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fd = open("/dev/null", O_RDWR); 119dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 120dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project dup2(fd, 0); 121dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project dup2(fd, 1); 122dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project dup2(fd, 2); 123dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project close(fd); 124dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 125dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 126dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/* 127dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * gettime() - returns the time in seconds of the system's monotonic clock or 128dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * zero on error. 129dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project */ 130dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic time_t gettime(void) 131dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 132dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project struct timespec ts; 133dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int ret; 134dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 135dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ret = clock_gettime(CLOCK_MONOTONIC, &ts); 136dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (ret < 0) { 137dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ERROR("clock_gettime(CLOCK_MONOTONIC) failed: %s\n", strerror(errno)); 138dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return 0; 139dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 140dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 141dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return ts.tv_sec; 142dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 143dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 144dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic void publish_socket(const char *name, int fd) 145dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 146dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project char key[64] = ANDROID_SOCKET_ENV_PREFIX; 147dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project char val[64]; 148dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 149dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project strlcpy(key + sizeof(ANDROID_SOCKET_ENV_PREFIX) - 1, 150dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project name, 151dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project sizeof(key) - sizeof(ANDROID_SOCKET_ENV_PREFIX)); 152dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project snprintf(val, sizeof(val), "%d", fd); 153dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project add_environment(key, val); 154dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 155dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project /* make sure we don't close-on-exec */ 156dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fcntl(fd, F_SETFD, 0); 157dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 158dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 159dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectvoid service_start(struct service *svc) 160dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 161dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project struct stat s; 162dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project pid_t pid; 163dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int needs_console; 164dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int n; 165dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 166dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project /* starting a service removes it from the disabled 167dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * state and immediately takes it out of the restarting 168dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * state if it was in there 169dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project */ 170dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project svc->flags &= (~(SVC_DISABLED|SVC_RESTARTING)); 171dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project svc->time_started = 0; 172dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 173dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project /* running processes require no additional work -- if 174dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * they're in the process of exiting, we've ensured 175dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * that they will immediately restart on exit, unless 176dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * they are ONESHOT 177dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project */ 178dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (svc->flags & SVC_RUNNING) { 179dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return; 180dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 181dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 182dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project needs_console = (svc->flags & SVC_CONSOLE) ? 1 : 0; 183dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (needs_console && (!have_console)) { 184dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ERROR("service '%s' requires console\n", svc->name); 185dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project svc->flags |= SVC_DISABLED; 186dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return; 187dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 188dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 189dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (stat(svc->args[0], &s) != 0) { 190dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ERROR("cannot find '%s', disabling '%s'\n", svc->args[0], svc->name); 191dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project svc->flags |= SVC_DISABLED; 192dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return; 193dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 194dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 195dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project NOTICE("starting '%s'\n", svc->name); 196dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 197dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project pid = fork(); 198dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 199dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (pid == 0) { 200dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project struct socketinfo *si; 201dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project struct svcenvinfo *ei; 202dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project char tmp[32]; 203dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int fd, sz; 204dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 205dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project get_property_workspace(&fd, &sz); 206dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project sprintf(tmp, "%d,%d", dup(fd), sz); 207dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project add_environment("ANDROID_PROPERTY_WORKSPACE", tmp); 208dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 209dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project for (ei = svc->envvars; ei; ei = ei->next) 210dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project add_environment(ei->name, ei->value); 211dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 212dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project for (si = svc->sockets; si; si = si->next) { 213dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int s = create_socket(si->name, 214dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project !strcmp(si->type, "dgram") ? 215dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project SOCK_DGRAM : SOCK_STREAM, 216dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project si->perm, si->uid, si->gid); 217dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (s >= 0) { 218dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project publish_socket(si->name, s); 219dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 220dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 221dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 222dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (needs_console) { 223dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project setsid(); 224dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project open_console(); 225dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else { 226dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project zap_stdio(); 227dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 228dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 229dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#if 0 230dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project for (n = 0; svc->args[n]; n++) { 231dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project INFO("args[%d] = '%s'\n", n, svc->args[n]); 232dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 233dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project for (n = 0; ENV[n]; n++) { 234dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project INFO("env[%d] = '%s'\n", n, ENV[n]); 235dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 236dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#endif 237dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 238dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project setpgid(0, getpid()); 239dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 240dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project /* as requested, set our gid, supplemental gids, and uid */ 241dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (svc->gid) { 242dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project setgid(svc->gid); 243dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 244dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (svc->nr_supp_gids) { 245dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project setgroups(svc->nr_supp_gids, svc->supp_gids); 246dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 247dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (svc->uid) { 248dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project setuid(svc->uid); 249dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 250dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 251dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project execve(svc->args[0], (char**) svc->args, (char**) ENV); 252dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project _exit(127); 253dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 254dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 255dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (pid < 0) { 256dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ERROR("failed to start '%s'\n", svc->name); 257dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project svc->pid = 0; 258dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return; 259dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 260dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 261dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project svc->time_started = gettime(); 262dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project svc->pid = pid; 263dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project svc->flags |= SVC_RUNNING; 264dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 265dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project notify_service_state(svc->name, "running"); 266dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 267dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 268dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectvoid service_stop(struct service *svc) 269dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 270dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project /* we are no longer running, nor should we 271dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * attempt to restart 272dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project */ 273dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project svc->flags &= (~(SVC_RUNNING|SVC_RESTARTING)); 274dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 275dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project /* if the service has not yet started, prevent 276dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * it from auto-starting with its class 277dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project */ 278dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project svc->flags |= SVC_DISABLED; 279dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 280dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (svc->pid) { 281dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project NOTICE("service '%s' is being killed\n", svc->name); 282dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project kill(-svc->pid, SIGTERM); 283dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project notify_service_state(svc->name, "stopping"); 284dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else { 285dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project notify_service_state(svc->name, "stopped"); 286dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 287dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 288dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 289dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectvoid property_changed(const char *name, const char *value) 290dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 291dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (property_triggers_enabled) { 292dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project queue_property_triggers(name, value); 293dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project drain_action_queue(); 294dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 295dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 296dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 297dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#define CRITICAL_CRASH_THRESHOLD 4 /* if we crash >4 times ... */ 298dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#define CRITICAL_CRASH_WINDOW (4*60) /* ... in 4 minutes, goto recovery*/ 299dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 300dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic int wait_for_one_process(int block) 301dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 302dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project pid_t pid; 303dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int status; 304dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project struct service *svc; 305dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project struct socketinfo *si; 306dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project time_t now; 307dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project struct listnode *node; 308dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project struct command *cmd; 309dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 310dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project while ( (pid = waitpid(-1, &status, block ? 0 : WNOHANG)) == -1 && errno == EINTR ); 311dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (pid <= 0) return -1; 312dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project INFO("waitpid returned pid %d, status = %08x\n", pid, status); 313dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 314dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project svc = service_find_by_pid(pid); 315dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (!svc) { 316dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ERROR("untracked pid %d exited\n", pid); 317dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return 0; 318dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 319dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 320dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project NOTICE("process '%s', pid %d exited\n", svc->name, pid); 321dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 322dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (!(svc->flags & SVC_ONESHOT)) { 323dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project kill(-pid, SIGKILL); 324dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project NOTICE("process '%s' killing any children in process group\n", svc->name); 325dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 326dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 327dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project /* remove any sockets we may have created */ 328dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project for (si = svc->sockets; si; si = si->next) { 329dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project char tmp[128]; 330dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project snprintf(tmp, sizeof(tmp), ANDROID_SOCKET_DIR"/%s", si->name); 331dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project unlink(tmp); 332dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 333dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 334dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project svc->pid = 0; 335dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project svc->flags &= (~SVC_RUNNING); 336dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 337dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project /* oneshot processes go into the disabled state on exit */ 338dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (svc->flags & SVC_ONESHOT) { 339dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project svc->flags |= SVC_DISABLED; 340dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 341dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 342dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project /* disabled processes do not get restarted automatically */ 343dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (svc->flags & SVC_DISABLED) { 344dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project notify_service_state(svc->name, "stopped"); 345dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return 0; 346dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 347dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 348dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project now = gettime(); 349dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (svc->flags & SVC_CRITICAL) { 350dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (svc->time_crashed + CRITICAL_CRASH_WINDOW >= now) { 351dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (++svc->nr_crashed > CRITICAL_CRASH_THRESHOLD) { 352dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ERROR("critical process '%s' exited %d times in %d minutes; " 353dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project "rebooting into recovery mode\n", svc->name, 354dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project CRITICAL_CRASH_THRESHOLD, CRITICAL_CRASH_WINDOW / 60); 355dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project sync(); 356dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project __reboot(LINUX_REBOOT_MAGIC1, LINUX_REBOOT_MAGIC2, 357dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project LINUX_REBOOT_CMD_RESTART2, "recovery"); 358dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return 0; 359dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 360dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else { 361dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project svc->time_crashed = now; 362dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project svc->nr_crashed = 1; 363dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 364dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 365dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 366dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project /* Execute all onrestart commands for this service. */ 367dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project list_for_each(node, &svc->onrestart.commands) { 368dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project cmd = node_to_item(node, struct command, clist); 369dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project cmd->func(cmd->nargs, cmd->args); 370dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 371dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project svc->flags |= SVC_RESTARTING; 372dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project notify_service_state(svc->name, "restarting"); 373dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return 0; 374dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 375dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 376dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic void restart_service_if_needed(struct service *svc) 377dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 378dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project time_t next_start_time = svc->time_started + 5; 379dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 380dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (next_start_time <= gettime()) { 381dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project svc->flags &= (~SVC_RESTARTING); 382dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project service_start(svc); 383dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return; 384dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 385dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 386dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if ((next_start_time < process_needs_restart) || 387dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project (process_needs_restart == 0)) { 388dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project process_needs_restart = next_start_time; 389dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 390dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 391dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 392dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic void restart_processes() 393dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 394dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project process_needs_restart = 0; 395dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project service_for_each_flags(SVC_RESTARTING, 396dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project restart_service_if_needed); 397dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 398dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 399dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic int signal_fd = -1; 400dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 401dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic void sigchld_handler(int s) 402dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 403dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project write(signal_fd, &s, 1); 404dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 405dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 406dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic void msg_start(const char *name) 407dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 408dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project struct service *svc = service_find_by_name(name); 409dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 410dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (svc) { 411dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project service_start(svc); 412dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else { 413dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ERROR("no such service '%s'\n", name); 414dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 415dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 416dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 417dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic void msg_stop(const char *name) 418dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 419dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project struct service *svc = service_find_by_name(name); 420dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 421dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (svc) { 422dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project service_stop(svc); 423dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else { 424770354d7e6cd471daed426fcf04bf7246e7cb18bDima Zavin ERROR("no such service '%s'\n", name); 425dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 426dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 427dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 428dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectvoid handle_control_message(const char *msg, const char *arg) 429dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 430dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (!strcmp(msg,"start")) { 431dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project msg_start(arg); 432dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else if (!strcmp(msg,"stop")) { 433dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project msg_stop(arg); 434dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else { 435dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ERROR("unknown control msg '%s'\n", msg); 436dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 437dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 438dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 439dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#define MAX_MTD_PARTITIONS 16 440dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 441dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic struct { 442dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project char name[16]; 443dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int number; 444dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} mtd_part_map[MAX_MTD_PARTITIONS]; 445dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 446dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic int mtd_part_count = -1; 447dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 448dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic void find_mtd_partitions(void) 449dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 450dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int fd; 451dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project char buf[1024]; 452dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project char *pmtdbufp; 453dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ssize_t pmtdsize; 454dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int r; 455dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 456dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fd = open("/proc/mtd", O_RDONLY); 457dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (fd < 0) 458dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return; 459dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 460dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project buf[sizeof(buf) - 1] = '\0'; 461dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project pmtdsize = read(fd, buf, sizeof(buf) - 1); 462dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project pmtdbufp = buf; 463dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project while (pmtdsize > 0) { 464dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int mtdnum, mtdsize, mtderasesize; 465dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project char mtdname[16]; 466dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project mtdname[0] = '\0'; 467dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project mtdnum = -1; 468dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project r = sscanf(pmtdbufp, "mtd%d: %x %x %15s", 469dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project &mtdnum, &mtdsize, &mtderasesize, mtdname); 470dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if ((r == 4) && (mtdname[0] == '"')) { 471dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project char *x = strchr(mtdname + 1, '"'); 472dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (x) { 473dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project *x = 0; 474dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 475dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project INFO("mtd partition %d, %s\n", mtdnum, mtdname + 1); 476dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (mtd_part_count < MAX_MTD_PARTITIONS) { 477dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project strcpy(mtd_part_map[mtd_part_count].name, mtdname + 1); 478dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project mtd_part_map[mtd_part_count].number = mtdnum; 479dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project mtd_part_count++; 480dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else { 481dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ERROR("too many mtd partitions\n"); 482dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 483dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 484dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project while (pmtdsize > 0 && *pmtdbufp != '\n') { 485dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project pmtdbufp++; 486dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project pmtdsize--; 487dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 488dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (pmtdsize > 0) { 489dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project pmtdbufp++; 490dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project pmtdsize--; 491dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 492dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 493dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project close(fd); 494dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 495dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 496dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectint mtd_name_to_number(const char *name) 497dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 498dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int n; 499dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (mtd_part_count < 0) { 500dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project mtd_part_count = 0; 501dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project find_mtd_partitions(); 502dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 503dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project for (n = 0; n < mtd_part_count; n++) { 504dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (!strcmp(name, mtd_part_map[n].name)) { 505dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return mtd_part_map[n].number; 506dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 507dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 508dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return -1; 509dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 510dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 511dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic void import_kernel_nv(char *name, int in_qemu) 512dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 513dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project char *value = strchr(name, '='); 514dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 515dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (value == 0) return; 516dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project *value++ = 0; 517dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (*name == 0) return; 518dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 519dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (!in_qemu) 520dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project { 521dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project /* on a real device, white-list the kernel options */ 522dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (!strcmp(name,"qemu")) { 523dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project strlcpy(qemu, value, sizeof(qemu)); 524dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else if (!strcmp(name,"androidboot.console")) { 525dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project strlcpy(console, value, sizeof(console)); 526dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else if (!strcmp(name,"androidboot.mode")) { 527dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project strlcpy(bootmode, value, sizeof(bootmode)); 528dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else if (!strcmp(name,"androidboot.serialno")) { 529dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project strlcpy(serialno, value, sizeof(serialno)); 530dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else if (!strcmp(name,"androidboot.baseband")) { 531dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project strlcpy(baseband, value, sizeof(baseband)); 532dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else if (!strcmp(name,"androidboot.carrier")) { 533dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project strlcpy(carrier, value, sizeof(carrier)); 534dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else if (!strcmp(name,"androidboot.bootloader")) { 535dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project strlcpy(bootloader, value, sizeof(bootloader)); 536dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else if (!strcmp(name,"androidboot.hardware")) { 537dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project strlcpy(hardware, value, sizeof(hardware)); 538dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else { 539dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project qemu_cmdline(name, value); 540dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 541dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else { 542dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project /* in the emulator, export any kernel option with the 543dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * ro.kernel. prefix */ 544dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project char buff[32]; 545dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int len = snprintf( buff, sizeof(buff), "ro.kernel.%s", name ); 546dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (len < (int)sizeof(buff)) { 547dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project property_set( buff, value ); 548dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 549dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 550dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 551dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 552dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic void import_kernel_cmdline(int in_qemu) 553dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 554dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project char cmdline[1024]; 555dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project char *ptr; 556dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int fd; 557dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 558dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fd = open("/proc/cmdline", O_RDONLY); 559dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (fd >= 0) { 560dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int n = read(fd, cmdline, 1023); 561dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (n < 0) n = 0; 562dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 563dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project /* get rid of trailing newline, it happens */ 564dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (n > 0 && cmdline[n-1] == '\n') n--; 565dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 566dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project cmdline[n] = 0; 567dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project close(fd); 568dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else { 569dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project cmdline[0] = 0; 570dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 571dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 572dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ptr = cmdline; 573dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project while (ptr && *ptr) { 574dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project char *x = strchr(ptr, ' '); 575dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (x != 0) *x++ = 0; 576dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project import_kernel_nv(ptr, in_qemu); 577dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ptr = x; 578dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 579dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 580dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project /* don't expose the raw commandline to nonpriv processes */ 581dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project chmod("/proc/cmdline", 0440); 582dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 583dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 584dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic void get_hardware_name(void) 585dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 586dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project char data[1024]; 587dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int fd, n; 588dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project char *x, *hw, *rev; 589dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 590dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project /* Hardware string was provided on kernel command line */ 591dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (hardware[0]) 592dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return; 593dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 594dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fd = open("/proc/cpuinfo", O_RDONLY); 595dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (fd < 0) return; 596dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 597dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project n = read(fd, data, 1023); 598dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project close(fd); 599dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (n < 0) return; 600dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 601dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project data[n] = 0; 602dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project hw = strstr(data, "\nHardware"); 603dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project rev = strstr(data, "\nRevision"); 604dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 605dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (hw) { 606dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project x = strstr(hw, ": "); 607dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (x) { 608dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project x += 2; 609dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project n = 0; 610dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project while (*x && !isspace(*x)) { 611dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project hardware[n++] = tolower(*x); 612dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project x++; 613dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (n == 31) break; 614dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 615dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project hardware[n] = 0; 616dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 617dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 618dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 619dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (rev) { 620dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project x = strstr(rev, ": "); 621dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (x) { 622dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project revision = strtoul(x + 2, 0, 16); 623dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 624dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 625dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 626dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 627dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic void drain_action_queue(void) 628dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 629dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project struct listnode *node; 630dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project struct command *cmd; 631dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project struct action *act; 632dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int ret; 633dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 634dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project while ((act = action_remove_queue_head())) { 635dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project INFO("processing action %p (%s)\n", act, act->name); 636dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project list_for_each(node, &act->commands) { 637dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project cmd = node_to_item(node, struct command, clist); 638dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ret = cmd->func(cmd->nargs, cmd->args); 639dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project INFO("command '%s' r=%d\n", cmd->args[0], ret); 640dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 641dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 642dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 643dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 644dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectvoid open_devnull_stdio(void) 645dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 646dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int fd; 647dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project static const char *name = "/dev/__null__"; 648dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (mknod(name, S_IFCHR | 0600, (1 << 8) | 3) == 0) { 649dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fd = open(name, O_RDWR); 650dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project unlink(name); 651dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (fd >= 0) { 652dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project dup2(fd, 0); 653dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project dup2(fd, 1); 654dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project dup2(fd, 2); 655dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (fd > 2) { 656dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project close(fd); 657dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 658dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return; 659dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 660dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 661dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 662dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project exit(1); 663dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 664dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 665dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectvoid add_service_keycodes(struct service *svc) 666dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 667dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project struct input_keychord *keychord; 668dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int i, size; 669dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 670dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (svc->keycodes) { 671dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project /* add a new keychord to the list */ 672dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project size = sizeof(*keychord) + svc->nkeycodes * sizeof(keychord->keycodes[0]); 673dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project keychords = realloc(keychords, keychords_length + size); 674dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (!keychords) { 675dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ERROR("could not allocate keychords\n"); 676dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project keychords_length = 0; 677dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project keychords_count = 0; 678dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return; 679dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 680dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 681dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project keychord = (struct input_keychord *)((char *)keychords + keychords_length); 682dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project keychord->version = KEYCHORD_VERSION; 683dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project keychord->id = keychords_count + 1; 684dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project keychord->count = svc->nkeycodes; 685dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project svc->keychord_id = keychord->id; 686dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 687dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project for (i = 0; i < svc->nkeycodes; i++) { 688dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project keychord->keycodes[i] = svc->keycodes[i]; 689dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 690dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project keychords_count++; 691dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project keychords_length += size; 692dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 693dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 694dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 695dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectint open_keychord() 696dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 697dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int fd, ret; 698dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 699dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project service_for_each(add_service_keycodes); 700dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 701dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project /* nothing to do if no services require keychords */ 702dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (!keychords) 703dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return -1; 704dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 705dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fd = open("/dev/keychord", O_RDWR); 706dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (fd < 0) { 707dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ERROR("could not open /dev/keychord\n"); 708dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return fd; 709dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 710dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fcntl(fd, F_SETFD, FD_CLOEXEC); 711dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 712dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ret = write(fd, keychords, keychords_length); 713dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (ret != keychords_length) { 714dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ERROR("could not configure /dev/keychord %d (%d)\n", ret, errno); 715dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project close(fd); 716dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fd = -1; 717dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 718dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 719dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project free(keychords); 720dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project keychords = 0; 721dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 722dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return fd; 723dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 724dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 725dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectvoid handle_keychord(int fd) 726dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 727dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project struct service *svc; 728dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int ret; 729dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project __u16 id; 730dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 731dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ret = read(fd, &id, sizeof(id)); 732dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (ret != sizeof(id)) { 733dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ERROR("could not read keychord id\n"); 734dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return; 735dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 736dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 737dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project svc = service_find_by_keychord(id); 738dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (svc) { 739dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project INFO("starting service %s from keychord\n", svc->name); 740dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project service_start(svc); 741dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else { 742dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ERROR("service for keychord %d not found\n", id); 743dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 744dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 745dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 746dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectint main(int argc, char **argv) 747dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 748dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int device_fd = -1; 749dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int property_set_fd = -1; 750dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int signal_recv_fd = -1; 751dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int keychord_fd = -1; 752dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int fd_count; 753dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int s[2]; 754dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int fd; 755dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project struct sigaction act; 756dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project char tmp[PROP_VALUE_MAX]; 757dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project struct pollfd ufds[4]; 758dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project char *tmpdev; 759dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project char* debuggable; 760dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 761dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project act.sa_handler = sigchld_handler; 762dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project act.sa_flags = SA_NOCLDSTOP; 763dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project act.sa_mask = 0; 764dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project act.sa_restorer = NULL; 765dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project sigaction(SIGCHLD, &act, 0); 766dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 767dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project /* clear the umask */ 768dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project umask(0); 769dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 770dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project /* Get the basic filesystem setup we need put 771dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * together in the initramdisk on / and then we'll 772dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * let the rc file figure out the rest. 773dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project */ 774dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project mkdir("/dev", 0755); 775dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project mkdir("/proc", 0755); 776dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project mkdir("/sys", 0755); 777dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 778dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project mount("tmpfs", "/dev", "tmpfs", 0, "mode=0755"); 779dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project mkdir("/dev/pts", 0755); 780dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project mkdir("/dev/socket", 0755); 781dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project mount("devpts", "/dev/pts", "devpts", 0, NULL); 782dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project mount("proc", "/proc", "proc", 0, NULL); 783dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project mount("sysfs", "/sys", "sysfs", 0, NULL); 784dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 785dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project /* We must have some place other than / to create the 786dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * device nodes for kmsg and null, otherwise we won't 787dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * be able to remount / read-only later on. 788dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * Now that tmpfs is mounted on /dev, we can actually 789dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * talk to the outside world. 790dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project */ 791dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project open_devnull_stdio(); 792dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project log_init(); 793dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 794dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project INFO("reading config file\n"); 795dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project parse_config_file("/init.rc"); 796dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 797dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project /* pull the kernel commandline and ramdisk properties file in */ 798dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project qemu_init(); 799dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project import_kernel_cmdline(0); 800dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 801dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project get_hardware_name(); 802dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project snprintf(tmp, sizeof(tmp), "/init.%s.rc", hardware); 803dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project parse_config_file(tmp); 804dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 805dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project action_for_each_trigger("early-init", action_add_queue_tail); 806dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project drain_action_queue(); 807dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 808dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project INFO("device init\n"); 809dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project device_fd = device_init(); 810dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 811dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project property_init(); 812dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 813dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project // only listen for keychords if ro.debuggable is true 814dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project debuggable = property_get("ro.debuggable"); 815dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (debuggable && !strcmp(debuggable, "1")) { 816dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project keychord_fd = open_keychord(); 817dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 818dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 819dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (console[0]) { 820dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project snprintf(tmp, sizeof(tmp), "/dev/%s", console); 821dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project console_name = strdup(tmp); 822dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 823dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 824dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fd = open(console_name, O_RDWR); 825dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (fd >= 0) 826dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project have_console = 1; 827dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project close(fd); 828dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 829dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if( load_565rle_image(INIT_IMAGE_FILE) ) { 830dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fd = open("/dev/tty0", O_WRONLY); 831dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (fd >= 0) { 832dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project const char *msg; 833dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project msg = "\n" 834dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project "\n" 835dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project "\n" 836dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project "\n" 837dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project "\n" 838dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project "\n" 839dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project "\n" // console is 40 cols x 30 lines 840dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project "\n" 841dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project "\n" 842dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project "\n" 843dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project "\n" 844dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project "\n" 845dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project "\n" 846dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project "\n" 847dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project " A N D R O I D "; 848dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project write(fd, msg, strlen(msg)); 849dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project close(fd); 850dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 851dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 852dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 853dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (qemu[0]) 854dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project import_kernel_cmdline(1); 855dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 856dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (!strcmp(bootmode,"factory")) 857dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project property_set("ro.factorytest", "1"); 858dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project else if (!strcmp(bootmode,"factory2")) 859dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project property_set("ro.factorytest", "2"); 860dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project else 861dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project property_set("ro.factorytest", "0"); 862dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 863dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project property_set("ro.serialno", serialno[0] ? serialno : ""); 864dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project property_set("ro.bootmode", bootmode[0] ? bootmode : "unknown"); 865dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project property_set("ro.baseband", baseband[0] ? baseband : "unknown"); 866dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project property_set("ro.carrier", carrier[0] ? carrier : "unknown"); 867dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project property_set("ro.bootloader", bootloader[0] ? bootloader : "unknown"); 868dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 869dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project property_set("ro.hardware", hardware); 870dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project snprintf(tmp, PROP_VALUE_MAX, "%d", revision); 871dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project property_set("ro.revision", tmp); 872dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 873dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project /* execute all the boot actions to get us started */ 874dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project action_for_each_trigger("init", action_add_queue_tail); 875dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project drain_action_queue(); 876dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 877dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project /* read any property files on system or data and 878dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * fire up the property service. This must happen 879dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * after the ro.foo properties are set above so 880dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * that /data/local.prop cannot interfere with them. 881dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project */ 882dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project property_set_fd = start_property_service(); 883dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 884dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project /* create a signalling mechanism for the sigchld handler */ 885dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (socketpair(AF_UNIX, SOCK_STREAM, 0, s) == 0) { 886dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project signal_fd = s[0]; 887dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project signal_recv_fd = s[1]; 888dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fcntl(s[0], F_SETFD, FD_CLOEXEC); 889dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fcntl(s[0], F_SETFL, O_NONBLOCK); 890dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fcntl(s[1], F_SETFD, FD_CLOEXEC); 891dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fcntl(s[1], F_SETFL, O_NONBLOCK); 892dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 893dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 894dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project /* make sure we actually have all the pieces we need */ 895dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if ((device_fd < 0) || 896dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project (property_set_fd < 0) || 897dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project (signal_recv_fd < 0)) { 898dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ERROR("init startup failure\n"); 899dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return 1; 900dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 901dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 902dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project /* execute all the boot actions to get us started */ 903dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project action_for_each_trigger("early-boot", action_add_queue_tail); 904dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project action_for_each_trigger("boot", action_add_queue_tail); 905dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project drain_action_queue(); 906dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 907dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project /* run all property triggers based on current state of the properties */ 908dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project queue_all_property_triggers(); 909dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project drain_action_queue(); 910dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 911dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project /* enable property triggers */ 912dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project property_triggers_enabled = 1; 913dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 914dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ufds[0].fd = device_fd; 915dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ufds[0].events = POLLIN; 916dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ufds[1].fd = property_set_fd; 917dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ufds[1].events = POLLIN; 918dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ufds[2].fd = signal_recv_fd; 919dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ufds[2].events = POLLIN; 920dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fd_count = 3; 921dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 922dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (keychord_fd > 0) { 923dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ufds[3].fd = keychord_fd; 924dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ufds[3].events = POLLIN; 925dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fd_count++; 926dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else { 927dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ufds[3].events = 0; 928dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ufds[3].revents = 0; 929dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 930dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 931dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#if BOOTCHART 932dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project bootchart_count = bootchart_init(); 933dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (bootchart_count < 0) { 934dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ERROR("bootcharting init failure\n"); 935dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else if (bootchart_count > 0) { 936dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project NOTICE("bootcharting started (period=%d ms)\n", bootchart_count*BOOTCHART_POLLING_MS); 937dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else { 938dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project NOTICE("bootcharting ignored\n"); 939dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 940dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#endif 941dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 942dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project for(;;) { 943dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int nr, i, timeout = -1; 944dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 945dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project for (i = 0; i < fd_count; i++) 946dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ufds[i].revents = 0; 947dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 948dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project drain_action_queue(); 949dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project restart_processes(); 950dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 951dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (process_needs_restart) { 952dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project timeout = (process_needs_restart - gettime()) * 1000; 953dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (timeout < 0) 954dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project timeout = 0; 955dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 956dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 957dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#if BOOTCHART 958dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (bootchart_count > 0) { 959dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (timeout < 0 || timeout > BOOTCHART_POLLING_MS) 960dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project timeout = BOOTCHART_POLLING_MS; 961dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (bootchart_step() < 0 || --bootchart_count == 0) { 962dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project bootchart_finish(); 963dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project bootchart_count = 0; 964dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 965dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 966dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#endif 967dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project nr = poll(ufds, fd_count, timeout); 968dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (nr <= 0) 969dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project continue; 970dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 971dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (ufds[2].revents == POLLIN) { 972dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project /* we got a SIGCHLD - reap and restart as needed */ 973dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project read(signal_recv_fd, tmp, sizeof(tmp)); 974dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project while (!wait_for_one_process(0)) 975dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ; 976dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project continue; 977dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 978dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 979dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (ufds[0].revents == POLLIN) 980dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project handle_device_fd(device_fd); 981dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 982dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (ufds[1].revents == POLLIN) 983dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project handle_property_set_fd(property_set_fd); 984dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (ufds[3].revents == POLLIN) 985dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project handle_keychord(keychord_fd); 986dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 987dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 988dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return 0; 989dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 990