X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=blobdiff_plain;f=service.c;h=2c3c0b233be3203aee90f6190d7546254f9c0c92;hb=4a72ff34c62f18559e96b35d69c665e07290f228;hp=fce42045a9cbaca4775f910a498be6458d45b2e2;hpb=acbb02252a38214ecba3aa8a5c9b3669f9c9317e;p=elogind.git diff --git a/service.c b/service.c index fce42045a..2c3c0b233 100644 --- a/service.c +++ b/service.c @@ -198,6 +198,34 @@ static int service_load_pid_file(Service *s) { return 0; } +static int service_notify_sockets(Service *s) { + Iterator i; + char *t; + + assert(s); + + SET_FOREACH(t, UNIT(s)->meta.names, i) { + char *k; + Unit *p; + + /* Look for all socket objects that go by any of our + * units and collect their fds */ + + if (!(k = unit_name_change_suffix(t, ".socket"))) + return -ENOMEM; + + p = manager_get_unit(UNIT(s)->meta.manager, k); + free(k); + + if (!p) + continue; + + socket_notify_service_dead(SOCKET(p)); + } + + return 0; +} + static void service_set_state(Service *s, ServiceState state) { ServiceState old_state; assert(s); @@ -252,6 +280,17 @@ static void service_set_state(Service *s, ServiceState state) { state != SERVICE_STOP_POST) s->control_command = NULL; + if (state == SERVICE_DEAD || + state == SERVICE_STOP || + state == SERVICE_STOP_SIGTERM || + state == SERVICE_STOP_SIGKILL || + state == SERVICE_STOP_POST || + state == SERVICE_FINAL_SIGTERM || + state == SERVICE_FINAL_SIGKILL || + state == SERVICE_MAINTAINANCE || + state == SERVICE_AUTO_RESTART) + service_notify_sockets(s); + log_debug("%s changing %s → %s", unit_id(UNIT(s)), state_string_table[old_state], state_string_table[state]); unit_notify(UNIT(s), state_translation_table[old_state], state_translation_table[state]); @@ -285,6 +324,9 @@ static int service_collect_fds(Service *s, int **fds, unsigned *n_fds) { p = manager_get_unit(UNIT(s)->meta.manager, k); free(k); + if (!p) + continue; + if ((r = socket_collect_fds(SOCKET(p), &cfds, &cn_fds)) < 0) goto fail; @@ -736,7 +778,7 @@ static void service_sigchld_event(Unit *u, pid_t pid, int code, int status) { assert(s); assert(pid >= 0); - success = code == CLD_EXITED || status == 0; + success = code == CLD_EXITED && status == 0; s->failure = s->failure || !success; if (s->main_pid == pid) { @@ -803,6 +845,8 @@ static void service_sigchld_event(Unit *u, pid_t pid, int code, int status) { /* No further commands for this step, so let's * figure out what to do next */ + log_debug("%s got final SIGCHLD for state %s", unit_id(u), state_string_table[s->state]); + switch (s->state) { case SERVICE_START_PRE: