+ if (s->deserialized_state == s->state)
+ return 0;
+
+ if (IN_SET(s->deserialized_state,
+ SOCKET_START_PRE,
+ SOCKET_START_CHOWN,
+ SOCKET_START_POST,
+ SOCKET_STOP_PRE,
+ SOCKET_STOP_PRE_SIGTERM,
+ SOCKET_STOP_PRE_SIGKILL,
+ SOCKET_STOP_POST,
+ SOCKET_FINAL_SIGTERM,
+ SOCKET_FINAL_SIGKILL)) {
+
+ if (s->control_pid <= 0)
+ return -EBADMSG;
+
+ r = unit_watch_pid(UNIT(s), s->control_pid);
+ if (r < 0)
+ return r;
+
+ r = socket_arm_timer(s);
+ if (r < 0)
+ return r;
+ }
+
+ if (IN_SET(s->deserialized_state,
+ SOCKET_START_CHOWN,
+ SOCKET_START_POST,
+ SOCKET_LISTENING,
+ SOCKET_RUNNING,
+ SOCKET_STOP_PRE,
+ SOCKET_STOP_PRE_SIGTERM,
+ SOCKET_STOP_PRE_SIGKILL)) {
+ r = socket_open_fds(s);
+ if (r < 0)
+ return r;
+ }
+
+ if (s->deserialized_state == SOCKET_LISTENING) {
+ r = socket_watch_fds(s);
+ if (r < 0)
+ return r;
+ }
+
+ socket_set_state(s, s->deserialized_state);
+ return 0;
+}
+
+static int socket_spawn(Socket *s, ExecCommand *c, pid_t *_pid) {
+ _cleanup_free_ char **argv = NULL;
+ pid_t pid;
+ int r;
+
+ assert(s);
+ assert(c);
+ assert(_pid);
+
+ unit_realize_cgroup(UNIT(s));
+
+ r = unit_setup_exec_runtime(UNIT(s));
+ if (r < 0)
+ goto fail;
+
+ r = socket_arm_timer(s);
+ if (r < 0)
+ goto fail;
+
+ r = unit_full_printf_strv(UNIT(s), c->argv, &argv);
+ if (r < 0)
+ goto fail;
+
+ r = exec_spawn(c,
+ argv,
+ &s->exec_context,
+ NULL, 0,
+ UNIT(s)->manager->environment,
+ true,
+ true,
+ true,
+ UNIT(s)->manager->confirm_spawn,
+ UNIT(s)->manager->cgroup_supported,
+ UNIT(s)->cgroup_path,
+ manager_get_runtime_prefix(UNIT(s)->manager),
+ UNIT(s)->id,
+ 0,
+ NULL,
+ s->exec_runtime,
+ &pid);
+ if (r < 0)
+ goto fail;
+
+ r = unit_watch_pid(UNIT(s), pid);
+ if (r < 0)
+ /* FIXME: we need to do something here */
+ goto fail;
+
+ *_pid = pid;
+ return 0;
+
+fail:
+ s->timer_event_source = sd_event_source_unref(s->timer_event_source);
+ return r;
+}
+
+static int socket_chown(Socket *s, pid_t *_pid) {
+ pid_t pid;
+ int r;
+
+ r = socket_arm_timer(s);
+ if (r < 0)
+ goto fail;
+
+ /* We have to resolve the user names out-of-process, hence
+ * let's fork here. It's messy, but well, what can we do? */
+
+ pid = fork();
+ if (pid < 0)
+ return -errno;