Loading init/builtins.c +3 −3 Original line number Diff line number Diff line Loading @@ -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); } } Loading Loading @@ -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; } Loading @@ -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; } Loading init/init.c +72 −7 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -192,6 +192,12 @@ 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(); Loading Loading @@ -248,9 +254,52 @@ void service_start(struct service *svc) setuid(svc->uid); } 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; char *tmp = strdup(dynamic_args); char *p = tmp; /* Copy the static arguments */ for (arg_idx = 0; arg_idx < svc->nargs; arg_idx++) { arg_ptrs[arg_idx] = svc->args[arg_idx]; } int done = 0; while(!done) { if (arg_idx == SVC_MAXARGS) break; /* Advance over any leading whitespace */ if (*p == ' ') { for (p; *p != ' '; p++); p++; } /* Locate next argument */ char *q = p; while(1) { if (*q == ' ') { *q = '\0'; break; } else if (*q == '\0') { done = 1; break; } q++; } arg_ptrs[arg_idx++] = p; q++; // Advance q to the next string p = q; } arg_ptrs[arg_idx] = '\0'; execve(svc->args[0], (char**) arg_ptrs, (char**) ENV); } _exit(127); } Loading Loading @@ -381,7 +430,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; } Loading @@ -407,13 +456,29 @@ 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); strcpy(tmp, 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) Loading Loading @@ -739,7 +804,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); } Loading init/init.h +3 −1 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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); Loading init/parser.c +2 −4 Original line number Diff line number Diff line Loading @@ -60,8 +60,6 @@ void DUMP(void) #endif } #define MAXARGS 64 #define T_EOF 0 #define T_TEXT 1 #define T_NEWLINE 2 Loading Loading @@ -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; Loading @@ -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; Loading Loading
init/builtins.c +3 −3 Original line number Diff line number Diff line Loading @@ -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); } } Loading Loading @@ -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; } Loading @@ -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; } Loading
init/init.c +72 −7 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -192,6 +192,12 @@ 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(); Loading Loading @@ -248,9 +254,52 @@ void service_start(struct service *svc) setuid(svc->uid); } 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; char *tmp = strdup(dynamic_args); char *p = tmp; /* Copy the static arguments */ for (arg_idx = 0; arg_idx < svc->nargs; arg_idx++) { arg_ptrs[arg_idx] = svc->args[arg_idx]; } int done = 0; while(!done) { if (arg_idx == SVC_MAXARGS) break; /* Advance over any leading whitespace */ if (*p == ' ') { for (p; *p != ' '; p++); p++; } /* Locate next argument */ char *q = p; while(1) { if (*q == ' ') { *q = '\0'; break; } else if (*q == '\0') { done = 1; break; } q++; } arg_ptrs[arg_idx++] = p; q++; // Advance q to the next string p = q; } arg_ptrs[arg_idx] = '\0'; execve(svc->args[0], (char**) arg_ptrs, (char**) ENV); } _exit(127); } Loading Loading @@ -381,7 +430,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; } Loading @@ -407,13 +456,29 @@ 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); strcpy(tmp, 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) Loading Loading @@ -739,7 +804,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); } Loading
init/init.h +3 −1 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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); Loading
init/parser.c +2 −4 Original line number Diff line number Diff line Loading @@ -60,8 +60,6 @@ void DUMP(void) #endif } #define MAXARGS 64 #define T_EOF 0 #define T_TEXT 1 #define T_NEWLINE 2 Loading Loading @@ -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; Loading @@ -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; Loading