diff options
Diffstat (limited to 'src/comp.c')
-rw-r--r-- | src/comp.c | 106 |
1 files changed, 102 insertions, 4 deletions
@@ -1,5 +1,5 @@ /* This file is part of GNU Pies. - Copyright (C) 2016-2021 Sergey Poznyakoff + Copyright (C) 2016-2023 Sergey Poznyakoff GNU Pies is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -157,6 +157,7 @@ component_create (const char *name) comp->redir[RETR_OUT].type = comp->redir[RETR_ERR].type = redir_null; comp->tag = grecs_strdup (name); comp->socket_type = SOCK_STREAM; + comp->sigterm = SIGTERM; component_append (comp); } return comp; @@ -218,8 +219,10 @@ argvcmp (char **a, char **b) { size_t i; - if (!a != !b) - return 1; + if (!a) + return !!b; + else if (!b) + return !!a; for (i = 0; a[i]; i++) if (!b[i] || strcmp (b[i], a[i])) @@ -271,8 +274,10 @@ component_match (struct component *comp, struct component *ref) EQ (mode); FN (tag, safe_strcmp); FN (program, safe_strcmp); + FN (command, safe_strcmp); EQ (argc); FN (argv, argvcmp); + FN (envop, envop_cmp); FN (dir, safe_strcmp); FN (prereq, grecs_list_compare); FN (depend, grecs_list_compare); @@ -280,6 +285,7 @@ component_match (struct component *comp, struct component *ref) EQ (max_instances); FN (rmfile, safe_strcmp); FNP (privs, pies_privs_cmp); + EQ (umask); FN (limits, limits_cmp); FN (runlevels, safe_strcmp); EQ (max_rate); @@ -478,6 +484,25 @@ component_build_depmap (void) } } +/* + * Recursively increase shutdown sequence numbers for all prerequisites + * of the given component. + */ +static void +compute_shutdown_sequence (struct component *comp) +{ + pies_depmap_pos_t pos; + struct component *dep; + for (dep = component_depmap_first (depmap_col, comp->arridx, &pos); + dep; + dep = component_depmap_next (pos)) + { + dep->shutdown_seqno++; + compute_shutdown_sequence (dep); + } + depmap_end (pos); +} + void component_config_commit (void) { @@ -527,10 +552,83 @@ component_config_commit (void) /* Build dependency map */ component_build_depmap (); - /* Register new progs */ + /* Register new progs and assign shutdown sequence numbers */ for (comp = comp_list[cur].head; comp; comp = comp->next) + { if (!comp->prog) register_prog (comp); + compute_shutdown_sequence (comp); + } +} + +static int +shutdown_seqno_comp (void const *a, void const *b) +{ + struct component const *ca = *(struct component const **) a; + struct component const *cb = *(struct component const **) b; + if (ca->shutdown_seqno < cb->shutdown_seqno) + return -1; + else if (ca->shutdown_seqno > cb->shutdown_seqno) + return 1; + return 0; +} + +/* + * Returns a list of components in shutdown sequence order. + */ +struct component ** +component_shutdown_list (void) +{ + struct component **a; + size_t i; + + a = grecs_calloc (comp_count, sizeof (a[0])); + memcpy (a, comp_array, comp_count * sizeof (a[0])); + qsort (a, comp_count, sizeof (a[0]), shutdown_seqno_comp); + return a; +} + +/* + * Prints on stdout the list of components in shutdown sequence + * order. + */ +void +components_list_shutdown_sequence (void) +{ + struct component **a = component_shutdown_list (); + size_t i; + + for (i = 0; i < comp_count; i++) + { + printf ("%lu: %s\n", a[i]->shutdown_seqno, a[i]->tag); + } + free (a); +} + +/* + * Computes array if shutdown sequence numbers and stores it in RET. + * Returns number of elements in the computed array. + */ +size_t +components_shutdown_sequence_numbers (unsigned long **ret) +{ + struct component **a = component_shutdown_list (); + unsigned long *idx = grecs_calloc (comp_count, sizeof (idx[0])); + size_t i; + size_t j; + + for (i = j = 0; i < comp_count; i++) + { + unsigned long seqno = idx[i] = a[j]->shutdown_seqno; + while (a[j]->shutdown_seqno == seqno) + { + if (++j == comp_count) + goto end; + } + } + end: + *ret = idx; + return i + 1; } static int |