diff options
author | Jean-Baptiste Queru <jbq@google.com> | 2009-07-25 18:07:41 -0700 |
---|---|---|
committer | Jean-Baptiste Queru <jbq@google.com> | 2009-07-25 18:07:41 -0700 |
commit | 96d58f4f521ee4c1fef58efe5c009f1ea523d67c (patch) | |
tree | 75aa0cdbbcb6e35a93c43550c724bc4dba13dbea /init | |
parent | dc9d52f35d6d590863b358997bf25605cf72be5f (diff) | |
parent | 3d9b265b7d34d886a2f44e486c25e402d7df791b (diff) | |
download | system_core-96d58f4f521ee4c1fef58efe5c009f1ea523d67c.zip system_core-96d58f4f521ee4c1fef58efe5c009f1ea523d67c.tar.gz system_core-96d58f4f521ee4c1fef58efe5c009f1ea523d67c.tar.bz2 |
Merge korg/donut into korg/master
Diffstat (limited to 'init')
-rw-r--r-- | init/builtins.c | 6 | ||||
-rw-r--r-- | init/devices.c | 9 | ||||
-rw-r--r-- | init/init.c | 57 | ||||
-rw-r--r-- | init/init.h | 15 | ||||
-rw-r--r-- | init/parser.c | 10 | ||||
-rw-r--r-- | init/property_service.c | 9 |
6 files changed, 79 insertions, 27 deletions
diff --git a/init/builtins.c b/init/builtins.c index bcdfee1..93ce6e8 100644 --- a/init/builtins.c +++ b/init/builtins.c @@ -127,7 +127,7 @@ done: static void service_start_if_not_disabled(struct service *svc) { if (!(svc->flags & SVC_DISABLED)) { - service_start(svc); + service_start(svc, NULL); } } @@ -372,7 +372,7 @@ int do_start(int nargs, char **args) struct service *svc; svc = service_find_by_name(args[1]); if (svc) { - service_start(svc); + service_start(svc, NULL); } return 0; } @@ -393,7 +393,7 @@ int do_restart(int nargs, char **args) svc = service_find_by_name(args[1]); if (svc) { service_stop(svc); - service_start(svc); + service_start(svc, NULL); } return 0; } diff --git a/init/devices.c b/init/devices.c index e0b1f1f..60f9b9c 100644 --- a/init/devices.c +++ b/init/devices.c @@ -115,6 +115,7 @@ static struct perms_ devperms[] = { { "/dev/oncrpc/", 0660, AID_ROOT, AID_SYSTEM, 1 }, { "/dev/adsp/", 0660, AID_SYSTEM, AID_AUDIO, 1 }, { "/dev/mt9t013", 0660, AID_SYSTEM, AID_SYSTEM, 0 }, + { "/dev/msm_camera/", 0660, AID_SYSTEM, AID_SYSTEM, 1 }, { "/dev/akm8976_daemon",0640, AID_COMPASS, AID_SYSTEM, 0 }, { "/dev/akm8976_aot", 0640, AID_COMPASS, AID_SYSTEM, 0 }, { "/dev/akm8976_pffd", 0640, AID_COMPASS, AID_SYSTEM, 0 }, @@ -126,10 +127,13 @@ static struct perms_ devperms[] = { { "/dev/msm_audpre", 0660, AID_SYSTEM, AID_AUDIO, 0 }, { "/dev/htc-acoustic", 0660, AID_SYSTEM, AID_AUDIO, 0 }, { "/dev/smd0", 0640, AID_RADIO, AID_RADIO, 0 }, + { "/dev/qemu_trace", 0666, AID_SYSTEM, AID_SYSTEM, 0 }, { "/dev/qmi", 0640, AID_RADIO, AID_RADIO, 0 }, { "/dev/qmi0", 0640, AID_RADIO, AID_RADIO, 0 }, { "/dev/qmi1", 0640, AID_RADIO, AID_RADIO, 0 }, { "/dev/qmi2", 0640, AID_RADIO, AID_RADIO, 0 }, + { "/dev/ppp", 0660, AID_RADIO, AID_VPN, 0 }, + { "/dev/tun", 0640, AID_VPN, AID_VPN, 0 }, { NULL, 0, 0, 0, 0 }, }; @@ -380,7 +384,10 @@ static void handle_device_event(struct uevent *uevent) } else if (!strncmp(uevent->subsystem, "adsp", 4)) { base = "/dev/adsp/"; mkdir(base, 0755); - } else if(!strncmp(uevent->subsystem, "input", 5)) { + } else if (!strncmp(uevent->subsystem, "msm_camera", 10)) { + base = "/dev/msm_camera/"; + mkdir(base, 0755); + } else if(!strncmp(uevent->subsystem, "input", 5)) { base = "/dev/input/"; mkdir(base, 0755); } else if(!strncmp(uevent->subsystem, "mtd", 3)) { diff --git a/init/init.c b/init/init.c index 1630155..dfc858a 100644 --- a/init/init.c +++ b/init/init.c @@ -156,7 +156,7 @@ static void publish_socket(const char *name, int fd) fcntl(fd, F_SETFD, 0); } -void service_start(struct service *svc) +void service_start(struct service *svc, const char *dynamic_args) { struct stat s; pid_t pid; @@ -192,6 +192,13 @@ void service_start(struct service *svc) return; } + if ((!(svc->flags & SVC_ONESHOT)) && dynamic_args) { + ERROR("service '%s' must be one-shot to use dynamic args, disabling\n", + svc->args[0]); + svc->flags |= SVC_DISABLED; + return; + } + NOTICE("starting '%s'\n", svc->name); pid = fork(); @@ -248,8 +255,27 @@ void service_start(struct service *svc) setuid(svc->uid); } - if (execve(svc->args[0], (char**) svc->args, (char**) ENV) < 0) { - ERROR("cannot execve('%s'): %s\n", svc->args[0], strerror(errno)); + if (!dynamic_args) + if (execve(svc->args[0], (char**) svc->args, (char**) ENV) < 0) + ERROR("cannot execve('%s'): %s\n", svc->args[0], strerror(errno)); + else { + char *arg_ptrs[SVC_MAXARGS+1]; + int arg_idx = svc->nargs; + char *tmp = strdup(dynamic_args); + char *next = tmp; + char *bword; + + /* Copy the static arguments */ + memcpy(arg_ptrs, svc->args, (svc->nargs * sizeof(char *))); + + while((bword = strsep(&next, " "))) { + arg_ptrs[arg_idx++] = bword; + if (arg_idx == SVC_MAXARGS) + break; + } + arg_ptrs[arg_idx] = '\0'; + if (execve(svc->args[0], (char**) arg_ptrs, (char**) ENV) < 0) + ERROR("cannot execve('%s'): %s\n", svc->args[0], strerror(errno)); } _exit(127); } @@ -381,7 +407,7 @@ static void restart_service_if_needed(struct service *svc) if (next_start_time <= gettime()) { svc->flags &= (~SVC_RESTARTING); - service_start(svc); + service_start(svc, NULL); return; } @@ -407,13 +433,28 @@ static void sigchld_handler(int s) static void msg_start(const char *name) { - struct service *svc = service_find_by_name(name); + struct service *svc; + char *tmp = NULL; + char *args = NULL; + + if (!strchr(name, ':')) + svc = service_find_by_name(name); + else { + tmp = strdup(name); + args = strchr(tmp, ':'); + *args = '\0'; + args++; + + svc = service_find_by_name(tmp); + } if (svc) { - service_start(svc); + service_start(svc, args); } else { ERROR("no such service '%s'\n", name); } + if (tmp) + free(tmp); } static void msg_stop(const char *name) @@ -423,7 +464,7 @@ static void msg_stop(const char *name) if (svc) { service_stop(svc); } else { - ERROR("no such service '%s'\n"); + ERROR("no such service '%s'\n", name); } } @@ -739,7 +780,7 @@ void handle_keychord(int fd) svc = service_find_by_keychord(id); if (svc) { INFO("starting service %s from keychord\n", svc->name); - service_start(svc); + service_start(svc, NULL); } else { ERROR("service for keychord %d not found\n", id); } diff --git a/init/init.h b/init/init.h index b686869..f306b7b 100644 --- a/init/init.h +++ b/init/init.h @@ -29,7 +29,8 @@ void *read_file(const char *fn, unsigned *_sz); void log_init(void); void log_set_level(int level); void log_close(void); -void log_write(int level, const char *fmt, ...); +void log_write(int level, const char *fmt, ...) + __attribute__ ((format(printf, 2, 3))); #define ERROR(x...) log_write(3, "<3>init: " x) #define NOTICE(x...) log_write(5, "<5>init: " x) @@ -115,6 +116,8 @@ struct svcenvinfo { #define NR_SVC_SUPP_GIDS 6 /* six supplementary groups */ +#define SVC_MAXARGS 64 + struct service { /* list of all services */ struct listnode slist; @@ -136,15 +139,17 @@ struct service { struct socketinfo *sockets; struct svcenvinfo *envvars; - int nargs; - char *args[1]; struct action onrestart; /* Actions to execute on restart. */ /* keycodes for triggering this service via /dev/keychord */ int *keycodes; int nkeycodes; int keychord_id; -}; + + int nargs; + /* "MUST BE AT THE END OF THE STRUCT" */ + char *args[1]; +}; /* ^-------'args' MUST be at the end of this struct! */ int parse_config_file(const char *fn); @@ -157,7 +162,7 @@ void service_for_each_class(const char *classname, void service_for_each_flags(unsigned matchflags, void (*func)(struct service *svc)); void service_stop(struct service *svc); -void service_start(struct service *svc); +void service_start(struct service *svc, const char *dynamic_args); void property_changed(const char *name, const char *value); struct action *action_remove_queue_head(void); diff --git a/init/parser.c b/init/parser.c index 6a22d24..33c1a68 100644 --- a/init/parser.c +++ b/init/parser.c @@ -60,8 +60,6 @@ void DUMP(void) #endif } -#define MAXARGS 64 - #define T_EOF 0 #define T_TEXT 1 #define T_NEWLINE 2 @@ -357,7 +355,7 @@ void parse_new_section(struct parse_state *state, int kw, static void parse_config(const char *fn, char *s) { struct parse_state state; - char *args[MAXARGS]; + char *args[SVC_MAXARGS]; int nargs; nargs = 0; @@ -384,7 +382,7 @@ static void parse_config(const char *fn, char *s) } break; case T_TEXT: - if (nargs < MAXARGS) { + if (nargs < SVC_MAXARGS) { args[nargs++] = state.text; } break; @@ -536,7 +534,7 @@ void queue_all_property_triggers() const char* name = act->name + strlen("property:"); const char* equals = strchr(name, '='); if (equals) { - char* prop_name[PROP_NAME_MAX + 1]; + char prop_name[PROP_NAME_MAX + 1]; const char* value; int length = equals - name; if (length > PROP_NAME_MAX) { @@ -546,7 +544,7 @@ void queue_all_property_triggers() prop_name[length] = 0; /* does the property exist, and match the trigger value? */ - value = property_get((const char *)&prop_name[0]); + value = property_get(prop_name); if (value && !strcmp(equals + 1, value)) { action_add_queue_tail(act); } diff --git a/init/property_service.c b/init/property_service.c index 0bc6239..23a8821 100644 --- a/init/property_service.c +++ b/init/property_service.c @@ -67,6 +67,8 @@ struct { { "wlan.", AID_SYSTEM }, { "dhcp.", AID_SYSTEM }, { "dhcp.", AID_DHCP }, + { "vpn.", AID_SYSTEM }, + { "vpn.", AID_VPN }, { "debug.", AID_SHELL }, { "log.", AID_SHELL }, { "service.adb.root", AID_SHELL }, @@ -296,7 +298,7 @@ int property_set(const char *name, const char *value) __futex_wake(&pa->serial, INT32_MAX); } /* If name starts with "net." treat as a DNS property. */ - if (strncmp("net.", name, sizeof("net.") - 1) == 0) { + if (strncmp("net.", name, strlen("net.")) == 0) { if (strcmp("net.change", name) == 0) { return 0; } @@ -307,7 +309,7 @@ int property_set(const char *name, const char *value) */ property_set("net.change", name); } else if (persistent_properties_loaded && - strncmp("persist.", name, sizeof("persist.") - 1) == 0) { + strncmp("persist.", name, strlen("persist.")) == 0) { /* * Don't write properties to disk until after we have read all default properties * to prevent them from being overwritten by default values. @@ -446,8 +448,7 @@ static void load_persistent_properties() if (dir) { while ((entry = readdir(dir)) != NULL) { - if (!strcmp(entry->d_name, ".") || !strcmp(entry->d_name, "..") || - strncmp("persist.", entry->d_name, sizeof("persist.") - 1)) + if (strncmp("persist.", entry->d_name, strlen("persist."))) continue; #if HAVE_DIRENT_D_TYPE if (entry->d_type != DT_REG) |