main.cpp revision 08b58b60fd70e81317a9df19cc431f0759bc9e71
1/* 2 * Copyright (C) 2008 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17#include <stdio.h> 18#include <stdlib.h> 19#include <signal.h> 20#include <errno.h> 21#include <string.h> 22#include <sys/stat.h> 23#include <sys/types.h> 24#include <sys/wait.h> 25 26#include <fcntl.h> 27#include <dirent.h> 28 29#define LOG_TAG "Netd" 30 31#include "cutils/log.h" 32 33#include "CommandListener.h" 34#include "NetlinkManager.h" 35#include "DnsProxyListener.h" 36 37static void coldboot(const char *path); 38static void sigchld_handler(int sig); 39 40int main() { 41 42 CommandListener *cl; 43 NetlinkManager *nm; 44 DnsProxyListener *dpl; 45 46 ALOGI("Netd 1.0 starting"); 47 48// signal(SIGCHLD, sigchld_handler); 49 50 if (!(nm = NetlinkManager::Instance())) { 51 LOGE("Unable to create NetlinkManager"); 52 exit(1); 53 }; 54 55 56 cl = new CommandListener(); 57 nm->setBroadcaster((SocketListener *) cl); 58 59 if (nm->start()) { 60 LOGE("Unable to start NetlinkManager (%s)", strerror(errno)); 61 exit(1); 62 } 63 64 // Set local DNS mode, to prevent bionic from proxying 65 // back to this service, recursively. 66 setenv("ANDROID_DNS_MODE", "local", 1); 67 dpl = new DnsProxyListener(); 68 if (dpl->startListener()) { 69 LOGE("Unable to start DnsProxyListener (%s)", strerror(errno)); 70 exit(1); 71 } 72 73 /* 74 * Now that we're up, we can respond to commands 75 */ 76 if (cl->startListener()) { 77 LOGE("Unable to start CommandListener (%s)", strerror(errno)); 78 exit(1); 79 } 80 81 // Eventually we'll become the monitoring thread 82 while(1) { 83 sleep(1000); 84 } 85 86 ALOGI("Netd exiting"); 87 exit(0); 88} 89 90static void do_coldboot(DIR *d, int lvl) 91{ 92 struct dirent *de; 93 int dfd, fd; 94 95 dfd = dirfd(d); 96 97 fd = openat(dfd, "uevent", O_WRONLY); 98 if(fd >= 0) { 99 write(fd, "add\n", 4); 100 close(fd); 101 } 102 103 while((de = readdir(d))) { 104 DIR *d2; 105 106 if (de->d_name[0] == '.') 107 continue; 108 109 if (de->d_type != DT_DIR && lvl > 0) 110 continue; 111 112 fd = openat(dfd, de->d_name, O_RDONLY | O_DIRECTORY); 113 if(fd < 0) 114 continue; 115 116 d2 = fdopendir(fd); 117 if(d2 == 0) 118 close(fd); 119 else { 120 do_coldboot(d2, lvl + 1); 121 closedir(d2); 122 } 123 } 124} 125 126static void coldboot(const char *path) 127{ 128 DIR *d = opendir(path); 129 if(d) { 130 do_coldboot(d, 0); 131 closedir(d); 132 } 133} 134 135static void sigchld_handler(int sig) { 136 pid_t pid = wait(NULL); 137 ALOGD("Child process %d exited", pid); 138} 139