diff options
Diffstat (limited to 'init')
-rw-r--r-- | init/builtins.c | 6 | ||||
-rw-r--r-- | init/devices.c | 2 | ||||
-rw-r--r-- | init/init.c | 55 | ||||
-rw-r--r-- | init/init.h | 4 | ||||
-rw-r--r-- | init/parser.c | 6 |
5 files changed, 57 insertions, 16 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 8aea772..300faab 100644 --- a/init/devices.c +++ b/init/devices.c @@ -131,9 +131,9 @@ static struct perms_ devperms[] = { { "/dev/qmi0", 0640, AID_RADIO, AID_RADIO, 0 }, { "/dev/qmi1", 0640, AID_RADIO, AID_RADIO, 0 }, { "/dev/qmi2", 0640, AID_RADIO, AID_RADIO, 0 }, - /* CDMA radio interface MUX */ { "/dev/ts0710mux", 0640, AID_RADIO, AID_RADIO, 1 }, + { "/dev/tun", 0640, AID_VPN , AID_VPN, 0 }, { NULL, 0, 0, 0, 0 }, }; diff --git a/init/init.c b/init/init.c index 283608c..8c2a058 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'; + execve(svc->args[0], (char**) arg_ptrs, (char**) ENV); } _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) @@ -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 b93eb50..f306b7b 100644 --- a/init/init.h +++ b/init/init.h @@ -116,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; @@ -160,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 30fa3de..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; |