chiark / gitweb /
add non-failing close() variant
[elogind.git] / socket.c
1 /*-*- Mode: C; c-basic-offset: 8 -*-*/
2
3 #include <sys/types.h>
4 #include <sys/stat.h>
5 #include <unistd.h>
6 #include <errno.h>
7 #include <fcntl.h>
8 #include <sys/poll.h>
9 #include <signal.h>
10
11 #include "unit.h"
12 #include "socket.h"
13 #include "log.h"
14
15 static const UnitActiveState state_translation_table[_SOCKET_STATE_MAX] = {
16         [SOCKET_DEAD] = UNIT_INACTIVE,
17         [SOCKET_START_PRE] = UNIT_ACTIVATING,
18         [SOCKET_START_POST] = UNIT_ACTIVATING,
19         [SOCKET_LISTENING] = UNIT_ACTIVE,
20         [SOCKET_RUNNING] = UNIT_ACTIVE,
21         [SOCKET_STOP_PRE] = UNIT_DEACTIVATING,
22         [SOCKET_STOP_PRE_SIGTERM] = UNIT_DEACTIVATING,
23         [SOCKET_STOP_PRE_SIGKILL] = UNIT_DEACTIVATING,
24         [SOCKET_STOP_POST] = UNIT_DEACTIVATING,
25         [SOCKET_STOP_POST_SIGTERM] = UNIT_DEACTIVATING,
26         [SOCKET_STOP_POST_SIGKILL] = UNIT_DEACTIVATING,
27         [SOCKET_MAINTAINANCE] = UNIT_INACTIVE,
28 };
29
30 static const char* const state_string_table[_SOCKET_STATE_MAX] = {
31         [SOCKET_DEAD] = "dead",
32         [SOCKET_START_PRE] = "start-pre",
33         [SOCKET_START_POST] = "start-post",
34         [SOCKET_LISTENING] = "listening",
35         [SOCKET_RUNNING] = "running",
36         [SOCKET_STOP_PRE] = "stop-pre",
37         [SOCKET_STOP_PRE_SIGTERM] = "stop-pre-sigterm",
38         [SOCKET_STOP_PRE_SIGKILL] = "stop-pre-sigkill",
39         [SOCKET_STOP_POST] = "stop-post",
40         [SOCKET_STOP_POST_SIGTERM] = "stop-post-sigterm",
41         [SOCKET_STOP_POST_SIGKILL] = "stop-post-sigkill",
42         [SOCKET_MAINTAINANCE] = "maintainance"
43 };
44
45 static void socket_done(Unit *u) {
46         Socket *s = SOCKET(u);
47         SocketPort *p;
48
49         assert(s);
50
51         while ((p = s->ports)) {
52                 LIST_REMOVE(SocketPort, port, s->ports, p);
53
54                 if (p->fd >= 0)
55                         close_nointr(p->fd);
56                 free(p->path);
57                 free(p);
58         }
59
60         exec_context_done(&s->exec_context);
61         exec_command_free_array(s->exec_command, _SOCKET_EXEC_MAX);
62         s->control_command = NULL;
63
64         if (s->control_pid > 0) {
65                 unit_unwatch_pid(u, s->control_pid);
66                 s->control_pid = 0;
67         }
68
69         s->service = NULL;
70
71         free(s->bind_to_device);
72
73         unit_unwatch_timer(u, &s->timer_watch);
74 }
75
76 static int socket_init(Unit *u) {
77         Socket *s = SOCKET(u);
78         char *t;
79         int r;
80
81         /* First, reset everything to the defaults, in case this is a
82          * reload */
83
84         s->state = 0;
85         s->timer_watch.type = WATCH_INVALID;
86         s->bind_ipv6_only = false;
87         s->backlog = SOMAXCONN;
88         s->timeout_usec = DEFAULT_TIMEOUT_USEC;
89         exec_context_init(&s->exec_context);
90
91         if ((r = unit_load_fragment_and_dropin(u)) < 0)
92                 goto fail;
93
94         if (!(t = unit_name_change_suffix(unit_id(u), ".service"))) {
95                 r = -ENOMEM;
96                 goto fail;
97         }
98
99         r = manager_load_unit(u->meta.manager, t, (Unit**) &s->service);
100         free(t);
101
102         if (r < 0)
103                 goto fail;
104
105         if ((r = unit_add_dependency(u, UNIT_BEFORE, UNIT(s->service))) < 0)
106                 goto fail;
107
108         return 0;
109
110 fail:
111         socket_done(u);
112         return r;
113 }
114
115 static const char* listen_lookup(int type) {
116
117         if (type == SOCK_STREAM)
118                 return "ListenStream";
119         else if (type == SOCK_DGRAM)
120                 return "ListenDatagram";
121         else if (type == SOCK_SEQPACKET)
122                 return "ListenSequentialPacket";
123
124         assert_not_reached("Unknown socket type");
125         return NULL;
126 }
127
128 static void socket_dump(Unit *u, FILE *f, const char *prefix) {
129
130         static const char* const command_table[_SOCKET_EXEC_MAX] = {
131                 [SOCKET_EXEC_START_PRE] = "StartPre",
132                 [SOCKET_EXEC_START_POST] = "StartPost",
133                 [SOCKET_EXEC_STOP_PRE] = "StopPre",
134                 [SOCKET_EXEC_STOP_POST] = "StopPost"
135         };
136
137         SocketExecCommand c;
138         Socket *s = SOCKET(u);
139         SocketPort *p;
140         char *prefix2;
141
142         assert(s);
143         assert(f);
144
145         prefix2 = strappend(prefix, "\t");
146         if (!prefix2)
147                 prefix2 = "";
148
149         fprintf(f,
150                 "%sSocket State: %s\n"
151                 "%sBindIPv6Only: %s\n"
152                 "%sBacklog: %u\n",
153                 prefix, state_string_table[s->state],
154                 prefix, yes_no(s->bind_ipv6_only),
155                 prefix, s->backlog);
156
157         if (s->bind_to_device)
158                 fprintf(f,
159                         "%sBindToDevice: %s\n",
160                         prefix, s->bind_to_device);
161
162         LIST_FOREACH(port, p, s->ports) {
163
164                 if (p->type == SOCKET_SOCKET) {
165                         const char *t;
166                         int r;
167                         char *k;
168
169                         if ((r = socket_address_print(&p->address, &k)) < 0)
170                                 t = strerror(-r);
171                         else
172                                 t = k;
173
174                         fprintf(f, "%s%s: %s\n", prefix, listen_lookup(p->address.type), k);
175                         free(k);
176                 } else
177                         fprintf(f, "%sListenFIFO: %s\n", prefix, p->path);
178         }
179
180         exec_context_dump(&s->exec_context, f, prefix);
181
182         for (c = 0; c < _SOCKET_EXEC_MAX; c++) {
183                 if (!s->exec_command[c])
184                         continue;
185
186                 fprintf(f, "%s→ %s:\n",
187                         prefix, command_table[c]);
188
189                 exec_command_dump_list(s->exec_command[c], f, prefix2);
190         }
191
192         free(prefix2);
193 }
194
195 static void socket_close_fds(Socket *s) {
196         SocketPort *p;
197
198         assert(s);
199
200         LIST_FOREACH(port, p, s->ports) {
201                 if (p->fd < 0)
202                         continue;
203
204                 unit_unwatch_fd(UNIT(s), &p->fd_watch);
205                 assert_se(close_nointr(p->fd) >= 0);
206
207                 p->fd = -1;
208         }
209 }
210
211 static int socket_open_fds(Socket *s) {
212         SocketPort *p;
213         int r;
214
215         assert(s);
216
217         LIST_FOREACH(port, p, s->ports) {
218
219                 if (p->fd >= 0)
220                         continue;
221
222                 if (p->type == SOCKET_SOCKET) {
223
224                         if ((r = socket_address_listen(&p->address, s->backlog, s->bind_ipv6_only, s->bind_to_device, &p->fd)) < 0)
225                                 goto rollback;
226
227                 } else {
228                         struct stat st;
229                         assert(p->type == SOCKET_FIFO);
230
231                         if (mkfifo(p->path, 0666 & ~s->exec_context.umask) < 0 && errno != EEXIST) {
232                                 r = -errno;
233                                 goto rollback;
234                         }
235
236                         if ((p->fd = open(p->path, O_RDWR|O_CLOEXEC|O_NOCTTY|O_NONBLOCK|O_NOFOLLOW)) < 0) {
237                                 r = -errno;
238                                 goto rollback;
239                         }
240
241                         if (fstat(p->fd, &st) < 0) {
242                                 r = -errno;
243                                 goto rollback;
244                         }
245
246                         /* FIXME verify user, access mode */
247
248                         if (!S_ISFIFO(st.st_mode)) {
249                                 r = -EEXIST;
250                                 goto rollback;
251                         }
252                 }
253         }
254
255         return 0;
256
257 rollback:
258         socket_close_fds(s);
259         return r;
260 }
261
262 static void socket_unwatch_fds(Socket *s) {
263         SocketPort *p;
264
265         assert(s);
266
267         LIST_FOREACH(port, p, s->ports) {
268                 if (p->fd < 0)
269                         continue;
270
271                 unit_unwatch_fd(UNIT(s), &p->fd_watch);
272         }
273 }
274
275 static int socket_watch_fds(Socket *s) {
276         SocketPort *p;
277         int r;
278
279         assert(s);
280
281         LIST_FOREACH(port, p, s->ports) {
282                 if (p->fd < 0)
283                         continue;
284
285                 if ((r = unit_watch_fd(UNIT(s), p->fd, POLLIN, &p->fd_watch)) < 0)
286                         goto fail;
287         }
288
289         return 0;
290
291 fail:
292         socket_unwatch_fds(s);
293         return r;
294 }
295
296 static void socket_set_state(Socket *s, SocketState state) {
297         SocketState old_state;
298         assert(s);
299
300         old_state = s->state;
301         s->state = state;
302
303         if (state != SOCKET_START_PRE &&
304             state != SOCKET_START_POST &&
305             state != SOCKET_STOP_PRE &&
306             state != SOCKET_STOP_PRE_SIGTERM &&
307             state != SOCKET_STOP_PRE_SIGKILL &&
308             state != SOCKET_STOP_POST &&
309             state != SOCKET_STOP_POST_SIGTERM &&
310             state != SOCKET_STOP_POST_SIGKILL)
311                 unit_unwatch_timer(UNIT(s), &s->timer_watch);
312
313         if (state != SOCKET_START_PRE &&
314             state != SOCKET_START_POST &&
315             state != SOCKET_STOP_PRE &&
316             state != SOCKET_STOP_PRE_SIGTERM &&
317             state != SOCKET_STOP_PRE_SIGKILL &&
318             state != SOCKET_STOP_POST &&
319             state != SOCKET_STOP_POST_SIGTERM &&
320             state != SOCKET_STOP_POST_SIGKILL)
321                 if (s->control_pid > 0) {
322                         unit_unwatch_pid(UNIT(s), s->control_pid);
323                         s->control_pid = 0;
324                 }
325
326         if (state != SOCKET_START_PRE &&
327             state != SOCKET_START_POST &&
328             state != SOCKET_STOP_PRE &&
329             state != SOCKET_STOP_POST)
330                 s->control_command = NULL;
331
332         if (state != SOCKET_START_POST &&
333             state != SOCKET_LISTENING &&
334             state != SOCKET_RUNNING &&
335             state != SOCKET_STOP_PRE &&
336             state != SOCKET_STOP_PRE_SIGTERM &&
337             state != SOCKET_STOP_PRE_SIGKILL)
338                 socket_close_fds(s);
339
340         if (state != SOCKET_LISTENING)
341                 socket_unwatch_fds(s);
342
343         log_debug("%s changing %s → %s", unit_id(UNIT(s)), state_string_table[old_state], state_string_table[state]);
344
345         unit_notify(UNIT(s), state_translation_table[old_state], state_translation_table[state]);
346 }
347
348 static int socket_spawn(Socket *s, ExecCommand *c, bool timeout, pid_t *_pid) {
349         pid_t pid;
350         int r;
351
352         assert(s);
353         assert(c);
354         assert(_pid);
355
356         if (timeout) {
357                 if ((r = unit_watch_timer(UNIT(s), s->timeout_usec, &s->timer_watch)) < 0)
358                         goto fail;
359         } else
360                 unit_unwatch_timer(UNIT(s), &s->timer_watch);
361
362         if ((r = exec_spawn(c, &s->exec_context, NULL, 0, &pid)) < 0)
363                 goto fail;
364
365         if ((r = unit_watch_pid(UNIT(s), pid)) < 0)
366                 /* FIXME: we need to do something here */
367                 goto fail;
368
369         *_pid = pid;
370
371         return 0;
372
373 fail:
374         if (timeout)
375                 unit_unwatch_timer(UNIT(s), &s->timer_watch);
376
377         return r;
378 }
379
380 static void socket_enter_dead(Socket *s, bool success) {
381         assert(s);
382
383         if (!success)
384                 s->failure = true;
385
386         socket_set_state(s, s->failure ? SOCKET_MAINTAINANCE : SOCKET_DEAD);
387 }
388
389 static void socket_enter_stop_post(Socket *s, bool success) {
390         int r;
391         assert(s);
392
393         if (!success)
394                 s->failure = true;
395
396         if ((s->control_command = s->exec_command[SOCKET_EXEC_STOP_POST])) {
397
398                 if ((r = socket_spawn(s, s->control_command, true, &s->control_pid)) < 0)
399                         goto fail;
400
401                 socket_set_state(s, SOCKET_STOP_POST);
402         } else
403                 socket_enter_dead(s, true);
404
405         return;
406
407 fail:
408         log_warning("%s failed to run stop-post executable: %s", unit_id(UNIT(s)), strerror(-r));
409         socket_enter_dead(s, false);
410 }
411
412 static void socket_enter_signal(Socket *s, SocketState state, bool success) {
413         int r;
414
415         assert(s);
416
417         if (!success)
418                 s->failure = true;
419
420         if (s->control_pid > 0) {
421                 int sig;
422
423                 sig = (state == SOCKET_STOP_PRE_SIGTERM || state == SOCKET_STOP_POST_SIGTERM) ? SIGTERM : SIGKILL;
424
425                 if (kill(s->control_pid, sig) < 0 && errno != ESRCH) {
426                         r = -errno;
427                         goto fail;
428                 }
429
430                 socket_set_state(s, state);
431         } else
432                 socket_enter_dead(s, true);
433
434         return;
435
436 fail:
437         log_warning("%s failed to kill processes: %s", unit_id(UNIT(s)), strerror(-r));
438
439         if (state == SOCKET_STOP_PRE_SIGTERM || state == SOCKET_STOP_PRE_SIGKILL)
440                 socket_enter_stop_post(s, false);
441         else
442                 socket_enter_dead(s, false);
443 }
444
445 static void socket_enter_stop_pre(Socket *s, bool success) {
446         int r;
447         assert(s);
448
449         if (!success)
450                 s->failure = true;
451
452         if ((s->control_command = s->exec_command[SOCKET_EXEC_STOP_PRE])) {
453
454                 if ((r = socket_spawn(s, s->control_command, true, &s->control_pid)) < 0)
455                         goto fail;
456
457                 socket_set_state(s, SOCKET_STOP_PRE);
458         } else
459                 socket_enter_stop_post(s, true);
460
461         return;
462
463 fail:
464         log_warning("%s failed to run stop-pre executable: %s", unit_id(UNIT(s)), strerror(-r));
465         socket_enter_stop_post(s, false);
466 }
467
468 static void socket_enter_listening(Socket *s) {
469         int r;
470         assert(s);
471
472         if ((r = socket_watch_fds(s)) < 0) {
473                 log_warning("%s failed to watch sockets: %s", unit_id(UNIT(s)), strerror(-r));
474                 goto fail;
475         }
476
477         socket_set_state(s, SOCKET_LISTENING);
478         return;
479
480 fail:
481         socket_enter_stop_pre(s, false);
482 }
483
484 static void socket_enter_start_post(Socket *s) {
485         int r;
486         assert(s);
487
488         if ((r = socket_open_fds(s)) < 0) {
489                 log_warning("%s failed to listen on sockets: %s", unit_id(UNIT(s)), strerror(-r));
490                 goto fail;
491         }
492
493         if ((s->control_command = s->exec_command[SOCKET_EXEC_START_POST])) {
494
495                 if ((r = socket_spawn(s, s->control_command, true, &s->control_pid)) < 0) {
496                         log_warning("%s failed to run start-post executable: %s", unit_id(UNIT(s)), strerror(-r));
497                         goto fail;
498                 }
499
500                 socket_set_state(s, SOCKET_START_POST);
501         } else
502                 socket_enter_listening(s);
503
504         return;
505
506 fail:
507         socket_enter_stop_pre(s, false);
508 }
509
510 static void socket_enter_start_pre(Socket *s) {
511         int r;
512         assert(s);
513
514         if ((s->control_command = s->exec_command[SOCKET_EXEC_START_PRE])) {
515
516                 if ((r = socket_spawn(s, s->control_command, true, &s->control_pid)) < 0)
517                         goto fail;
518
519                 socket_set_state(s, SOCKET_START_PRE);
520         } else
521                 socket_enter_start_post(s);
522
523         return;
524
525 fail:
526         log_warning("%s failed to run start-pre exectuable: %s", unit_id(UNIT(s)), strerror(-r));
527         socket_enter_dead(s, false);
528 }
529
530 static void socket_enter_running(Socket *s) {
531         int r;
532
533         assert(s);
534
535         if ((r = manager_add_job(UNIT(s)->meta.manager, JOB_START, UNIT(s->service), JOB_REPLACE, true, NULL)) < 0)
536                 goto fail;
537
538         socket_set_state(s, SOCKET_RUNNING);
539         return;
540
541 fail:
542         log_warning("%s failed to queue socket startup job: %s", unit_id(UNIT(s)), strerror(-r));
543         socket_enter_dead(s, false);
544 }
545
546 static void socket_run_next(Socket *s, bool success) {
547         int r;
548
549         assert(s);
550         assert(s->control_command);
551         assert(s->control_command->command_next);
552
553         if (!success)
554                 s->failure = true;
555
556         s->control_command = s->control_command->command_next;
557
558         if ((r = socket_spawn(s, s->control_command, true, &s->control_pid)) < 0)
559                 goto fail;
560
561         return;
562
563 fail:
564         if (s->state == SOCKET_STOP_PRE)
565                 socket_enter_stop_post(s, false);
566         else if (s->state == SOCKET_STOP_POST)
567                 socket_enter_dead(s, false);
568         else
569                 socket_enter_stop_pre(s, false);
570 }
571
572 static int socket_start(Unit *u) {
573         Socket *s = SOCKET(u);
574
575         assert(s);
576
577         /* We cannot fulfill this request right now, try again later
578          * please! */
579         if (s->state == SOCKET_STOP_PRE ||
580             s->state == SOCKET_STOP_PRE_SIGKILL ||
581             s->state == SOCKET_STOP_PRE_SIGTERM ||
582             s->state == SOCKET_STOP_POST ||
583             s->state == SOCKET_STOP_POST_SIGTERM ||
584             s->state == SOCKET_STOP_POST_SIGKILL)
585                 return -EAGAIN;
586
587         if (s->state == SOCKET_START_PRE ||
588             s->state == SOCKET_START_POST)
589                 return 0;
590
591         /* Cannot run this without the service being around */
592         if (s->service->meta.load_state != UNIT_LOADED)
593                 return -ENOENT;
594
595         assert(s->state == SOCKET_DEAD || s->state == SOCKET_MAINTAINANCE);
596
597         s->failure = false;
598         socket_enter_start_pre(s);
599         return 0;
600 }
601
602 static int socket_stop(Unit *u) {
603         Socket *s = SOCKET(u);
604
605         assert(s);
606
607         /* We cannot fulfill this request right now, try again later
608          * please! */
609         if (s->state == SOCKET_START_PRE ||
610             s->state == SOCKET_START_POST)
611                 return -EAGAIN;
612
613         assert(s->state == SOCKET_LISTENING || s->state == SOCKET_RUNNING);
614
615         socket_enter_stop_pre(s, true);
616         return 0;
617 }
618
619 static UnitActiveState socket_active_state(Unit *u) {
620         assert(u);
621
622         return state_translation_table[SOCKET(u)->state];
623 }
624
625 static void socket_fd_event(Unit *u, int fd, uint32_t events, Watch *w) {
626         Socket *s = SOCKET(u);
627
628         assert(s);
629
630         log_debug("Incoming traffic on %s", unit_id(u));
631
632         if (events != POLLIN)
633                 socket_enter_stop_pre(s, false);
634
635         socket_enter_running(s);
636 }
637
638 static void socket_sigchld_event(Unit *u, pid_t pid, int code, int status) {
639         Socket *s = SOCKET(u);
640         bool success;
641
642         assert(s);
643         assert(pid >= 0);
644
645         success = code == CLD_EXITED && status == 0;
646         s->failure = s->failure || !success;
647
648         assert(s->control_pid == pid);
649         assert(s->control_command);
650
651         exec_status_fill(&s->control_command->exec_status, pid, code, status);
652         s->control_pid = 0;
653
654         log_debug("%s control process exited, code=%s status=%i", unit_id(u), sigchld_code(code), status);
655
656         if (s->control_command->command_next &&
657             (success || (s->state == SOCKET_EXEC_STOP_PRE || s->state == SOCKET_EXEC_STOP_POST))) {
658                 log_debug("%s running next command for the state %s", unit_id(u), state_string_table[s->state]);
659                 socket_run_next(s, success);
660         } else {
661                 /* No further commands for this step, so let's figure
662                  * out what to do next */
663
664                 log_debug("%s got final SIGCHLD for state %s", unit_id(u), state_string_table[s->state]);
665
666                 switch (s->state) {
667
668                 case SOCKET_START_PRE:
669                         if (success)
670                                 socket_enter_start_post(s);
671                         else
672                                 socket_enter_stop_pre(s, false);
673                         break;
674
675                 case SOCKET_START_POST:
676                         if (success)
677                                 socket_enter_listening(s);
678                         else
679                                 socket_enter_stop_pre(s, false);
680                         break;
681
682                 case SOCKET_STOP_PRE:
683                 case SOCKET_STOP_PRE_SIGTERM:
684                 case SOCKET_STOP_PRE_SIGKILL:
685                         socket_enter_stop_post(s, success);
686                         break;
687
688                 case SOCKET_STOP_POST:
689                 case SOCKET_STOP_POST_SIGTERM:
690                 case SOCKET_STOP_POST_SIGKILL:
691                         socket_enter_dead(s, success);
692                         break;
693
694                 default:
695                         assert_not_reached("Uh, control process died at wrong time.");
696                 }
697         }
698 }
699
700 static void socket_timer_event(Unit *u, uint64_t elapsed, Watch *w) {
701         Socket *s = SOCKET(u);
702
703         assert(s);
704         assert(elapsed == 1);
705
706         assert(w == &s->timer_watch);
707
708         switch (s->state) {
709
710         case SOCKET_START_PRE:
711         case SOCKET_START_POST:
712                 log_warning("%s operation timed out. Stopping.", unit_id(u));
713                 socket_enter_stop_pre(s, false);
714                 break;
715
716         case SOCKET_STOP_PRE:
717                 log_warning("%s stopping timed out. Terminating.", unit_id(u));
718                 socket_enter_signal(s, SOCKET_STOP_PRE_SIGTERM, false);
719                 break;
720
721         case SOCKET_STOP_PRE_SIGTERM:
722                 log_warning("%s stopping timed out. Killing.", unit_id(u));
723                 socket_enter_signal(s, SOCKET_STOP_PRE_SIGKILL, false);
724                 break;
725
726         case SOCKET_STOP_PRE_SIGKILL:
727                 log_warning("%s still around after SIGKILL. Ignoring.", unit_id(u));
728                 socket_enter_stop_post(s, false);
729                 break;
730
731         case SOCKET_STOP_POST:
732                 log_warning("%s stopping timed out (2). Terminating.", unit_id(u));
733                 socket_enter_signal(s, SOCKET_STOP_POST_SIGTERM, false);
734                 break;
735
736         case SOCKET_STOP_POST_SIGTERM:
737                 log_warning("%s stopping timed out (2). Killing.", unit_id(u));
738                 socket_enter_signal(s, SOCKET_STOP_POST_SIGKILL, false);
739                 break;
740
741         case SOCKET_STOP_POST_SIGKILL:
742                 log_warning("%s still around after SIGKILL (2). Entering maintainance mode.", unit_id(u));
743                 socket_enter_dead(s, false);
744                 break;
745
746         default:
747                 assert_not_reached("Timeout at wrong time.");
748         }
749 }
750
751 int socket_collect_fds(Socket *s, int **fds, unsigned *n_fds) {
752         int *rfds;
753         unsigned rn_fds, k;
754         SocketPort *p;
755
756         assert(s);
757         assert(fds);
758         assert(n_fds);
759
760         /* Called from the service code for requesting our fds */
761
762         rn_fds = 0;
763         LIST_FOREACH(port, p, s->ports)
764                 if (p->fd >= 0)
765                         rn_fds++;
766
767         if (!(rfds = new(int, rn_fds)) < 0)
768                 return -ENOMEM;
769
770         k = 0;
771         LIST_FOREACH(port, p, s->ports)
772                 if (p->fd >= 0)
773                         rfds[k++] = p->fd;
774
775         assert(k == rn_fds);
776
777         *fds = rfds;
778         *n_fds = rn_fds;
779
780         return 0;
781 }
782
783 void socket_notify_service_dead(Socket *s) {
784         assert(s);
785
786         /* The service is dead. Dang. */
787
788         if (s->state == SOCKET_RUNNING) {
789                 log_debug("%s got notified about service death.", unit_id(UNIT(s)));
790                 socket_enter_listening(s);
791         }
792 }
793
794 const UnitVTable socket_vtable = {
795         .suffix = ".socket",
796
797         .init = socket_init,
798         .done = socket_done,
799
800         .dump = socket_dump,
801
802         .start = socket_start,
803         .stop = socket_stop,
804
805         .active_state = socket_active_state,
806
807         .fd_event = socket_fd_event,
808         .sigchld_event = socket_sigchld_event,
809         .timer_event = socket_timer_event
810 };