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 36 static void coldboot(const char *path); 37 static void sigchld_handler(int sig); 38 39 int main() { 40 41 CommandListener *cl; 42 NetlinkManager *nm; 43 44 LOGI("Netd 1.0 starting"); 45 46 // signal(SIGCHLD, sigchld_handler); 47 48 if (!(nm = NetlinkManager::Instance())) { 49 LOGE("Unable to create NetlinkManager"); 50 exit(1); 51 }; 52 53 54 cl = new CommandListener(); 55 nm->setBroadcaster((SocketListener *) cl); 56 57 if (nm->start()) { 58 LOGE("Unable to start NetlinkManager (%s)", strerror(errno)); 59 exit(1); 60 } 61 62 /* 63 * Now that we're up, we can respond to commands 64 */ 65 if (cl->startListener()) { 66 LOGE("Unable to start CommandListener (%s)", strerror(errno)); 67 exit(1); 68 } 69 70 // Eventually we'll become the monitoring thread 71 while(1) { 72 sleep(1000); 73 } 74 75 LOGI("Netd exiting"); 76 exit(0); 77 } 78 79 static void do_coldboot(DIR *d, int lvl) 80 { 81 struct dirent *de; 82 int dfd, fd; 83 84 dfd = dirfd(d); 85 86 fd = openat(dfd, "uevent", O_WRONLY); 87 if(fd >= 0) { 88 write(fd, "add\n", 4); 89 close(fd); 90 } 91 92 while((de = readdir(d))) { 93 DIR *d2; 94 95 if (de->d_name[0] == '.') 96 continue; 97 98 if (de->d_type != DT_DIR && lvl > 0) 99 continue; 100 101 fd = openat(dfd, de->d_name, O_RDONLY | O_DIRECTORY); 102 if(fd < 0) 103 continue; 104 105 d2 = fdopendir(fd); 106 if(d2 == 0) 107 close(fd); 108 else { 109 do_coldboot(d2, lvl + 1); 110 closedir(d2); 111 } 112 } 113 } 114 115 static void coldboot(const char *path) 116 { 117 DIR *d = opendir(path); 118 if(d) { 119 do_coldboot(d, 0); 120 closedir(d); 121 } 122 } 123 124 static void sigchld_handler(int sig) { 125 pid_t pid = wait(NULL); 126 LOGD("Child process %d exited", pid); 127 } 128