init.c revision 165de92bf1bca1648b4df3047a8f274e0aff4ca9
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> 404f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 414f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project#include <sys/system_properties.h> 424f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 434f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project#include "devices.h" 444f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project#include "init.h" 454f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project#include "property_service.h" 464f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 474f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project#ifndef BOOTCHART 484f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project# define BOOTCHART 0 494f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project#endif 504f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 514f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Projectstatic int property_triggers_enabled = 0; 524f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 534f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project#if BOOTCHART 544f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Projectstatic int bootchart_count; 554f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Projectextern int bootchart_init(void); 564f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Projectextern int bootchart_step(void); 574f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Projectextern void bootchart_finish(void); 584f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project# define BOOTCHART_POLLING_MS 200 /* polling period in ms */ 594f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project# define BOOTCHART_MAX_TIME_MS (2*60*1000) /* max polling time from boot */ 604f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project# define BOOTCHART_MAX_COUNT (BOOTCHART_MAX_TIME_MS/BOOTCHART_POLLING_MS) 614f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project#endif 624f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 634f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Projectstatic char console[32]; 644f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Projectstatic char serialno[32]; 654f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Projectstatic char bootmode[32]; 664f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Projectstatic char baseband[32]; 674f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Projectstatic char carrier[32]; 684f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Projectstatic char bootloader[32]; 694f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Projectstatic char hardware[32]; 704f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Projectstatic unsigned revision = 0; 714f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Projectstatic char qemu[32]; 724f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 734f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Projectstatic void drain_action_queue(void); 744f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 754f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Projectstatic void notify_service_state(const char *name, const char *state) 764f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project{ 774f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project char pname[PROP_NAME_MAX]; 784f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project int len = strlen(name); 794f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project if ((len + 10) > PROP_NAME_MAX) 804f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project return; 814f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project snprintf(pname, sizeof(pname), "init.svc.%s", name); 824f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project property_set(pname, state); 834f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project} 844f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 854f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Projectstatic int have_console; 864f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Projectstatic char *console_name = "/dev/console"; 874f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Projectstatic time_t process_needs_restart; 884f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 894f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Projectstatic const char *ENV[32]; 904f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 914f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project/* add_environment - add "key=value" to the current environment */ 924f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Projectint add_environment(const char *key, const char *val) 934f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project{ 944f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project int n; 954f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 964f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project for (n = 0; n < 31; n++) { 974f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project if (!ENV[n]) { 984f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project size_t len = strlen(key) + strlen(val) + 2; 994f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project char *entry = malloc(len); 1004f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project snprintf(entry, len, "%s=%s", key, val); 1014f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project ENV[n] = entry; 1024f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project return 0; 1034f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project } 1044f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project } 1054f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 1064f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project return 1; 1074f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project} 1084f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 1094f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Projectstatic void zap_stdio(void) 1104f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project{ 1114f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project int fd; 1124f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project fd = open("/dev/null", O_RDWR); 1134f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project dup2(fd, 0); 1144f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project dup2(fd, 1); 1154f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project dup2(fd, 2); 1164f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project close(fd); 1174f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project} 1184f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 1194f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Projectstatic void open_console() 1204f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project{ 1214f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project int fd; 1224f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project if ((fd = open(console_name, O_RDWR)) < 0) { 1234f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project fd = open("/dev/null", O_RDWR); 1244f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project } 1254f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project dup2(fd, 0); 1264f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project dup2(fd, 1); 1274f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project dup2(fd, 2); 1284f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project close(fd); 1294f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project} 1304f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 1314f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project/* 1324f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project * gettime() - returns the time in seconds of the system's monotonic clock or 1334f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project * zero on error. 1344f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project */ 1354f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Projectstatic time_t gettime(void) 1364f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project{ 1374f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project struct timespec ts; 1384f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project int ret; 1394f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 1404f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project ret = clock_gettime(CLOCK_MONOTONIC, &ts); 1414f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project if (ret < 0) { 1424f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project ERROR("clock_gettime(CLOCK_MONOTONIC) failed: %s\n", strerror(errno)); 1434f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project return 0; 1444f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project } 1454f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 1464f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project return ts.tv_sec; 1474f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project} 1484f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 1494f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Projectstatic void publish_socket(const char *name, int fd) 1504f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project{ 1514f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project char key[64] = ANDROID_SOCKET_ENV_PREFIX; 1524f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project char val[64]; 1534f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 1544f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project strlcpy(key + sizeof(ANDROID_SOCKET_ENV_PREFIX) - 1, 1554f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project name, 1564f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project sizeof(key) - sizeof(ANDROID_SOCKET_ENV_PREFIX)); 1574f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project snprintf(val, sizeof(val), "%d", fd); 1584f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project add_environment(key, val); 1594f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 1604f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project /* make sure we don't close-on-exec */ 1614f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project fcntl(fd, F_SETFD, 0); 1624f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project} 1634f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 1644f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Projectvoid service_start(struct service *svc) 1654f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project{ 1664f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project struct stat s; 1674f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project pid_t pid; 1684f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project int needs_console; 1694f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project int n; 1704f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 1714f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project /* starting a service removes it from the disabled 1724f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project * state and immediately takes it out of the restarting 1734f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project * state if it was in there 1744f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project */ 1754f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project svc->flags &= (~(SVC_DISABLED|SVC_RESTARTING)); 1764f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project svc->time_started = 0; 1774f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 1784f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project /* running processes require no additional work -- if 1794f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project * they're in the process of exiting, we've ensured 1804f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project * that they will immediately restart on exit, unless 1814f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project * they are ONESHOT 1824f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project */ 1834f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project if (svc->flags & SVC_RUNNING) { 1844f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project return; 1854f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project } 1864f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 1874f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project needs_console = (svc->flags & SVC_CONSOLE) ? 1 : 0; 1884f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project if (needs_console && (!have_console)) { 1894f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project ERROR("service '%s' requires console\n", svc->name); 1904f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project svc->flags |= SVC_DISABLED; 1914f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project return; 1924f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project } 1934f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 1944f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project if (stat(svc->args[0], &s) != 0) { 1954f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project ERROR("cannot find '%s', disabling '%s'\n", svc->args[0], svc->name); 1964f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project svc->flags |= SVC_DISABLED; 1974f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project return; 1984f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project } 1994f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 2004f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project NOTICE("starting '%s'\n", svc->name); 2014f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 2024f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project pid = fork(); 2034f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 2044f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project if (pid == 0) { 2054f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project struct socketinfo *si; 2064f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project struct svcenvinfo *ei; 2074f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project char tmp[32]; 2084f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project int fd, sz; 2094f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 2104f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project get_property_workspace(&fd, &sz); 2114f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project sprintf(tmp, "%d,%d", dup(fd), sz); 2124f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project add_environment("ANDROID_PROPERTY_WORKSPACE", tmp); 2134f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 2144f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project for (ei = svc->envvars; ei; ei = ei->next) 2154f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project add_environment(ei->name, ei->value); 2164f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 2174f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project for (si = svc->sockets; si; si = si->next) { 2184f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project int s = create_socket(si->name, 2194f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project !strcmp(si->type, "dgram") ? 2204f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project SOCK_DGRAM : SOCK_STREAM, 2214f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project si->perm, si->uid, si->gid); 2224f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project if (s >= 0) { 2234f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project publish_socket(si->name, s); 2244f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project } 2254f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project } 2264f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 2274f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project if (needs_console) { 2284f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project setsid(); 2294f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project open_console(); 2304f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project } else { 2314f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project zap_stdio(); 2324f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project } 2334f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 2344f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project#if 0 2354f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project for (n = 0; svc->args[n]; n++) { 2364f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project INFO("args[%d] = '%s'\n", n, svc->args[n]); 2374f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project } 2384f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project for (n = 0; ENV[n]; n++) { 2394f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project INFO("env[%d] = '%s'\n", n, ENV[n]); 2404f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project } 2414f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project#endif 2424f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 2434f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project setpgid(0, getpid()); 2444f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 2454f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project /* as requested, set our gid, supplemental gids, and uid */ 2464f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project if (svc->gid) { 2474f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project setgid(svc->gid); 2484f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project } 2494f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project if (svc->nr_supp_gids) { 2504f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project setgroups(svc->nr_supp_gids, svc->supp_gids); 2514f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project } 2524f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project if (svc->uid) { 2534f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project setuid(svc->uid); 2544f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project } 2554f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 256165de92bf1bca1648b4df3047a8f274e0aff4ca9Ivan Djelic if (execve(svc->args[0], (char**) svc->args, (char**) ENV) < 0) { 257165de92bf1bca1648b4df3047a8f274e0aff4ca9Ivan Djelic ERROR("cannot execve('%s'): %s\n", svc->args[0], strerror(errno)); 258165de92bf1bca1648b4df3047a8f274e0aff4ca9Ivan Djelic } 2594f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project _exit(127); 2604f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project } 2614f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 2624f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project if (pid < 0) { 2634f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project ERROR("failed to start '%s'\n", svc->name); 2644f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project svc->pid = 0; 2654f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project return; 2664f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project } 2674f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 2684f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project svc->time_started = gettime(); 2694f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project svc->pid = pid; 2704f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project svc->flags |= SVC_RUNNING; 2714f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 2724f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project notify_service_state(svc->name, "running"); 2734f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project} 2744f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 2754f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Projectvoid service_stop(struct service *svc) 2764f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project{ 2774f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project /* we are no longer running, nor should we 2784f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project * attempt to restart 2794f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project */ 2804f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project svc->flags &= (~(SVC_RUNNING|SVC_RESTARTING)); 2814f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 2824f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project /* if the service has not yet started, prevent 2834f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project * it from auto-starting with its class 2844f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project */ 2854f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project svc->flags |= SVC_DISABLED; 2864f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 2874f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project if (svc->pid) { 2884f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project NOTICE("service '%s' is being killed\n", svc->name); 2894f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project kill(-svc->pid, SIGTERM); 2904f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project notify_service_state(svc->name, "stopping"); 2914f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project } else { 2924f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project notify_service_state(svc->name, "stopped"); 2934f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project } 2944f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project} 2954f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 2964f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Projectvoid property_changed(const char *name, const char *value) 2974f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project{ 2984f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project if (property_triggers_enabled) { 2994f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project queue_property_triggers(name, value); 3004f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project drain_action_queue(); 3014f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project } 3024f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project} 3034f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 3044f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project#define CRITICAL_CRASH_THRESHOLD 4 /* if we crash >4 times ... */ 3054f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project#define CRITICAL_CRASH_WINDOW (4*60) /* ... in 4 minutes, goto recovery*/ 3064f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 3074f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Projectstatic int wait_for_one_process(int block) 3084f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project{ 3094f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project pid_t pid; 3104f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project int status; 3114f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project struct service *svc; 3124f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project struct socketinfo *si; 3134f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project time_t now; 3144f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project struct listnode *node; 3154f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project struct command *cmd; 3164f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 3174f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project while ( (pid = waitpid(-1, &status, block ? 0 : WNOHANG)) == -1 && errno == EINTR ); 3184f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project if (pid <= 0) return -1; 3194f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project INFO("waitpid returned pid %d, status = %08x\n", pid, status); 3204f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 3214f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project svc = service_find_by_pid(pid); 3224f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project if (!svc) { 3234f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project ERROR("untracked pid %d exited\n", pid); 3244f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project return 0; 3254f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project } 3264f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 3274f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project NOTICE("process '%s', pid %d exited\n", svc->name, pid); 3284f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 3294f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project if (!(svc->flags & SVC_ONESHOT)) { 3304f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project kill(-pid, SIGKILL); 3314f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project NOTICE("process '%s' killing any children in process group\n", svc->name); 3324f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project } 3334f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 3344f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project /* remove any sockets we may have created */ 3354f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project for (si = svc->sockets; si; si = si->next) { 3364f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project char tmp[128]; 3374f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project snprintf(tmp, sizeof(tmp), ANDROID_SOCKET_DIR"/%s", si->name); 3384f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project unlink(tmp); 3394f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project } 3404f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 3414f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project svc->pid = 0; 3424f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project svc->flags &= (~SVC_RUNNING); 3434f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 3444f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project /* oneshot processes go into the disabled state on exit */ 3454f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project if (svc->flags & SVC_ONESHOT) { 3464f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project svc->flags |= SVC_DISABLED; 3474f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project } 3484f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 3494f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project /* disabled processes do not get restarted automatically */ 3504f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project if (svc->flags & SVC_DISABLED) { 3514f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project notify_service_state(svc->name, "stopped"); 3524f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project return 0; 3534f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project } 3544f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 3554f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project now = gettime(); 3564f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project if (svc->flags & SVC_CRITICAL) { 3574f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project if (svc->time_crashed + CRITICAL_CRASH_WINDOW >= now) { 3584f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project if (++svc->nr_crashed > CRITICAL_CRASH_THRESHOLD) { 3594f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project ERROR("critical process '%s' exited %d times in %d minutes; " 3604f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project "rebooting into recovery mode\n", svc->name, 3614f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project CRITICAL_CRASH_THRESHOLD, CRITICAL_CRASH_WINDOW / 60); 3624f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project sync(); 3634f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project __reboot(LINUX_REBOOT_MAGIC1, LINUX_REBOOT_MAGIC2, 3644f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project LINUX_REBOOT_CMD_RESTART2, "recovery"); 3654f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project return 0; 3664f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project } 3674f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project } else { 3684f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project svc->time_crashed = now; 3694f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project svc->nr_crashed = 1; 3704f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project } 3714f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project } 3724f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 3734f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project /* Execute all onrestart commands for this service. */ 3744f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project list_for_each(node, &svc->onrestart.commands) { 3754f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project cmd = node_to_item(node, struct command, clist); 3764f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project cmd->func(cmd->nargs, cmd->args); 3774f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project } 3784f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project svc->flags |= SVC_RESTARTING; 3794f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project notify_service_state(svc->name, "restarting"); 3804f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project return 0; 3814f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project} 3824f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 3834f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Projectstatic void restart_service_if_needed(struct service *svc) 3844f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project{ 3854f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project time_t next_start_time = svc->time_started + 5; 3864f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 3874f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project if (next_start_time <= gettime()) { 3884f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project svc->flags &= (~SVC_RESTARTING); 3894f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project service_start(svc); 3904f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project return; 3914f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project } 3924f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 3934f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project if ((next_start_time < process_needs_restart) || 3944f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project (process_needs_restart == 0)) { 3954f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project process_needs_restart = next_start_time; 3964f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project } 3974f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project} 3984f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 3994f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Projectstatic void restart_processes() 4004f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project{ 4014f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project process_needs_restart = 0; 4024f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project service_for_each_flags(SVC_RESTARTING, 4034f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project restart_service_if_needed); 4044f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project} 4054f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 4064f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Projectstatic int signal_fd = -1; 4074f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 4084f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Projectstatic void sigchld_handler(int s) 4094f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project{ 4104f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project write(signal_fd, &s, 1); 4114f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project} 4124f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 4134f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Projectstatic void msg_start(const char *name) 4144f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project{ 4154f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project struct service *svc = service_find_by_name(name); 4164f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 4174f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project if (svc) { 4184f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project service_start(svc); 4194f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project } else { 4204f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project ERROR("no such service '%s'\n", name); 4214f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project } 4224f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project} 4234f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 4244f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Projectstatic void msg_stop(const char *name) 4254f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project{ 4264f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project struct service *svc = service_find_by_name(name); 4274f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 4284f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project if (svc) { 4294f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project service_stop(svc); 4304f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project } else { 4314f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project ERROR("no such service '%s'\n"); 4324f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project } 4334f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project} 4344f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 4354f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Projectvoid handle_control_message(const char *msg, const char *arg) 4364f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project{ 4374f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project if (!strcmp(msg,"start")) { 4384f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project msg_start(arg); 4394f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project } else if (!strcmp(msg,"stop")) { 4404f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project msg_stop(arg); 4414f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project } else { 4424f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project ERROR("unknown control msg '%s'\n", msg); 4434f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project } 4444f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project} 4454f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 4464f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project#define MAX_MTD_PARTITIONS 16 4474f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 4484f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Projectstatic struct { 4494f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project char name[16]; 4504f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project int number; 4514f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project} mtd_part_map[MAX_MTD_PARTITIONS]; 4524f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 4534f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Projectstatic int mtd_part_count = -1; 4544f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 4554f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Projectstatic void find_mtd_partitions(void) 4564f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project{ 4574f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project int fd; 4584f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project char buf[1024]; 4594f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project char *pmtdbufp; 4604f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project ssize_t pmtdsize; 4614f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project int r; 4624f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 4634f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project fd = open("/proc/mtd", O_RDONLY); 4644f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project if (fd < 0) 4654f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project return; 4664f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 4674f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project buf[sizeof(buf) - 1] = '\0'; 4684f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project pmtdsize = read(fd, buf, sizeof(buf) - 1); 4694f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project pmtdbufp = buf; 4704f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project while (pmtdsize > 0) { 4714f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project int mtdnum, mtdsize, mtderasesize; 4724f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project char mtdname[16]; 4734f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project mtdname[0] = '\0'; 4744f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project mtdnum = -1; 4754f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project r = sscanf(pmtdbufp, "mtd%d: %x %x %15s", 4764f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project &mtdnum, &mtdsize, &mtderasesize, mtdname); 4774f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project if ((r == 4) && (mtdname[0] == '"')) { 4784f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project char *x = strchr(mtdname + 1, '"'); 4794f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project if (x) { 4804f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project *x = 0; 4814f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project } 4824f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project INFO("mtd partition %d, %s\n", mtdnum, mtdname + 1); 4834f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project if (mtd_part_count < MAX_MTD_PARTITIONS) { 4844f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project strcpy(mtd_part_map[mtd_part_count].name, mtdname + 1); 4854f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project mtd_part_map[mtd_part_count].number = mtdnum; 4864f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project mtd_part_count++; 4874f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project } else { 4884f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project ERROR("too many mtd partitions\n"); 4894f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project } 4904f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project } 4914f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project while (pmtdsize > 0 && *pmtdbufp != '\n') { 4924f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project pmtdbufp++; 4934f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project pmtdsize--; 4944f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project } 4954f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project if (pmtdsize > 0) { 4964f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project pmtdbufp++; 4974f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project pmtdsize--; 4984f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project } 4994f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project } 5004f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project close(fd); 5014f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project} 5024f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 5034f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Projectint mtd_name_to_number(const char *name) 5044f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project{ 5054f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project int n; 5064f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project if (mtd_part_count < 0) { 5074f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project mtd_part_count = 0; 5084f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project find_mtd_partitions(); 5094f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project } 5104f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project for (n = 0; n < mtd_part_count; n++) { 5114f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project if (!strcmp(name, mtd_part_map[n].name)) { 5124f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project return mtd_part_map[n].number; 5134f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project } 5144f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project } 5154f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project return -1; 5164f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project} 5174f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 5184f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Projectstatic void import_kernel_nv(char *name, int in_qemu) 5194f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project{ 5204f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project char *value = strchr(name, '='); 5214f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 5224f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project if (value == 0) return; 5234f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project *value++ = 0; 5244f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project if (*name == 0) return; 5254f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 5264f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project if (!in_qemu) 5274f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project { 5284f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project /* on a real device, white-list the kernel options */ 5294f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project if (!strcmp(name,"qemu")) { 5304f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project strlcpy(qemu, value, sizeof(qemu)); 5314f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project } else if (!strcmp(name,"androidboot.console")) { 5324f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project strlcpy(console, value, sizeof(console)); 5334f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project } else if (!strcmp(name,"androidboot.mode")) { 5344f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project strlcpy(bootmode, value, sizeof(bootmode)); 5354f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project } else if (!strcmp(name,"androidboot.serialno")) { 5364f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project strlcpy(serialno, value, sizeof(serialno)); 5374f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project } else if (!strcmp(name,"androidboot.baseband")) { 5384f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project strlcpy(baseband, value, sizeof(baseband)); 5394f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project } else if (!strcmp(name,"androidboot.carrier")) { 5404f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project strlcpy(carrier, value, sizeof(carrier)); 5414f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project } else if (!strcmp(name,"androidboot.bootloader")) { 5424f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project strlcpy(bootloader, value, sizeof(bootloader)); 5434f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project } else if (!strcmp(name,"androidboot.hardware")) { 5444f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project strlcpy(hardware, value, sizeof(hardware)); 5454f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project } else { 5464f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project qemu_cmdline(name, value); 5474f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project } 5484f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project } else { 5494f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project /* in the emulator, export any kernel option with the 5504f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project * ro.kernel. prefix */ 5514f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project char buff[32]; 5524f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project int len = snprintf( buff, sizeof(buff), "ro.kernel.%s", name ); 5534f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project if (len < (int)sizeof(buff)) { 5544f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project property_set( buff, value ); 5554f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project } 5564f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project } 5574f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project} 5584f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 5594f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Projectstatic void import_kernel_cmdline(int in_qemu) 5604f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project{ 5614f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project char cmdline[1024]; 5624f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project char *ptr; 5634f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project int fd; 5644f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 5654f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project fd = open("/proc/cmdline", O_RDONLY); 5664f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project if (fd >= 0) { 5674f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project int n = read(fd, cmdline, 1023); 5684f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project if (n < 0) n = 0; 5694f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 5704f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project /* get rid of trailing newline, it happens */ 5714f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project if (n > 0 && cmdline[n-1] == '\n') n--; 5724f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 5734f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project cmdline[n] = 0; 5744f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project close(fd); 5754f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project } else { 5764f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project cmdline[0] = 0; 5774f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project } 5784f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 5794f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project ptr = cmdline; 5804f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project while (ptr && *ptr) { 5814f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project char *x = strchr(ptr, ' '); 5824f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project if (x != 0) *x++ = 0; 5834f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project import_kernel_nv(ptr, in_qemu); 5844f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project ptr = x; 5854f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project } 5864f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 5874f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project /* don't expose the raw commandline to nonpriv processes */ 5884f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project chmod("/proc/cmdline", 0440); 5894f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project} 5904f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 5914f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Projectstatic void get_hardware_name(void) 5924f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project{ 5934f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project char data[1024]; 5944f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project int fd, n; 5954f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project char *x, *hw, *rev; 5964f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 5974f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project /* Hardware string was provided on kernel command line */ 5984f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project if (hardware[0]) 5994f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project return; 6004f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 6014f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project fd = open("/proc/cpuinfo", O_RDONLY); 6024f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project if (fd < 0) return; 6034f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 6044f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project n = read(fd, data, 1023); 6054f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project close(fd); 6064f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project if (n < 0) return; 6074f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 6084f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project data[n] = 0; 6094f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project hw = strstr(data, "\nHardware"); 6104f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project rev = strstr(data, "\nRevision"); 6114f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 6124f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project if (hw) { 6134f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project x = strstr(hw, ": "); 6144f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project if (x) { 6154f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project x += 2; 6164f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project n = 0; 6174f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project while (*x && !isspace(*x)) { 6184f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project hardware[n++] = tolower(*x); 6194f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project x++; 6204f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project if (n == 31) break; 6214f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project } 6224f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project hardware[n] = 0; 6234f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project } 6244f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project } 6254f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 6264f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project if (rev) { 6274f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project x = strstr(rev, ": "); 6284f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project if (x) { 6294f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project revision = strtoul(x + 2, 0, 16); 6304f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project } 6314f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project } 6324f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project} 6334f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 6344f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Projectstatic void drain_action_queue(void) 6354f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project{ 6364f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project struct listnode *node; 6374f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project struct command *cmd; 6384f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project struct action *act; 6394f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project int ret; 6404f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 6414f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project while ((act = action_remove_queue_head())) { 6424f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project INFO("processing action %p (%s)\n", act, act->name); 6434f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project list_for_each(node, &act->commands) { 6444f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project cmd = node_to_item(node, struct command, clist); 6454f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project ret = cmd->func(cmd->nargs, cmd->args); 6464f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project INFO("command '%s' r=%d\n", cmd->args[0], ret); 6474f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project } 6484f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project } 6494f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project} 6504f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 6514f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Projectvoid open_devnull_stdio(void) 6524f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project{ 6534f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project int fd; 6544f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project static const char *name = "/dev/__null__"; 6554f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project if (mknod(name, S_IFCHR | 0600, (1 << 8) | 3) == 0) { 6564f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project fd = open(name, O_RDWR); 6574f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project unlink(name); 6584f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project if (fd >= 0) { 6594f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project dup2(fd, 0); 6604f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project dup2(fd, 1); 6614f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project dup2(fd, 2); 6624f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project if (fd > 2) { 6634f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project close(fd); 6644f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project } 6654f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project return; 6664f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project } 6674f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project } 6684f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 6694f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project exit(1); 6704f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project} 6714f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 6724f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Projectint main(int argc, char **argv) 6734f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project{ 6744f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project int device_fd = -1; 6754f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project int property_set_fd = -1; 6764f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project int signal_recv_fd = -1; 6774f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project int s[2]; 6784f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project int fd; 6794f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project struct sigaction act; 6804f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project char tmp[PROP_VALUE_MAX]; 6814f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project struct pollfd ufds[4]; 6824f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project char *tmpdev; 6834f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 6844f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project act.sa_handler = sigchld_handler; 6854f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project act.sa_flags = SA_NOCLDSTOP; 6864f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project act.sa_mask = 0; 6874f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project act.sa_restorer = NULL; 6884f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project sigaction(SIGCHLD, &act, 0); 6894f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 6904f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project /* clear the umask */ 6914f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project umask(0); 6924f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 6934f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project /* Get the basic filesystem setup we need put 6944f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project * together in the initramdisk on / and then we'll 6954f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project * let the rc file figure out the rest. 6964f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project */ 6974f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project mkdir("/dev", 0755); 6984f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project mkdir("/proc", 0755); 6994f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project mkdir("/sys", 0755); 7004f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 7014f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project mount("tmpfs", "/dev", "tmpfs", 0, "mode=0755"); 7024f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project mkdir("/dev/pts", 0755); 7034f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project mkdir("/dev/socket", 0755); 7044f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project mount("devpts", "/dev/pts", "devpts", 0, NULL); 7054f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project mount("proc", "/proc", "proc", 0, NULL); 7064f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project mount("sysfs", "/sys", "sysfs", 0, NULL); 7074f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 7084f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project /* We must have some place other than / to create the 7094f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project * device nodes for kmsg and null, otherwise we won't 7104f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project * be able to remount / read-only later on. 7114f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project * Now that tmpfs is mounted on /dev, we can actually 7124f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project * talk to the outside world. 7134f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project */ 7144f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project open_devnull_stdio(); 7154f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project log_init(); 7164f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 7174f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project INFO("reading config file\n"); 7184f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project parse_config_file("/init.rc"); 7194f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 7204f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project /* pull the kernel commandline and ramdisk properties file in */ 7214f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project qemu_init(); 7224f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project import_kernel_cmdline(0); 7234f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 7244f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project get_hardware_name(); 7254f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project snprintf(tmp, sizeof(tmp), "/init.%s.rc", hardware); 7264f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project parse_config_file(tmp); 7274f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 7284f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project action_for_each_trigger("early-init", action_add_queue_tail); 7294f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project drain_action_queue(); 7304f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 7314f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project INFO("device init\n"); 7324f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project device_fd = device_init(); 7334f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 7344f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project property_init(); 7354f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 7364f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project if (console[0]) { 7374f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project snprintf(tmp, sizeof(tmp), "/dev/%s", console); 7384f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project console_name = strdup(tmp); 7394f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project } 7404f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 7414f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project fd = open(console_name, O_RDWR); 7424f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project if (fd >= 0) 7434f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project have_console = 1; 7444f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project close(fd); 7454f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 7464f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project if( load_565rle_image(INIT_IMAGE_FILE) ) { 7474f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project fd = open("/dev/tty0", O_WRONLY); 7484f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project if (fd >= 0) { 7494f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project const char *msg; 7504f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project msg = "\n" 7514f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project "\n" 7524f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project "\n" 7534f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project "\n" 7544f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project "\n" 7554f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project "\n" 7564f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project "\n" // console is 40 cols x 30 lines 7574f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project "\n" 7584f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project "\n" 7594f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project "\n" 7604f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project "\n" 7614f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project "\n" 7624f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project "\n" 7634f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project "\n" 7644f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project " A N D R O I D "; 7654f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project write(fd, msg, strlen(msg)); 7664f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project close(fd); 7674f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project } 7684f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project } 7694f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 7704f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project if (qemu[0]) 7714f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project import_kernel_cmdline(1); 7724f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 7734f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project if (!strcmp(bootmode,"factory")) 7744f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project property_set("ro.factorytest", "1"); 7754f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project else if (!strcmp(bootmode,"factory2")) 7764f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project property_set("ro.factorytest", "2"); 7774f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project else 7784f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project property_set("ro.factorytest", "0"); 7794f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 7804f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project property_set("ro.serialno", serialno[0] ? serialno : ""); 7814f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project property_set("ro.bootmode", bootmode[0] ? bootmode : "unknown"); 7824f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project property_set("ro.baseband", baseband[0] ? baseband : "unknown"); 7834f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project property_set("ro.carrier", carrier[0] ? carrier : "unknown"); 7844f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project property_set("ro.bootloader", bootloader[0] ? bootloader : "unknown"); 7854f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 7864f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project property_set("ro.hardware", hardware); 7874f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project snprintf(tmp, PROP_VALUE_MAX, "%d", revision); 7884f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project property_set("ro.revision", tmp); 7894f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 7904f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project /* execute all the boot actions to get us started */ 7914f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project action_for_each_trigger("init", action_add_queue_tail); 7924f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project drain_action_queue(); 7934f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 7944f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project /* read any property files on system or data and 7954f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project * fire up the property service. This must happen 7964f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project * after the ro.foo properties are set above so 7974f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project * that /data/local.prop cannot interfere with them. 7984f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project */ 7994f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project property_set_fd = start_property_service(); 8004f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 8014f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project /* create a signalling mechanism for the sigchld handler */ 8024f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project if (socketpair(AF_UNIX, SOCK_STREAM, 0, s) == 0) { 8034f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project signal_fd = s[0]; 8044f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project signal_recv_fd = s[1]; 8054f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project fcntl(s[0], F_SETFD, FD_CLOEXEC); 8064f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project fcntl(s[0], F_SETFL, O_NONBLOCK); 8074f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project fcntl(s[1], F_SETFD, FD_CLOEXEC); 8084f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project fcntl(s[1], F_SETFL, O_NONBLOCK); 8094f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project } 8104f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 8114f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project /* make sure we actually have all the pieces we need */ 8124f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project if ((device_fd < 0) || 8134f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project (property_set_fd < 0) || 8144f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project (signal_recv_fd < 0)) { 8154f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project ERROR("init startup failure\n"); 8164f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project return 1; 8174f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project } 8184f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 8194f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project /* execute all the boot actions to get us started */ 8204f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project action_for_each_trigger("early-boot", action_add_queue_tail); 8214f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project action_for_each_trigger("boot", action_add_queue_tail); 8224f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project drain_action_queue(); 8234f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 8244f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project /* run all property triggers based on current state of the properties */ 8254f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project queue_all_property_triggers(); 8264f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project drain_action_queue(); 8274f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 8284f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project /* enable property triggers */ 8294f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project property_triggers_enabled = 1; 8304f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 8314f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project ufds[0].fd = device_fd; 8324f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project ufds[0].events = POLLIN; 8334f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project ufds[1].fd = property_set_fd; 8344f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project ufds[1].events = POLLIN; 8354f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project ufds[2].fd = signal_recv_fd; 8364f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project ufds[2].events = POLLIN; 8374f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 8384f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project#if BOOTCHART 8394f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project if (bootchart_init() < 0) 8404f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project ERROR("bootcharting init failure\n"); 8414f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project else { 8424f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project NOTICE("bootcharting started\n"); 8434f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project bootchart_count = BOOTCHART_MAX_COUNT; 8444f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project } 8454f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project#endif 8464f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 8474f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project for(;;) { 8484f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project int nr, timeout = -1; 8494f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 8504f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project ufds[0].revents = 0; 8514f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project ufds[1].revents = 0; 8524f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project ufds[2].revents = 0; 8534f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 8544f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project drain_action_queue(); 8554f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project restart_processes(); 8564f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 8574f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project if (process_needs_restart) { 8584f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project timeout = (process_needs_restart - gettime()) * 1000; 8594f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project if (timeout < 0) 8604f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project timeout = 0; 8614f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project } 8624f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 8634f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project#if BOOTCHART 8644f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project if (bootchart_count > 0) { 8654f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project if (timeout < 0 || timeout > BOOTCHART_POLLING_MS) 8664f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project timeout = BOOTCHART_POLLING_MS; 8674f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project if (bootchart_step() < 0 || --bootchart_count == 0) { 8684f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project bootchart_finish(); 8694f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project bootchart_count = 0; 8704f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project } 8714f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project } 8724f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project#endif 8734f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project nr = poll(ufds, 3, timeout); 8744f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project if (nr <= 0) 8754f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project continue; 8764f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 8774f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project if (ufds[2].revents == POLLIN) { 8784f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project /* we got a SIGCHLD - reap and restart as needed */ 8794f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project read(signal_recv_fd, tmp, sizeof(tmp)); 8804f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project while (!wait_for_one_process(0)) 8814f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project ; 8824f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project continue; 8834f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project } 8844f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 8854f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project if (ufds[0].revents == POLLIN) 8864f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project handle_device_fd(device_fd); 8874f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 8884f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project if (ufds[1].revents == POLLIN) 8894f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project handle_property_set_fd(property_set_fd); 8904f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project } 8914f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project 8924f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project return 0; 8934f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project} 894