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);
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]);
return 0;
}
+void socket_notify_service_dead(Socket *s) {
+ assert(s);
+
+ /* The service is dead. Dang. */
+
+ if (s->state == SOCKET_RUNNING) {
+ log_debug("%s got notified about service death.", unit_id(UNIT(s)));
+ socket_enter_listening(s);
+ }
+}
+
const UnitVTable socket_vtable = {
.suffix = ".socket",
/* Called from the service code when collecting fds */
int socket_collect_fds(Socket *s, int **fds, unsigned *n_fds);
+/* Called from the service when it shut down */
+void socket_notify_service_dead(Socket *s);
+
extern const UnitVTable socket_vtable;
#endif