init.c revision 8ad15685e6d3d2251ceac4ac7135397cf6140e1a
14f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project/* 24f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project * Copyright (C) 2008 The Android Open Source Project 34f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project * 44f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License"); 54f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project * you may not use this file except in compliance with the License. 64f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project * You may obtain a copy of the License at 74f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project * 84f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 94f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project * 104f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project * Unless required by applicable law or agreed to in writing, software 114f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, 124f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 134f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project * See the License for the specific language governing permissions and 144f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project * limitations under the License. 154f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project */ 164f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 174f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project#include <stdio.h> 184f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project#include <stdlib.h> 194f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project#include <string.h> 204f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project#include <unistd.h> 214f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project#include <fcntl.h> 224f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project#include <ctype.h> 234f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project#include <signal.h> 244f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project#include <sys/wait.h> 254f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project#include <sys/mount.h> 264f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project#include <sys/stat.h> 274f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project#include <sys/poll.h> 284f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project#include <time.h> 294f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project#include <errno.h> 304f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project#include <stdarg.h> 314f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project#include <mtd/mtd-user.h> 324f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project#include <sys/types.h> 334f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project#include <sys/socket.h> 344f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project#include <sys/un.h> 354f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project#include <sys/reboot.h> 364f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 374f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project#include <cutils/sockets.h> 384f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project#include <termios.h> 394f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project#include <linux/kd.h> 405ae090ed949cea9d1e7ab1552b455a229f8f9757The Android Open Source Project#include <linux/keychord.h> 414f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 424f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project#include <sys/system_properties.h> 434f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 444f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project#include "devices.h" 454f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project#include "init.h" 464f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project#include "property_service.h" 4735237d135807af84bf9b0e5b8d7f8633e58db6f5The Android Open Source Project#include "bootchart.h" 484f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 494f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Projectstatic int property_triggers_enabled = 0; 504f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 514f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project#if BOOTCHART 524f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Projectstatic int bootchart_count; 534f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project#endif 544f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 554f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Projectstatic char console[32]; 564f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Projectstatic char serialno[32]; 574f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Projectstatic char bootmode[32]; 584f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Projectstatic char baseband[32]; 594f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Projectstatic char carrier[32]; 604f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Projectstatic char bootloader[32]; 614f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Projectstatic char hardware[32]; 624f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Projectstatic unsigned revision = 0; 634f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Projectstatic char qemu[32]; 645ae090ed949cea9d1e7ab1552b455a229f8f9757The Android Open Source Projectstatic struct input_keychord *keychords = 0; 655ae090ed949cea9d1e7ab1552b455a229f8f9757The Android Open Source Projectstatic int keychords_count = 0; 665ae090ed949cea9d1e7ab1552b455a229f8f9757The Android Open Source Projectstatic int keychords_length = 0; 674f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 684f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Projectstatic void drain_action_queue(void); 694f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 704f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Projectstatic void notify_service_state(const char *name, const char *state) 714f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project{ 724f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project char pname[PROP_NAME_MAX]; 734f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project int len = strlen(name); 744f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project if ((len + 10) > PROP_NAME_MAX) 754f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project return; 764f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project snprintf(pname, sizeof(pname), "init.svc.%s", name); 774f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project property_set(pname, state); 784f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project} 794f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 804f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Projectstatic int have_console; 814f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Projectstatic char *console_name = "/dev/console"; 824f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Projectstatic time_t process_needs_restart; 834f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 844f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Projectstatic const char *ENV[32]; 854f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 864f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project/* add_environment - add "key=value" to the current environment */ 874f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Projectint add_environment(const char *key, const char *val) 884f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project{ 894f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project int n; 904f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 914f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project for (n = 0; n < 31; n++) { 924f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project if (!ENV[n]) { 934f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project size_t len = strlen(key) + strlen(val) + 2; 944f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project char *entry = malloc(len); 954f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project snprintf(entry, len, "%s=%s", key, val); 964f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project ENV[n] = entry; 974f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project return 0; 984f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project } 994f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project } 1004f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 1014f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project return 1; 1024f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project} 1034f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 1044f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Projectstatic void zap_stdio(void) 1054f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project{ 1064f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project int fd; 1074f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project fd = open("/dev/null", O_RDWR); 1084f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project dup2(fd, 0); 1094f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project dup2(fd, 1); 1104f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project dup2(fd, 2); 1114f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project close(fd); 1124f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project} 1134f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 1144f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Projectstatic void open_console() 1154f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project{ 1164f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project int fd; 1174f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project if ((fd = open(console_name, O_RDWR)) < 0) { 1184f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project fd = open("/dev/null", O_RDWR); 1194f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project } 1204f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project dup2(fd, 0); 1214f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project dup2(fd, 1); 1224f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project dup2(fd, 2); 1234f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project close(fd); 1244f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project} 1254f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 1264f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project/* 1274f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project * gettime() - returns the time in seconds of the system's monotonic clock or 1284f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project * zero on error. 1294f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project */ 1304f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Projectstatic time_t gettime(void) 1314f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project{ 1324f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project struct timespec ts; 1334f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project int ret; 1344f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 1354f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project ret = clock_gettime(CLOCK_MONOTONIC, &ts); 1364f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project if (ret < 0) { 1374f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project ERROR("clock_gettime(CLOCK_MONOTONIC) failed: %s\n", strerror(errno)); 1384f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project return 0; 1394f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project } 1404f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 1414f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project return ts.tv_sec; 1424f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project} 1434f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 1444f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Projectstatic void publish_socket(const char *name, int fd) 1454f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project{ 1464f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project char key[64] = ANDROID_SOCKET_ENV_PREFIX; 1474f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project char val[64]; 1484f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 1494f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project strlcpy(key + sizeof(ANDROID_SOCKET_ENV_PREFIX) - 1, 1504f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project name, 1514f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project sizeof(key) - sizeof(ANDROID_SOCKET_ENV_PREFIX)); 1524f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project snprintf(val, sizeof(val), "%d", fd); 1534f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project add_environment(key, val); 1544f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 1554f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project /* make sure we don't close-on-exec */ 1564f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project fcntl(fd, F_SETFD, 0); 1574f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project} 1584f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 159f24e252903ca0f71c7fbfb135cf17e83e0c2ea90San Mehatvoid service_start(struct service *svc, const char *dynamic_args) 1604f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project{ 1614f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project struct stat s; 1624f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project pid_t pid; 1634f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project int needs_console; 1644f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project int n; 1654f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 1664f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project /* starting a service removes it from the disabled 1674f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project * state and immediately takes it out of the restarting 1684f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project * state if it was in there 1694f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project */ 1704f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project svc->flags &= (~(SVC_DISABLED|SVC_RESTARTING)); 1714f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project svc->time_started = 0; 1724f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 1734f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project /* running processes require no additional work -- if 1744f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project * they're in the process of exiting, we've ensured 1754f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project * that they will immediately restart on exit, unless 1764f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project * they are ONESHOT 1774f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project */ 1784f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project if (svc->flags & SVC_RUNNING) { 1794f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project return; 1804f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project } 1814f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 1824f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project needs_console = (svc->flags & SVC_CONSOLE) ? 1 : 0; 1834f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project if (needs_console && (!have_console)) { 1844f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project ERROR("service '%s' requires console\n", svc->name); 1854f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project svc->flags |= SVC_DISABLED; 1864f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project return; 1874f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project } 1884f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 1894f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project if (stat(svc->args[0], &s) != 0) { 1904f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project ERROR("cannot find '%s', disabling '%s'\n", svc->args[0], svc->name); 1914f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project svc->flags |= SVC_DISABLED; 1924f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project return; 1934f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project } 1944f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 195f24e252903ca0f71c7fbfb135cf17e83e0c2ea90San Mehat if ((!(svc->flags & SVC_ONESHOT)) && dynamic_args) { 196f24e252903ca0f71c7fbfb135cf17e83e0c2ea90San Mehat ERROR("service '%s' must be one-shot to use dynamic args, disabling\n", svc->args[0]); 197f24e252903ca0f71c7fbfb135cf17e83e0c2ea90San Mehat svc->flags |= SVC_DISABLED; 198f24e252903ca0f71c7fbfb135cf17e83e0c2ea90San Mehat return; 199f24e252903ca0f71c7fbfb135cf17e83e0c2ea90San Mehat } 200f24e252903ca0f71c7fbfb135cf17e83e0c2ea90San Mehat 2014f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project NOTICE("starting '%s'\n", svc->name); 2024f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 2034f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project pid = fork(); 2044f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 2054f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project if (pid == 0) { 2064f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project struct socketinfo *si; 2074f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project struct svcenvinfo *ei; 2084f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project char tmp[32]; 2094f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project int fd, sz; 2104f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 2114f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project get_property_workspace(&fd, &sz); 2124f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project sprintf(tmp, "%d,%d", dup(fd), sz); 2134f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project add_environment("ANDROID_PROPERTY_WORKSPACE", tmp); 2144f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 2154f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project for (ei = svc->envvars; ei; ei = ei->next) 2164f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project add_environment(ei->name, ei->value); 2174f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 2184f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project for (si = svc->sockets; si; si = si->next) { 2194f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project int s = create_socket(si->name, 2204f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project !strcmp(si->type, "dgram") ? 2214f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project SOCK_DGRAM : SOCK_STREAM, 2224f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project si->perm, si->uid, si->gid); 2234f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project if (s >= 0) { 2244f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project publish_socket(si->name, s); 2254f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project } 2264f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project } 2274f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 2284f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project if (needs_console) { 2294f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project setsid(); 2304f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project open_console(); 2314f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project } else { 2324f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project zap_stdio(); 2334f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project } 2344f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 2354f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project#if 0 2364f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project for (n = 0; svc->args[n]; n++) { 2374f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project INFO("args[%d] = '%s'\n", n, svc->args[n]); 2384f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project } 2394f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project for (n = 0; ENV[n]; n++) { 2404f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project INFO("env[%d] = '%s'\n", n, ENV[n]); 2414f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project } 2424f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project#endif 2434f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 2444f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project setpgid(0, getpid()); 2454f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 2465ae090ed949cea9d1e7ab1552b455a229f8f9757The Android Open Source Project /* as requested, set our gid, supplemental gids, and uid */ 2474f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project if (svc->gid) { 2484f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project setgid(svc->gid); 2494f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project } 2504f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project if (svc->nr_supp_gids) { 2514f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project setgroups(svc->nr_supp_gids, svc->supp_gids); 2524f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project } 2534f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project if (svc->uid) { 2544f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project setuid(svc->uid); 2554f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project } 2564f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 2578ad15685e6d3d2251ceac4ac7135397cf6140e1aSan Mehat if (!dynamic_args) { 2588ad15685e6d3d2251ceac4ac7135397cf6140e1aSan Mehat if (execve(svc->args[0], (char**) svc->args, (char**) ENV) < 0) { 2598ad15685e6d3d2251ceac4ac7135397cf6140e1aSan Mehat ERROR("cannot execve('%s'): %s\n", svc->args[0], strerror(errno)); 2608ad15685e6d3d2251ceac4ac7135397cf6140e1aSan Mehat } 2618ad15685e6d3d2251ceac4ac7135397cf6140e1aSan Mehat } else { 262f24e252903ca0f71c7fbfb135cf17e83e0c2ea90San Mehat char *arg_ptrs[SVC_MAXARGS+1]; 263f24e252903ca0f71c7fbfb135cf17e83e0c2ea90San Mehat int arg_idx; 264f24e252903ca0f71c7fbfb135cf17e83e0c2ea90San Mehat char *tmp = strdup(dynamic_args); 265f24e252903ca0f71c7fbfb135cf17e83e0c2ea90San Mehat char *p = tmp; 266f24e252903ca0f71c7fbfb135cf17e83e0c2ea90San Mehat 267f24e252903ca0f71c7fbfb135cf17e83e0c2ea90San Mehat /* Copy the static arguments */ 268f24e252903ca0f71c7fbfb135cf17e83e0c2ea90San Mehat for (arg_idx = 0; arg_idx < svc->nargs; arg_idx++) { 269f24e252903ca0f71c7fbfb135cf17e83e0c2ea90San Mehat arg_ptrs[arg_idx] = svc->args[arg_idx]; 270f24e252903ca0f71c7fbfb135cf17e83e0c2ea90San Mehat } 271f24e252903ca0f71c7fbfb135cf17e83e0c2ea90San Mehat 272f24e252903ca0f71c7fbfb135cf17e83e0c2ea90San Mehat int done = 0; 273f24e252903ca0f71c7fbfb135cf17e83e0c2ea90San Mehat while(!done) { 274f24e252903ca0f71c7fbfb135cf17e83e0c2ea90San Mehat 275f24e252903ca0f71c7fbfb135cf17e83e0c2ea90San Mehat if (arg_idx == SVC_MAXARGS) 276f24e252903ca0f71c7fbfb135cf17e83e0c2ea90San Mehat break; 277f24e252903ca0f71c7fbfb135cf17e83e0c2ea90San Mehat 278f24e252903ca0f71c7fbfb135cf17e83e0c2ea90San Mehat /* Advance over any leading whitespace */ 279f24e252903ca0f71c7fbfb135cf17e83e0c2ea90San Mehat if (*p == ' ') { 280f24e252903ca0f71c7fbfb135cf17e83e0c2ea90San Mehat for (p; *p != ' '; p++); 281f24e252903ca0f71c7fbfb135cf17e83e0c2ea90San Mehat p++; 282f24e252903ca0f71c7fbfb135cf17e83e0c2ea90San Mehat } 283f24e252903ca0f71c7fbfb135cf17e83e0c2ea90San Mehat /* Locate next argument */ 284f24e252903ca0f71c7fbfb135cf17e83e0c2ea90San Mehat char *q = p; 285f24e252903ca0f71c7fbfb135cf17e83e0c2ea90San Mehat while(1) { 286f24e252903ca0f71c7fbfb135cf17e83e0c2ea90San Mehat if (*q == ' ') { 287f24e252903ca0f71c7fbfb135cf17e83e0c2ea90San Mehat *q = '\0'; 288f24e252903ca0f71c7fbfb135cf17e83e0c2ea90San Mehat break; 289f24e252903ca0f71c7fbfb135cf17e83e0c2ea90San Mehat } else if (*q == '\0') { 290f24e252903ca0f71c7fbfb135cf17e83e0c2ea90San Mehat done = 1; 291f24e252903ca0f71c7fbfb135cf17e83e0c2ea90San Mehat break; 292f24e252903ca0f71c7fbfb135cf17e83e0c2ea90San Mehat } 293f24e252903ca0f71c7fbfb135cf17e83e0c2ea90San Mehat q++; 294f24e252903ca0f71c7fbfb135cf17e83e0c2ea90San Mehat } 295f24e252903ca0f71c7fbfb135cf17e83e0c2ea90San Mehat arg_ptrs[arg_idx++] = p; 296f24e252903ca0f71c7fbfb135cf17e83e0c2ea90San Mehat 297f24e252903ca0f71c7fbfb135cf17e83e0c2ea90San Mehat q++; // Advance q to the next string 298f24e252903ca0f71c7fbfb135cf17e83e0c2ea90San Mehat p = q; 299f24e252903ca0f71c7fbfb135cf17e83e0c2ea90San Mehat } 300f24e252903ca0f71c7fbfb135cf17e83e0c2ea90San Mehat arg_ptrs[arg_idx] = '\0'; 301f24e252903ca0f71c7fbfb135cf17e83e0c2ea90San Mehat execve(svc->args[0], (char**) arg_ptrs, (char**) ENV); 302165de92bf1bca1648b4df3047a8f274e0aff4ca9Ivan Djelic } 3034f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project _exit(127); 3044f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project } 3054f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 3064f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project if (pid < 0) { 3074f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project ERROR("failed to start '%s'\n", svc->name); 3084f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project svc->pid = 0; 3094f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project return; 3104f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project } 3114f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 3124f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project svc->time_started = gettime(); 3134f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project svc->pid = pid; 3144f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project svc->flags |= SVC_RUNNING; 3154f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 3164f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project notify_service_state(svc->name, "running"); 3174f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project} 3184f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 3194f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Projectvoid service_stop(struct service *svc) 3204f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project{ 3214f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project /* we are no longer running, nor should we 3224f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project * attempt to restart 3234f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project */ 3244f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project svc->flags &= (~(SVC_RUNNING|SVC_RESTARTING)); 3254f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 3264f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project /* if the service has not yet started, prevent 3274f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project * it from auto-starting with its class 3284f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project */ 3294f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project svc->flags |= SVC_DISABLED; 3304f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 3314f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project if (svc->pid) { 3324f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project NOTICE("service '%s' is being killed\n", svc->name); 3334f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project kill(-svc->pid, SIGTERM); 3344f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project notify_service_state(svc->name, "stopping"); 3354f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project } else { 3364f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project notify_service_state(svc->name, "stopped"); 3374f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project } 3384f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project} 3394f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 3404f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Projectvoid property_changed(const char *name, const char *value) 3414f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project{ 3424f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project if (property_triggers_enabled) { 3434f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project queue_property_triggers(name, value); 3444f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project drain_action_queue(); 3454f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project } 3464f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project} 3474f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 3484f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project#define CRITICAL_CRASH_THRESHOLD 4 /* if we crash >4 times ... */ 3494f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project#define CRITICAL_CRASH_WINDOW (4*60) /* ... in 4 minutes, goto recovery*/ 3504f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 3514f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Projectstatic int wait_for_one_process(int block) 3524f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project{ 3534f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project pid_t pid; 3544f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project int status; 3554f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project struct service *svc; 3564f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project struct socketinfo *si; 3574f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project time_t now; 3584f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project struct listnode *node; 3594f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project struct command *cmd; 3604f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 3614f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project while ( (pid = waitpid(-1, &status, block ? 0 : WNOHANG)) == -1 && errno == EINTR ); 3624f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project if (pid <= 0) return -1; 3634f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project INFO("waitpid returned pid %d, status = %08x\n", pid, status); 3644f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 3654f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project svc = service_find_by_pid(pid); 3664f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project if (!svc) { 3674f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project ERROR("untracked pid %d exited\n", pid); 3684f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project return 0; 3694f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project } 3704f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 3714f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project NOTICE("process '%s', pid %d exited\n", svc->name, pid); 3724f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 3734f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project if (!(svc->flags & SVC_ONESHOT)) { 3744f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project kill(-pid, SIGKILL); 3754f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project NOTICE("process '%s' killing any children in process group\n", svc->name); 3764f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project } 3774f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 3784f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project /* remove any sockets we may have created */ 3794f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project for (si = svc->sockets; si; si = si->next) { 3804f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project char tmp[128]; 3814f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project snprintf(tmp, sizeof(tmp), ANDROID_SOCKET_DIR"/%s", si->name); 3824f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project unlink(tmp); 3834f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project } 3844f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 3854f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project svc->pid = 0; 3864f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project svc->flags &= (~SVC_RUNNING); 3874f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 3884f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project /* oneshot processes go into the disabled state on exit */ 3894f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project if (svc->flags & SVC_ONESHOT) { 3904f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project svc->flags |= SVC_DISABLED; 3914f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project } 3924f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 3934f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project /* disabled processes do not get restarted automatically */ 3944f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project if (svc->flags & SVC_DISABLED) { 3954f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project notify_service_state(svc->name, "stopped"); 3964f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project return 0; 3974f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project } 3984f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 3994f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project now = gettime(); 4004f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project if (svc->flags & SVC_CRITICAL) { 4014f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project if (svc->time_crashed + CRITICAL_CRASH_WINDOW >= now) { 4024f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project if (++svc->nr_crashed > CRITICAL_CRASH_THRESHOLD) { 4034f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project ERROR("critical process '%s' exited %d times in %d minutes; " 4044f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project "rebooting into recovery mode\n", svc->name, 4054f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project CRITICAL_CRASH_THRESHOLD, CRITICAL_CRASH_WINDOW / 60); 4064f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project sync(); 4074f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project __reboot(LINUX_REBOOT_MAGIC1, LINUX_REBOOT_MAGIC2, 4084f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project LINUX_REBOOT_CMD_RESTART2, "recovery"); 4094f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project return 0; 4104f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project } 4114f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project } else { 4124f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project svc->time_crashed = now; 4134f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project svc->nr_crashed = 1; 4144f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project } 4154f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project } 4164f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 4174f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project /* Execute all onrestart commands for this service. */ 4184f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project list_for_each(node, &svc->onrestart.commands) { 4194f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project cmd = node_to_item(node, struct command, clist); 4204f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project cmd->func(cmd->nargs, cmd->args); 4214f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project } 4224f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project svc->flags |= SVC_RESTARTING; 4234f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project notify_service_state(svc->name, "restarting"); 4244f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project return 0; 4254f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project} 4264f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 4274f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Projectstatic void restart_service_if_needed(struct service *svc) 4284f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project{ 4294f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project time_t next_start_time = svc->time_started + 5; 4304f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 4314f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project if (next_start_time <= gettime()) { 4324f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project svc->flags &= (~SVC_RESTARTING); 433f24e252903ca0f71c7fbfb135cf17e83e0c2ea90San Mehat service_start(svc, NULL); 4344f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project return; 4354f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project } 4364f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 4374f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project if ((next_start_time < process_needs_restart) || 4384f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project (process_needs_restart == 0)) { 4394f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project process_needs_restart = next_start_time; 4404f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project } 4414f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project} 4424f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 4434f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Projectstatic void restart_processes() 4444f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project{ 4454f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project process_needs_restart = 0; 4464f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project service_for_each_flags(SVC_RESTARTING, 4474f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project restart_service_if_needed); 4484f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project} 4494f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 4504f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Projectstatic int signal_fd = -1; 4514f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 4524f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Projectstatic void sigchld_handler(int s) 4534f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project{ 4544f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project write(signal_fd, &s, 1); 4554f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project} 4564f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 4574f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Projectstatic void msg_start(const char *name) 4584f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project{ 459f24e252903ca0f71c7fbfb135cf17e83e0c2ea90San Mehat struct service *svc; 460f24e252903ca0f71c7fbfb135cf17e83e0c2ea90San Mehat char *tmp = NULL; 461f24e252903ca0f71c7fbfb135cf17e83e0c2ea90San Mehat char *args = NULL; 462f24e252903ca0f71c7fbfb135cf17e83e0c2ea90San Mehat 463f24e252903ca0f71c7fbfb135cf17e83e0c2ea90San Mehat if (!strchr(name, ':')) 464f24e252903ca0f71c7fbfb135cf17e83e0c2ea90San Mehat svc = service_find_by_name(name); 465f24e252903ca0f71c7fbfb135cf17e83e0c2ea90San Mehat else { 466f24e252903ca0f71c7fbfb135cf17e83e0c2ea90San Mehat tmp = strdup(name); 467f24e252903ca0f71c7fbfb135cf17e83e0c2ea90San Mehat strcpy(tmp, name); 468f24e252903ca0f71c7fbfb135cf17e83e0c2ea90San Mehat args = strchr(tmp, ':'); 469f24e252903ca0f71c7fbfb135cf17e83e0c2ea90San Mehat *args = '\0'; 470f24e252903ca0f71c7fbfb135cf17e83e0c2ea90San Mehat args++; 471f24e252903ca0f71c7fbfb135cf17e83e0c2ea90San Mehat 472f24e252903ca0f71c7fbfb135cf17e83e0c2ea90San Mehat svc = service_find_by_name(tmp); 473f24e252903ca0f71c7fbfb135cf17e83e0c2ea90San Mehat } 4744f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 4754f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project if (svc) { 476f24e252903ca0f71c7fbfb135cf17e83e0c2ea90San Mehat service_start(svc, args); 4774f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project } else { 4784f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project ERROR("no such service '%s'\n", name); 4794f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project } 480f24e252903ca0f71c7fbfb135cf17e83e0c2ea90San Mehat if (tmp) 481f24e252903ca0f71c7fbfb135cf17e83e0c2ea90San Mehat free(tmp); 4824f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project} 4834f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 4844f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Projectstatic void msg_stop(const char *name) 4854f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project{ 4864f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project struct service *svc = service_find_by_name(name); 4874f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 4884f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project if (svc) { 4894f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project service_stop(svc); 4904f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project } else { 491770354d7e6cd471daed426fcf04bf7246e7cb18bDima Zavin ERROR("no such service '%s'\n", name); 4924f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project } 4934f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project} 4944f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 4954f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Projectvoid handle_control_message(const char *msg, const char *arg) 4964f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project{ 4974f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project if (!strcmp(msg,"start")) { 4984f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project msg_start(arg); 4994f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project } else if (!strcmp(msg,"stop")) { 5004f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project msg_stop(arg); 5014f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project } else { 5024f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project ERROR("unknown control msg '%s'\n", msg); 5034f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project } 5044f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project} 5054f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 5064f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project#define MAX_MTD_PARTITIONS 16 5074f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 5084f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Projectstatic struct { 5094f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project char name[16]; 5104f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project int number; 5114f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project} mtd_part_map[MAX_MTD_PARTITIONS]; 5124f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 5134f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Projectstatic int mtd_part_count = -1; 5144f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 5154f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Projectstatic void find_mtd_partitions(void) 5164f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project{ 5174f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project int fd; 5184f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project char buf[1024]; 5194f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project char *pmtdbufp; 5204f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project ssize_t pmtdsize; 5214f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project int r; 5224f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 5234f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project fd = open("/proc/mtd", O_RDONLY); 5244f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project if (fd < 0) 5254f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project return; 5264f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 5274f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project buf[sizeof(buf) - 1] = '\0'; 5284f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project pmtdsize = read(fd, buf, sizeof(buf) - 1); 5294f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project pmtdbufp = buf; 5304f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project while (pmtdsize > 0) { 5314f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project int mtdnum, mtdsize, mtderasesize; 5324f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project char mtdname[16]; 5334f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project mtdname[0] = '\0'; 5344f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project mtdnum = -1; 5354f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project r = sscanf(pmtdbufp, "mtd%d: %x %x %15s", 5364f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project &mtdnum, &mtdsize, &mtderasesize, mtdname); 5374f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project if ((r == 4) && (mtdname[0] == '"')) { 5384f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project char *x = strchr(mtdname + 1, '"'); 5394f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project if (x) { 5404f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project *x = 0; 5414f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project } 5424f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project INFO("mtd partition %d, %s\n", mtdnum, mtdname + 1); 5434f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project if (mtd_part_count < MAX_MTD_PARTITIONS) { 5444f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project strcpy(mtd_part_map[mtd_part_count].name, mtdname + 1); 5454f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project mtd_part_map[mtd_part_count].number = mtdnum; 5464f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project mtd_part_count++; 5474f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project } else { 5484f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project ERROR("too many mtd partitions\n"); 5494f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project } 5504f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project } 5514f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project while (pmtdsize > 0 && *pmtdbufp != '\n') { 5524f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project pmtdbufp++; 5534f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project pmtdsize--; 5544f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project } 5554f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project if (pmtdsize > 0) { 5564f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project pmtdbufp++; 5574f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project pmtdsize--; 5584f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project } 5594f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project } 5604f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project close(fd); 5614f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project} 5624f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 5634f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Projectint mtd_name_to_number(const char *name) 5644f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project{ 5654f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project int n; 5664f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project if (mtd_part_count < 0) { 5674f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project mtd_part_count = 0; 5684f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project find_mtd_partitions(); 5694f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project } 5704f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project for (n = 0; n < mtd_part_count; n++) { 5714f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project if (!strcmp(name, mtd_part_map[n].name)) { 5724f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project return mtd_part_map[n].number; 5734f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project } 5744f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project } 5754f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project return -1; 5764f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project} 5774f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 5784f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Projectstatic void import_kernel_nv(char *name, int in_qemu) 5794f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project{ 5804f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project char *value = strchr(name, '='); 5814f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 5824f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project if (value == 0) return; 5834f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project *value++ = 0; 5844f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project if (*name == 0) return; 5854f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 5864f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project if (!in_qemu) 5874f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project { 5884f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project /* on a real device, white-list the kernel options */ 5894f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project if (!strcmp(name,"qemu")) { 5904f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project strlcpy(qemu, value, sizeof(qemu)); 5914f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project } else if (!strcmp(name,"androidboot.console")) { 5924f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project strlcpy(console, value, sizeof(console)); 5934f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project } else if (!strcmp(name,"androidboot.mode")) { 5944f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project strlcpy(bootmode, value, sizeof(bootmode)); 5954f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project } else if (!strcmp(name,"androidboot.serialno")) { 5964f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project strlcpy(serialno, value, sizeof(serialno)); 5974f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project } else if (!strcmp(name,"androidboot.baseband")) { 5984f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project strlcpy(baseband, value, sizeof(baseband)); 5994f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project } else if (!strcmp(name,"androidboot.carrier")) { 6004f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project strlcpy(carrier, value, sizeof(carrier)); 6014f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project } else if (!strcmp(name,"androidboot.bootloader")) { 6024f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project strlcpy(bootloader, value, sizeof(bootloader)); 6034f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project } else if (!strcmp(name,"androidboot.hardware")) { 6044f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project strlcpy(hardware, value, sizeof(hardware)); 6054f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project } else { 6064f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project qemu_cmdline(name, value); 6074f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project } 6084f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project } else { 6094f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project /* in the emulator, export any kernel option with the 6104f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project * ro.kernel. prefix */ 6114f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project char buff[32]; 6124f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project int len = snprintf( buff, sizeof(buff), "ro.kernel.%s", name ); 6134f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project if (len < (int)sizeof(buff)) { 6144f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project property_set( buff, value ); 6154f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project } 6164f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project } 6174f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project} 6184f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 6194f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Projectstatic void import_kernel_cmdline(int in_qemu) 6204f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project{ 6214f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project char cmdline[1024]; 6224f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project char *ptr; 6234f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project int fd; 6244f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 6254f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project fd = open("/proc/cmdline", O_RDONLY); 6264f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project if (fd >= 0) { 6274f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project int n = read(fd, cmdline, 1023); 6284f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project if (n < 0) n = 0; 6294f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 6304f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project /* get rid of trailing newline, it happens */ 6314f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project if (n > 0 && cmdline[n-1] == '\n') n--; 6324f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 6334f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project cmdline[n] = 0; 6344f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project close(fd); 6354f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project } else { 6364f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project cmdline[0] = 0; 6374f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project } 6384f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 6394f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project ptr = cmdline; 6404f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project while (ptr && *ptr) { 6414f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project char *x = strchr(ptr, ' '); 6424f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project if (x != 0) *x++ = 0; 6434f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project import_kernel_nv(ptr, in_qemu); 6444f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project ptr = x; 6454f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project } 6464f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 6474f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project /* don't expose the raw commandline to nonpriv processes */ 6484f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project chmod("/proc/cmdline", 0440); 6494f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project} 6504f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 6514f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Projectstatic void get_hardware_name(void) 6524f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project{ 6534f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project char data[1024]; 6544f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project int fd, n; 6554f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project char *x, *hw, *rev; 6564f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 6574f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project /* Hardware string was provided on kernel command line */ 6584f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project if (hardware[0]) 6594f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project return; 6604f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 6614f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project fd = open("/proc/cpuinfo", O_RDONLY); 6624f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project if (fd < 0) return; 6634f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 6644f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project n = read(fd, data, 1023); 6654f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project close(fd); 6664f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project if (n < 0) return; 6674f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 6684f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project data[n] = 0; 6694f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project hw = strstr(data, "\nHardware"); 6704f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project rev = strstr(data, "\nRevision"); 6714f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 6724f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project if (hw) { 6734f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project x = strstr(hw, ": "); 6744f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project if (x) { 6754f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project x += 2; 6764f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project n = 0; 6774f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project while (*x && !isspace(*x)) { 6784f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project hardware[n++] = tolower(*x); 6794f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project x++; 6804f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project if (n == 31) break; 6814f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project } 6824f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project hardware[n] = 0; 6834f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project } 6844f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project } 6854f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 6864f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project if (rev) { 6874f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project x = strstr(rev, ": "); 6884f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project if (x) { 6894f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project revision = strtoul(x + 2, 0, 16); 6904f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project } 6914f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project } 6924f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project} 6934f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 6944f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Projectstatic void drain_action_queue(void) 6954f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project{ 6964f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project struct listnode *node; 6974f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project struct command *cmd; 6984f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project struct action *act; 6994f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project int ret; 7004f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 7014f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project while ((act = action_remove_queue_head())) { 7024f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project INFO("processing action %p (%s)\n", act, act->name); 7034f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project list_for_each(node, &act->commands) { 7044f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project cmd = node_to_item(node, struct command, clist); 7054f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project ret = cmd->func(cmd->nargs, cmd->args); 7064f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project INFO("command '%s' r=%d\n", cmd->args[0], ret); 7074f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project } 7084f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project } 7094f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project} 7104f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 7114f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Projectvoid open_devnull_stdio(void) 7124f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project{ 7134f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project int fd; 7144f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project static const char *name = "/dev/__null__"; 7154f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project if (mknod(name, S_IFCHR | 0600, (1 << 8) | 3) == 0) { 7164f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project fd = open(name, O_RDWR); 7174f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project unlink(name); 7184f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project if (fd >= 0) { 7194f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project dup2(fd, 0); 7204f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project dup2(fd, 1); 7214f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project dup2(fd, 2); 7224f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project if (fd > 2) { 7234f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project close(fd); 7244f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project } 7254f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project return; 7264f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project } 7274f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project } 7284f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 7294f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project exit(1); 7304f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project} 7314f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 7325ae090ed949cea9d1e7ab1552b455a229f8f9757The Android Open Source Projectvoid add_service_keycodes(struct service *svc) 7335ae090ed949cea9d1e7ab1552b455a229f8f9757The Android Open Source Project{ 7345ae090ed949cea9d1e7ab1552b455a229f8f9757The Android Open Source Project struct input_keychord *keychord; 7355ae090ed949cea9d1e7ab1552b455a229f8f9757The Android Open Source Project int i, size; 7365ae090ed949cea9d1e7ab1552b455a229f8f9757The Android Open Source Project 7375ae090ed949cea9d1e7ab1552b455a229f8f9757The Android Open Source Project if (svc->keycodes) { 7385ae090ed949cea9d1e7ab1552b455a229f8f9757The Android Open Source Project /* add a new keychord to the list */ 7395ae090ed949cea9d1e7ab1552b455a229f8f9757The Android Open Source Project size = sizeof(*keychord) + svc->nkeycodes * sizeof(keychord->keycodes[0]); 7405ae090ed949cea9d1e7ab1552b455a229f8f9757The Android Open Source Project keychords = realloc(keychords, keychords_length + size); 7415ae090ed949cea9d1e7ab1552b455a229f8f9757The Android Open Source Project if (!keychords) { 7425ae090ed949cea9d1e7ab1552b455a229f8f9757The Android Open Source Project ERROR("could not allocate keychords\n"); 7435ae090ed949cea9d1e7ab1552b455a229f8f9757The Android Open Source Project keychords_length = 0; 7445ae090ed949cea9d1e7ab1552b455a229f8f9757The Android Open Source Project keychords_count = 0; 7455ae090ed949cea9d1e7ab1552b455a229f8f9757The Android Open Source Project return; 7465ae090ed949cea9d1e7ab1552b455a229f8f9757The Android Open Source Project } 7475ae090ed949cea9d1e7ab1552b455a229f8f9757The Android Open Source Project 7485ae090ed949cea9d1e7ab1552b455a229f8f9757The Android Open Source Project keychord = (struct input_keychord *)((char *)keychords + keychords_length); 7495ae090ed949cea9d1e7ab1552b455a229f8f9757The Android Open Source Project keychord->version = KEYCHORD_VERSION; 7505ae090ed949cea9d1e7ab1552b455a229f8f9757The Android Open Source Project keychord->id = keychords_count + 1; 7515ae090ed949cea9d1e7ab1552b455a229f8f9757The Android Open Source Project keychord->count = svc->nkeycodes; 7525ae090ed949cea9d1e7ab1552b455a229f8f9757The Android Open Source Project svc->keychord_id = keychord->id; 7535ae090ed949cea9d1e7ab1552b455a229f8f9757The Android Open Source Project 7545ae090ed949cea9d1e7ab1552b455a229f8f9757The Android Open Source Project for (i = 0; i < svc->nkeycodes; i++) { 7555ae090ed949cea9d1e7ab1552b455a229f8f9757The Android Open Source Project keychord->keycodes[i] = svc->keycodes[i]; 7565ae090ed949cea9d1e7ab1552b455a229f8f9757The Android Open Source Project } 7575ae090ed949cea9d1e7ab1552b455a229f8f9757The Android Open Source Project keychords_count++; 7585ae090ed949cea9d1e7ab1552b455a229f8f9757The Android Open Source Project keychords_length += size; 7595ae090ed949cea9d1e7ab1552b455a229f8f9757The Android Open Source Project } 7605ae090ed949cea9d1e7ab1552b455a229f8f9757The Android Open Source Project} 7615ae090ed949cea9d1e7ab1552b455a229f8f9757The Android Open Source Project 7625ae090ed949cea9d1e7ab1552b455a229f8f9757The Android Open Source Projectint open_keychord() 7635ae090ed949cea9d1e7ab1552b455a229f8f9757The Android Open Source Project{ 7645ae090ed949cea9d1e7ab1552b455a229f8f9757The Android Open Source Project int fd, ret; 7655ae090ed949cea9d1e7ab1552b455a229f8f9757The Android Open Source Project 7665ae090ed949cea9d1e7ab1552b455a229f8f9757The Android Open Source Project service_for_each(add_service_keycodes); 7675ae090ed949cea9d1e7ab1552b455a229f8f9757The Android Open Source Project 7685ae090ed949cea9d1e7ab1552b455a229f8f9757The Android Open Source Project /* nothing to do if no services require keychords */ 7695ae090ed949cea9d1e7ab1552b455a229f8f9757The Android Open Source Project if (!keychords) 7705ae090ed949cea9d1e7ab1552b455a229f8f9757The Android Open Source Project return -1; 7715ae090ed949cea9d1e7ab1552b455a229f8f9757The Android Open Source Project 7725ae090ed949cea9d1e7ab1552b455a229f8f9757The Android Open Source Project fd = open("/dev/keychord", O_RDWR); 7735ae090ed949cea9d1e7ab1552b455a229f8f9757The Android Open Source Project if (fd < 0) { 7745ae090ed949cea9d1e7ab1552b455a229f8f9757The Android Open Source Project ERROR("could not open /dev/keychord\n"); 7755ae090ed949cea9d1e7ab1552b455a229f8f9757The Android Open Source Project return fd; 7765ae090ed949cea9d1e7ab1552b455a229f8f9757The Android Open Source Project } 7775ae090ed949cea9d1e7ab1552b455a229f8f9757The Android Open Source Project fcntl(fd, F_SETFD, FD_CLOEXEC); 7785ae090ed949cea9d1e7ab1552b455a229f8f9757The Android Open Source Project 7795ae090ed949cea9d1e7ab1552b455a229f8f9757The Android Open Source Project ret = write(fd, keychords, keychords_length); 7805ae090ed949cea9d1e7ab1552b455a229f8f9757The Android Open Source Project if (ret != keychords_length) { 7815ae090ed949cea9d1e7ab1552b455a229f8f9757The Android Open Source Project ERROR("could not configure /dev/keychord %d (%d)\n", ret, errno); 7825ae090ed949cea9d1e7ab1552b455a229f8f9757The Android Open Source Project close(fd); 7835ae090ed949cea9d1e7ab1552b455a229f8f9757The Android Open Source Project fd = -1; 7845ae090ed949cea9d1e7ab1552b455a229f8f9757The Android Open Source Project } 7855ae090ed949cea9d1e7ab1552b455a229f8f9757The Android Open Source Project 7865ae090ed949cea9d1e7ab1552b455a229f8f9757The Android Open Source Project free(keychords); 7875ae090ed949cea9d1e7ab1552b455a229f8f9757The Android Open Source Project keychords = 0; 7885ae090ed949cea9d1e7ab1552b455a229f8f9757The Android Open Source Project 7895ae090ed949cea9d1e7ab1552b455a229f8f9757The Android Open Source Project return fd; 7905ae090ed949cea9d1e7ab1552b455a229f8f9757The Android Open Source Project} 7915ae090ed949cea9d1e7ab1552b455a229f8f9757The Android Open Source Project 7925ae090ed949cea9d1e7ab1552b455a229f8f9757The Android Open Source Projectvoid handle_keychord(int fd) 7935ae090ed949cea9d1e7ab1552b455a229f8f9757The Android Open Source Project{ 7945ae090ed949cea9d1e7ab1552b455a229f8f9757The Android Open Source Project struct service *svc; 7955ae090ed949cea9d1e7ab1552b455a229f8f9757The Android Open Source Project int ret; 7965ae090ed949cea9d1e7ab1552b455a229f8f9757The Android Open Source Project __u16 id; 7975ae090ed949cea9d1e7ab1552b455a229f8f9757The Android Open Source Project 7985ae090ed949cea9d1e7ab1552b455a229f8f9757The Android Open Source Project ret = read(fd, &id, sizeof(id)); 7995ae090ed949cea9d1e7ab1552b455a229f8f9757The Android Open Source Project if (ret != sizeof(id)) { 8005ae090ed949cea9d1e7ab1552b455a229f8f9757The Android Open Source Project ERROR("could not read keychord id\n"); 8015ae090ed949cea9d1e7ab1552b455a229f8f9757The Android Open Source Project return; 8025ae090ed949cea9d1e7ab1552b455a229f8f9757The Android Open Source Project } 8035ae090ed949cea9d1e7ab1552b455a229f8f9757The Android Open Source Project 8045ae090ed949cea9d1e7ab1552b455a229f8f9757The Android Open Source Project svc = service_find_by_keychord(id); 8055ae090ed949cea9d1e7ab1552b455a229f8f9757The Android Open Source Project if (svc) { 8065ae090ed949cea9d1e7ab1552b455a229f8f9757The Android Open Source Project INFO("starting service %s from keychord\n", svc->name); 807f24e252903ca0f71c7fbfb135cf17e83e0c2ea90San Mehat service_start(svc, NULL); 8085ae090ed949cea9d1e7ab1552b455a229f8f9757The Android Open Source Project } else { 8095ae090ed949cea9d1e7ab1552b455a229f8f9757The Android Open Source Project ERROR("service for keychord %d not found\n", id); 8105ae090ed949cea9d1e7ab1552b455a229f8f9757The Android Open Source Project } 8115ae090ed949cea9d1e7ab1552b455a229f8f9757The Android Open Source Project} 8125ae090ed949cea9d1e7ab1552b455a229f8f9757The Android Open Source Project 8134f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Projectint main(int argc, char **argv) 8144f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project{ 8154f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project int device_fd = -1; 8164f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project int property_set_fd = -1; 8174f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project int signal_recv_fd = -1; 8185ae090ed949cea9d1e7ab1552b455a229f8f9757The Android Open Source Project int keychord_fd = -1; 8195ae090ed949cea9d1e7ab1552b455a229f8f9757The Android Open Source Project int fd_count; 8204f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project int s[2]; 8214f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project int fd; 8224f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project struct sigaction act; 8234f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project char tmp[PROP_VALUE_MAX]; 8244f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project struct pollfd ufds[4]; 8254f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project char *tmpdev; 8265ae090ed949cea9d1e7ab1552b455a229f8f9757The Android Open Source Project char* debuggable; 8274f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 8284f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project act.sa_handler = sigchld_handler; 8294f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project act.sa_flags = SA_NOCLDSTOP; 8304f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project act.sa_mask = 0; 8314f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project act.sa_restorer = NULL; 8324f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project sigaction(SIGCHLD, &act, 0); 8334f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 8344f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project /* clear the umask */ 8354f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project umask(0); 8364f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 8374f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project /* Get the basic filesystem setup we need put 8384f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project * together in the initramdisk on / and then we'll 8394f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project * let the rc file figure out the rest. 8404f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project */ 8414f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project mkdir("/dev", 0755); 8424f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project mkdir("/proc", 0755); 8434f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project mkdir("/sys", 0755); 8444f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 8454f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project mount("tmpfs", "/dev", "tmpfs", 0, "mode=0755"); 8464f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project mkdir("/dev/pts", 0755); 8474f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project mkdir("/dev/socket", 0755); 8484f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project mount("devpts", "/dev/pts", "devpts", 0, NULL); 8494f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project mount("proc", "/proc", "proc", 0, NULL); 8504f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project mount("sysfs", "/sys", "sysfs", 0, NULL); 8514f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 8524f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project /* We must have some place other than / to create the 8534f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project * device nodes for kmsg and null, otherwise we won't 8544f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project * be able to remount / read-only later on. 8554f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project * Now that tmpfs is mounted on /dev, we can actually 8564f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project * talk to the outside world. 8574f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project */ 8584f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project open_devnull_stdio(); 8594f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project log_init(); 8604f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 8614f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project INFO("reading config file\n"); 8624f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project parse_config_file("/init.rc"); 8634f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 8644f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project /* pull the kernel commandline and ramdisk properties file in */ 8654f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project qemu_init(); 8664f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project import_kernel_cmdline(0); 8674f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 8684f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project get_hardware_name(); 8694f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project snprintf(tmp, sizeof(tmp), "/init.%s.rc", hardware); 8704f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project parse_config_file(tmp); 8714f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 8724f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project action_for_each_trigger("early-init", action_add_queue_tail); 8734f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project drain_action_queue(); 8744f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 8754f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project INFO("device init\n"); 8764f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project device_fd = device_init(); 8774f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 8784f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project property_init(); 8795ae090ed949cea9d1e7ab1552b455a229f8f9757The Android Open Source Project 8805ae090ed949cea9d1e7ab1552b455a229f8f9757The Android Open Source Project // only listen for keychords if ro.debuggable is true 8815ae090ed949cea9d1e7ab1552b455a229f8f9757The Android Open Source Project debuggable = property_get("ro.debuggable"); 8825ae090ed949cea9d1e7ab1552b455a229f8f9757The Android Open Source Project if (debuggable && !strcmp(debuggable, "1")) { 8835ae090ed949cea9d1e7ab1552b455a229f8f9757The Android Open Source Project keychord_fd = open_keychord(); 8845ae090ed949cea9d1e7ab1552b455a229f8f9757The Android Open Source Project } 8854f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 8864f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project if (console[0]) { 8874f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project snprintf(tmp, sizeof(tmp), "/dev/%s", console); 8884f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project console_name = strdup(tmp); 8894f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project } 8904f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 8914f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project fd = open(console_name, O_RDWR); 8924f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project if (fd >= 0) 8934f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project have_console = 1; 8944f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project close(fd); 8954f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 8964f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project if( load_565rle_image(INIT_IMAGE_FILE) ) { 8975ae090ed949cea9d1e7ab1552b455a229f8f9757The Android Open Source Project fd = open("/dev/tty0", O_WRONLY); 8985ae090ed949cea9d1e7ab1552b455a229f8f9757The Android Open Source Project if (fd >= 0) { 8995ae090ed949cea9d1e7ab1552b455a229f8f9757The Android Open Source Project const char *msg; 9004f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project msg = "\n" 9015ae090ed949cea9d1e7ab1552b455a229f8f9757The Android Open Source Project "\n" 9025ae090ed949cea9d1e7ab1552b455a229f8f9757The Android Open Source Project "\n" 9035ae090ed949cea9d1e7ab1552b455a229f8f9757The Android Open Source Project "\n" 9045ae090ed949cea9d1e7ab1552b455a229f8f9757The Android Open Source Project "\n" 9055ae090ed949cea9d1e7ab1552b455a229f8f9757The Android Open Source Project "\n" 9065ae090ed949cea9d1e7ab1552b455a229f8f9757The Android Open Source Project "\n" // console is 40 cols x 30 lines 9075ae090ed949cea9d1e7ab1552b455a229f8f9757The Android Open Source Project "\n" 9085ae090ed949cea9d1e7ab1552b455a229f8f9757The Android Open Source Project "\n" 9095ae090ed949cea9d1e7ab1552b455a229f8f9757The Android Open Source Project "\n" 9105ae090ed949cea9d1e7ab1552b455a229f8f9757The Android Open Source Project "\n" 9115ae090ed949cea9d1e7ab1552b455a229f8f9757The Android Open Source Project "\n" 9125ae090ed949cea9d1e7ab1552b455a229f8f9757The Android Open Source Project "\n" 9135ae090ed949cea9d1e7ab1552b455a229f8f9757The Android Open Source Project "\n" 9145ae090ed949cea9d1e7ab1552b455a229f8f9757The Android Open Source Project " A N D R O I D "; 9155ae090ed949cea9d1e7ab1552b455a229f8f9757The Android Open Source Project write(fd, msg, strlen(msg)); 9165ae090ed949cea9d1e7ab1552b455a229f8f9757The Android Open Source Project close(fd); 9175ae090ed949cea9d1e7ab1552b455a229f8f9757The Android Open Source Project } 9184f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project } 9194f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 9204f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project if (qemu[0]) 9214f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project import_kernel_cmdline(1); 9224f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 9234f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project if (!strcmp(bootmode,"factory")) 9244f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project property_set("ro.factorytest", "1"); 9254f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project else if (!strcmp(bootmode,"factory2")) 9264f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project property_set("ro.factorytest", "2"); 9274f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project else 9284f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project property_set("ro.factorytest", "0"); 9294f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 9304f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project property_set("ro.serialno", serialno[0] ? serialno : ""); 9314f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project property_set("ro.bootmode", bootmode[0] ? bootmode : "unknown"); 9324f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project property_set("ro.baseband", baseband[0] ? baseband : "unknown"); 9334f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project property_set("ro.carrier", carrier[0] ? carrier : "unknown"); 9344f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project property_set("ro.bootloader", bootloader[0] ? bootloader : "unknown"); 9354f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 9364f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project property_set("ro.hardware", hardware); 9374f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project snprintf(tmp, PROP_VALUE_MAX, "%d", revision); 9384f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project property_set("ro.revision", tmp); 9394f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 9404f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project /* execute all the boot actions to get us started */ 9414f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project action_for_each_trigger("init", action_add_queue_tail); 9424f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project drain_action_queue(); 9434f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 9444f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project /* read any property files on system or data and 9454f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project * fire up the property service. This must happen 9464f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project * after the ro.foo properties are set above so 9474f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project * that /data/local.prop cannot interfere with them. 9484f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project */ 9494f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project property_set_fd = start_property_service(); 9504f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 9514f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project /* create a signalling mechanism for the sigchld handler */ 9524f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project if (socketpair(AF_UNIX, SOCK_STREAM, 0, s) == 0) { 9534f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project signal_fd = s[0]; 9544f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project signal_recv_fd = s[1]; 9554f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project fcntl(s[0], F_SETFD, FD_CLOEXEC); 9564f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project fcntl(s[0], F_SETFL, O_NONBLOCK); 9574f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project fcntl(s[1], F_SETFD, FD_CLOEXEC); 9584f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project fcntl(s[1], F_SETFL, O_NONBLOCK); 9594f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project } 9604f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 9614f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project /* make sure we actually have all the pieces we need */ 9624f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project if ((device_fd < 0) || 9634f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project (property_set_fd < 0) || 9644f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project (signal_recv_fd < 0)) { 9654f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project ERROR("init startup failure\n"); 9664f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project return 1; 9674f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project } 9684f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 9694f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project /* execute all the boot actions to get us started */ 9704f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project action_for_each_trigger("early-boot", action_add_queue_tail); 9714f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project action_for_each_trigger("boot", action_add_queue_tail); 9724f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project drain_action_queue(); 9734f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 9744f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project /* run all property triggers based on current state of the properties */ 9754f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project queue_all_property_triggers(); 9764f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project drain_action_queue(); 9774f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 9784f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project /* enable property triggers */ 9794f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project property_triggers_enabled = 1; 9804f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 9814f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project ufds[0].fd = device_fd; 9824f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project ufds[0].events = POLLIN; 9834f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project ufds[1].fd = property_set_fd; 9844f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project ufds[1].events = POLLIN; 9854f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project ufds[2].fd = signal_recv_fd; 9864f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project ufds[2].events = POLLIN; 9875ae090ed949cea9d1e7ab1552b455a229f8f9757The Android Open Source Project fd_count = 3; 9885ae090ed949cea9d1e7ab1552b455a229f8f9757The Android Open Source Project 9895ae090ed949cea9d1e7ab1552b455a229f8f9757The Android Open Source Project if (keychord_fd > 0) { 9905ae090ed949cea9d1e7ab1552b455a229f8f9757The Android Open Source Project ufds[3].fd = keychord_fd; 9915ae090ed949cea9d1e7ab1552b455a229f8f9757The Android Open Source Project ufds[3].events = POLLIN; 9925ae090ed949cea9d1e7ab1552b455a229f8f9757The Android Open Source Project fd_count++; 9935ae090ed949cea9d1e7ab1552b455a229f8f9757The Android Open Source Project } else { 9945ae090ed949cea9d1e7ab1552b455a229f8f9757The Android Open Source Project ufds[3].events = 0; 9955ae090ed949cea9d1e7ab1552b455a229f8f9757The Android Open Source Project ufds[3].revents = 0; 9965ae090ed949cea9d1e7ab1552b455a229f8f9757The Android Open Source Project } 9974f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 9984f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project#if BOOTCHART 99935237d135807af84bf9b0e5b8d7f8633e58db6f5The Android Open Source Project bootchart_count = bootchart_init(); 100035237d135807af84bf9b0e5b8d7f8633e58db6f5The Android Open Source Project if (bootchart_count < 0) { 10014f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project ERROR("bootcharting init failure\n"); 100235237d135807af84bf9b0e5b8d7f8633e58db6f5The Android Open Source Project } else if (bootchart_count > 0) { 100335237d135807af84bf9b0e5b8d7f8633e58db6f5The Android Open Source Project NOTICE("bootcharting started (period=%d ms)\n", bootchart_count*BOOTCHART_POLLING_MS); 100435237d135807af84bf9b0e5b8d7f8633e58db6f5The Android Open Source Project } else { 100535237d135807af84bf9b0e5b8d7f8633e58db6f5The Android Open Source Project NOTICE("bootcharting ignored\n"); 10064f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project } 10074f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project#endif 10084f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 10094f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project for(;;) { 10105ae090ed949cea9d1e7ab1552b455a229f8f9757The Android Open Source Project int nr, i, timeout = -1; 10114f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 10125ae090ed949cea9d1e7ab1552b455a229f8f9757The Android Open Source Project for (i = 0; i < fd_count; i++) 10135ae090ed949cea9d1e7ab1552b455a229f8f9757The Android Open Source Project ufds[i].revents = 0; 10144f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 10154f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project drain_action_queue(); 10164f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project restart_processes(); 10174f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 10184f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project if (process_needs_restart) { 10194f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project timeout = (process_needs_restart - gettime()) * 1000; 10204f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project if (timeout < 0) 10214f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project timeout = 0; 10224f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project } 10234f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 10244f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project#if BOOTCHART 10254f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project if (bootchart_count > 0) { 10264f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project if (timeout < 0 || timeout > BOOTCHART_POLLING_MS) 10274f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project timeout = BOOTCHART_POLLING_MS; 10284f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project if (bootchart_step() < 0 || --bootchart_count == 0) { 10294f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project bootchart_finish(); 10304f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project bootchart_count = 0; 10314f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project } 10324f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project } 10334f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project#endif 10345ae090ed949cea9d1e7ab1552b455a229f8f9757The Android Open Source Project nr = poll(ufds, fd_count, timeout); 10354f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project if (nr <= 0) 10364f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project continue; 10374f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 10384f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project if (ufds[2].revents == POLLIN) { 10394f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project /* we got a SIGCHLD - reap and restart as needed */ 10404f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project read(signal_recv_fd, tmp, sizeof(tmp)); 10414f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project while (!wait_for_one_process(0)) 10424f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project ; 10434f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project continue; 10444f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project } 10454f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 10464f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project if (ufds[0].revents == POLLIN) 10474f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project handle_device_fd(device_fd); 10484f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 10494f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project if (ufds[1].revents == POLLIN) 10504f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project handle_property_set_fd(property_set_fd); 10515ae090ed949cea9d1e7ab1552b455a229f8f9757The Android Open Source Project if (ufds[3].revents == POLLIN) 10525ae090ed949cea9d1e7ab1552b455a229f8f9757The Android Open Source Project handle_keychord(keychord_fd); 10534f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project } 10544f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 10554f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project return 0; 10564f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project} 1057