diff options
Diffstat (limited to 'src/pies.c')
-rw-r--r-- | src/pies.c | 417 |
1 files changed, 294 insertions, 123 deletions
@@ -1,5 +1,5 @@ /* This file is part of GNU Pies. - Copyright (C) 2008-2020 Sergey Poznyakoff + Copyright (C) 2008-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 @@ -23,8 +23,6 @@ int preprocess_only; /* Preprocess config, do nothing more */ int lint_mode; /* Test configuration syntax and exit */ int log_to_stderr_only; /* Use only stderr for logging */ -int log_facility = LOG_USER; -char *log_tag; struct pies_privs pies_privs; int foreground; int init_process; @@ -38,7 +36,8 @@ enum pies_command COM_STOP, COM_DUMP_DEPMAP, COM_TRACE_PREREQ, - COM_TRACE_DEPEND + COM_TRACE_DEPEND, + COM_LIST_SHUTDOWN_SEQUENCE }; enum pies_command command; @@ -62,6 +61,8 @@ char *default_control_url[2] = { DEFAULT_PIES_CONTROL_URL, DEFAULT_INIT_CONTROL_URL }; + +static envop_t *pies_envop; struct config_syntax { @@ -323,15 +324,15 @@ static struct tokendef sig_tokendef[] = { void action_free (struct action *act) { - if (!act) - return; - if (act->nstat > 0) - free (act->status); - free (act->addr); - free (act->message); - free (act->command); + if (act) + { + grecs_list_free (act->cond_list); + free (act->addr); + free (act->message); + free (act->command); - free (act); + free (act); + } } static void @@ -340,6 +341,35 @@ free_entry_action (void *act) action_free (act); } +int +strtosignum (char const *arg) +{ + size_t len; + int n; + + if (arg == NULL) + return 0; + + len = strlen (arg); + if (len > 3 && memcmp (arg, "SIG", 3) == 0) + { + if (arg[4] == '+') + { + char *p; + unsigned long un; + + errno = 0; + un = strtoul (arg + 4, &p, 0); + if (un == 0 || *p || errno || un > INT_MAX) + return 0; + n = un; + } + else if (strtotok_ci (sig_tokendef, arg, &n)) + return 0; + } + return n; +} + static struct action * create_action (struct component *comp, grecs_locus_t *locus, @@ -347,22 +377,38 @@ create_action (struct component *comp, const char *(*getarg) (grecs_value_t *, int, grecs_locus_t *)) { int i; - unsigned *retv; - int retc = 0; - int allflag = 0; + struct grecs_list *cond_list; struct action *act; - retv = grecs_calloc (argc, sizeof *retv); if (argc == 0 || (argc == 1 && strcmp (getarg (val, 0, locus), "*") == 0)) - allflag = 1; + cond_list = NULL; else { + cond_list = grecs_list_create (); + cond_list->free_entry = listel_dispose; + for (i = 0; i < argc; i++) { - unsigned n; + struct status_cond *sc; + int n; + int neg = 0; const char *arg = getarg (val, i, locus); size_t len = strlen (arg); + if (*arg == '!') + { + neg = 1; + arg++; + if (*arg == 0) + { + i++; + if (i == argc) + break; + arg = getarg (val, i, locus); + len = strlen (arg); + } + } + if (isdigit (arg[0])) { char *p; @@ -375,22 +421,14 @@ create_action (struct component *comp, } else if (len > 3 && memcmp (arg, "SIG", 3) == 0) { - if (arg[4] == '+') + int signo; + if ((signo = strtosignum (arg)) == 0) { - char *p; - n = strtoul (arg + 4, &p, 0); - if (*p) - { - grecs_error (locus, 0, _("%s: not a number"), p); - continue; - } - } - else if (strtotok_ci (sig_tokendef, arg, (int*) &n)) - { - grecs_error (locus, 0, _("%s: not a signal code"), arg); + grecs_error (locus, 0, _("%s: bad signal specification"), + arg); continue; } - n |= STATUS_SIG_BIT; + n = STATUS_SIG_BIT | signo; } else if (strtotok_ci (ex_tokendef, arg, (int *) &n)) { @@ -398,23 +436,16 @@ create_action (struct component *comp, continue; } - /* Alles in ordnung */ - retv[retc++] = n; - } - } + sc = grecs_malloc (sizeof (sc[0])); + sc->status = n; + sc->neg = neg; - if (retc == 0 && !allflag) - { - free (retv); - return NULL; + grecs_list_append (cond_list, sc); + } } act = grecs_zalloc (sizeof *act); - if (!allflag) - { - act->nstat = retc; - act->status = retv; - } + act->cond_list = cond_list; if (!comp->act_list) { comp->act_list = grecs_list_create (); @@ -626,6 +657,7 @@ parse_legacy_env (char **argv, envop_t **envop) else { msize = len + vlen + 6; + mem = grecs_malloc (msize); snprintf (mem, msize, "${%s:-}%s", name, value); } value = mem; @@ -648,6 +680,7 @@ parse_legacy_env (char **argv, envop_t **envop) else { msize = len + vlen + 6; + mem = grecs_malloc (msize); snprintf (mem, msize, "%s${%s:-}", value, name); } value = mem; @@ -707,19 +740,19 @@ cb_env_section_parser (enum grecs_callback_command cmd, { grecs_locus_t *locus = &node->locus; grecs_value_t *value = node->v.value; - struct component *comp = varptr; + envop_t **envop_ptr = varptr; switch (cmd) { case grecs_callback_section_begin: - *(struct component **) cb_data = comp; + *(envop_t ***) cb_data = envop_ptr; break; case grecs_callback_section_end: break; case grecs_callback_set_value: - return _cb_env (&comp->envop, value, locus); + return _cb_env (envop_ptr, value, locus); } return 0; } @@ -731,7 +764,7 @@ _cb_env_clear (enum grecs_callback_command cmd, { grecs_locus_t *locus = &node->locus; grecs_value_t *value = node->v.value; - struct component *comp = varptr; + envop_t **envop_ptr = varptr; if (!GRECS_VALUE_EMPTY_P (value)) { @@ -739,7 +772,7 @@ _cb_env_clear (enum grecs_callback_command cmd, return 1; } - if (envop_entry_add (&comp->envop, envop_clear, NULL, NULL)) + if (envop_entry_add (envop_ptr, envop_clear, NULL, NULL)) grecs_error (locus, errno, "envop_entry_add"); return 0; @@ -752,7 +785,7 @@ _cb_env_keep (enum grecs_callback_command cmd, { grecs_locus_t *locus = &node->locus; grecs_value_t *value = node->v.value; - struct component *comp = varptr; + envop_t **envop_ptr = varptr; char *p; if (grecs_assert_node_value_type (cmd, node, GRECS_TYPE_STRING)) @@ -760,9 +793,9 @@ _cb_env_keep (enum grecs_callback_command cmd, p = strchr (value->v.string, '='); if (p) *p++ = 0; - if (envop_entry_add (&comp->envop, envop_clear, NULL, NULL)) + if (envop_entry_add (envop_ptr, envop_clear, NULL, NULL)) grecs_error (locus, errno, "envop_entry_add"); - if (envop_entry_add (&comp->envop, envop_keep, value->v.string, p)) + if (envop_entry_add (envop_ptr, envop_keep, value->v.string, p)) grecs_error (locus, errno, "envop_entry_add"); return 0; } @@ -774,7 +807,7 @@ _cb_env_set (enum grecs_callback_command cmd, { grecs_locus_t *locus = &node->locus; grecs_value_t *value = node->v.value; - struct component *comp = varptr; + envop_t **envop_ptr = varptr; char *p; if (grecs_assert_node_value_type (cmd, node, GRECS_TYPE_STRING)) @@ -782,7 +815,7 @@ _cb_env_set (enum grecs_callback_command cmd, p = strchr (value->v.string, '='); if (p) *p++ = 0; - if (envop_entry_add (&comp->envop, envop_set, value->v.string, p)) + if (envop_entry_add (envop_ptr, envop_set, value->v.string, p)) grecs_error (locus, errno, "envop_entry_add"); return 0; } @@ -794,11 +827,11 @@ _cb_env_eval (enum grecs_callback_command cmd, { grecs_locus_t *locus = &node->locus; grecs_value_t *value = node->v.value; - struct component *comp = varptr; + envop_t **envop_ptr = varptr; if (grecs_assert_node_value_type (cmd, node, GRECS_TYPE_STRING)) return 1; - if (envop_entry_add (&comp->envop, envop_set, NULL, value->v.string)) + if (envop_entry_add (envop_ptr, envop_set, NULL, value->v.string)) grecs_error (locus, errno, "envop_entry_add"); return 0; } @@ -810,7 +843,7 @@ _cb_env_unset (enum grecs_callback_command cmd, { grecs_locus_t *locus = &node->locus; grecs_value_t *value = node->v.value; - struct component *comp = varptr; + envop_t **envop_ptr = varptr; char *p; if (grecs_assert_node_value_type (cmd, node, GRECS_TYPE_STRING)) @@ -818,7 +851,7 @@ _cb_env_unset (enum grecs_callback_command cmd, p = strchr (value->v.string, '='); if (p) *p++ = 0; - if (envop_entry_add (&comp->envop, envop_unset, value->v.string, p)) + if (envop_entry_add (envop_ptr, envop_unset, value->v.string, p)) grecs_error (locus, errno, "envop_entry_add"); return 0; } @@ -878,7 +911,7 @@ string_to_syslog_priority (const char *key, int *pres) } int -string_to_syslog_facility (const char *key, int *pres) +string_to_syslog_facility (const char *key, int len, int *pres) { static struct tokendef tokdef_fac[] = { {"auth", LOG_AUTH}, @@ -908,7 +941,52 @@ string_to_syslog_facility (const char *key, int *pres) {NULL} }; - return strtotok_ci (tokdef_fac, key, pres); + return len == 0 + ? strtotok_ci (tokdef_fac, key, pres) + : strtotok_len_ci (tokdef_fac, key, len, pres); +} + +static int +string_to_syslog_fp (const char *str, grecs_locus_t *locus, int *pres) +{ + size_t len = strcspn (str, "."); + int f = pies_log_facility, p = LOG_ERR; + + if (string_to_syslog_facility (str, len, &f) == 0) + { + if (str[len]) + { + if (string_to_syslog_priority (str + len + 1, &p)) + { + grecs_error (locus, 0, "%s", _("unknown syslog priority")); + return 1; + } + } + } + else if (str[len]) + { + grecs_error (locus, 0, "%s", _("unknown syslog facility")); + return 1; + } + else if (string_to_syslog_priority (str, &p)) + { + grecs_error (locus, 0, "%s", _("unknown syslog priority")); + return 1; + } + *pres = f | p; + return 0; +} + +static int +cb_syslog_dev (enum grecs_callback_command cmd, + grecs_node_t *node, + void *varptr, void *cb_data) +{ + grecs_value_t *value = node->v.value; + + if (grecs_assert_node_value_type (cmd, node, GRECS_TYPE_STRING)) + return 1; + return pies_syslog_set_dev (value->v.string); } static int @@ -933,7 +1011,7 @@ cb_syslog_facility (enum grecs_callback_command cmd, else *(int *) varptr = n; } - else if (string_to_syslog_facility (str, varptr)) + else if (string_to_syslog_facility (str, 0, varptr)) grecs_error (locus, 0, _("unknown syslog facility %s"), str); return 0; } @@ -963,12 +1041,8 @@ _cb_redir (enum grecs_callback_command cmd, break; } rp->type = redir_syslog; - if (string_to_syslog_priority (value->v.string, &rp->v.prio)) - { - grecs_error (locus, 0, _("unknown syslog priority %s"), - value->v.string); - return 1; - } + if (string_to_syslog_fp (value->v.string, locus, &rp->v.prio)) + return 1; break; case GRECS_TYPE_ARRAY: @@ -997,14 +1071,9 @@ _cb_redir (enum grecs_callback_command cmd, break; case redir_syslog: - if (string_to_syslog_priority (value->v.arg.v[1]->v.string, - &rp->v.prio)) - { - grecs_error (locus, 0, - _("unknown syslog priority %s"), - value->v.arg.v[1]->v.string); - return 1; - } + if (string_to_syslog_fp (value->v.arg.v[1]->v.string, + locus, &rp->v.prio)) + return 1; break; case redir_file: @@ -1143,6 +1212,7 @@ str_to_cf (const char *string, int *flags) { "siggroup", CF_SIGGROUP }, { "nullinput", CF_NULLINPUT }, { "shell", CF_SHELL }, + { "expandenv", CF_EXPANDENV }, { NULL } }; @@ -1207,6 +1277,27 @@ _cb_flags (enum grecs_callback_command cmd, return 0; } +static int +_cb_signal (enum grecs_callback_command cmd, + grecs_node_t *node, + void *varptr, void *cb_data) +{ + grecs_locus_t *locus = &node->locus; + grecs_value_t *value = node->v.value; + int n; + + if (grecs_assert_node_value_type (cmd, node, GRECS_TYPE_STRING)) + return 1; + if ((n = strtosignum (value->v.string)) == 0) + { + grecs_error (locus, 0, _("%s: bad signal specification"), + value->v.string); + return 1; + } + *(int*)varptr = n; + return 0; +} + struct grecs_keyword component_keywords[] = { {"mode", N_("mode"), @@ -1246,6 +1337,11 @@ struct grecs_keyword component_keywords[] = { N_("List of flags."), grecs_type_string, GRECS_LIST, NULL, offsetof (struct component, flags), _cb_flags }, + {"sigterm", + N_("SIGNAL"), + N_("Termination signal."), + grecs_type_string, GRECS_DFLT, NULL, offsetof (struct component, sigterm), + _cb_signal }, #if PIES_SYSVINIT_ENABLED {"runlevels", N_("chars"), @@ -1344,13 +1440,6 @@ struct grecs_keyword component_keywords[] = { NULL, offsetof (struct component, rmfile), NULL, }, - {"facility", - N_("arg"), - N_("Override default syslog facility for this component."), - grecs_type_string, GRECS_DFLT, - NULL, offsetof (struct component, facility), - cb_syslog_facility, - }, {"stdout", /* TRANSLATORS: file and syslog are keywords. Do not translate them. */ N_("type: {file | syslog}> <channel: string"), @@ -1408,7 +1497,7 @@ struct grecs_keyword component_keywords[] = { NULL, N_("Modify program environment."), grecs_type_section, GRECS_DFLT, - NULL, 0, + NULL, offsetof (struct component, envop), cb_env_section_parser, NULL, cb_env_keywords }, {"env", @@ -1416,7 +1505,7 @@ struct grecs_keyword component_keywords[] = { N_("Modify program environment (legacy syntax).\n" "Argument is a list of quoted assignments separated by white space."), grecs_type_string, GRECS_DFLT, - NULL, 0, + NULL, offsetof (struct component, envop), cb_env_section_parser, NULL, NULL }, {"chdir", @@ -1536,16 +1625,25 @@ struct grecs_keyword control_keywords[] = { /* syslog */ static struct grecs_keyword syslog_kw[] = { + {"dev", + N_("name"), + N_("Syslog device: either absolute pathname of the socket file, " + "or an IPv4 address and optional port, separated with a colon"), + grecs_type_string, GRECS_CONST, + NULL, 0, cb_syslog_dev }, {"facility", N_("name"), N_("Set syslog facility. Arg is one of the following: user, daemon, " "auth, authpriv, mail, cron, local0 through local7 (case-insensitive), " "or a facility number."), grecs_type_string, GRECS_DFLT, - &log_facility, 0, cb_syslog_facility}, + &pies_log_facility, 0, cb_syslog_facility}, {"tag", N_("string"), N_("Tag syslog messages with this string"), grecs_type_string, GRECS_DFLT, - &log_tag}, + &pies_log_tag}, + {"fallback-file", N_("filename"), N_("Name of the fallback log file"), + grecs_type_string, GRECS_DFLT, + &pies_fallback_file}, #if 0 /* This is reserved for future use */ { @@ -1589,6 +1687,13 @@ struct grecs_keyword pies_keywords[] = { grecs_type_section, GRECS_DFLT, NULL, 0, component_section_parser, NULL, component_keywords}, + {"env", + NULL, + N_("Modify program environment."), + grecs_type_section, GRECS_DFLT, + &pies_envop, 0, + cb_env_section_parser, NULL, cb_env_keywords + }, {"control", NULL, N_("Define control socket"), @@ -1751,8 +1856,8 @@ struct grecs_keyword pies_keywords[] = { void config_init (void) { - grecs_include_path_setup (DEFAULT_VERSION_INCLUDE_DIR, - DEFAULT_INCLUDE_DIR, NULL); + grecs_preprocessor = DEFAULT_PREPROCESSOR; + grecs_log_to_stderr = log_to_stderr_only; pies_identity_mechanism_register (&system_identity_mechanism); #ifdef WITH_PAM @@ -1851,7 +1956,15 @@ pies_schedule_children (int op) children_op |= op; } -RETSIGTYPE +static int +children_op_toggle (int op) +{ + int result = children_op & op; + children_op &= ~op; + return result; +} + +void sig_handler (int sig) { if (SYSVINIT_ACTIVE && sysvinit_sigtrans (sig, &action)) @@ -1885,7 +1998,7 @@ sig_handler (int sig) } } -RETSIGTYPE +void sigchld_early (int sig) { while (waitpid (-1, NULL, WNOHANG) != -1) @@ -1893,7 +2006,7 @@ sigchld_early (int sig) } void -setsigvhan (RETSIGTYPE (*handler) (int signo), int *sigv, int sigc) +setsigvhan (void (*handler) (int signo), int *sigv, int sigc) { int i; struct sigaction act; @@ -1937,7 +2050,7 @@ add_extra_sigv (int *sigv, int sigc) } void -signal_setup (RETSIGTYPE (*sf) (int)) +signal_setup (void (*sf) (int)) { setsigvhan (sf, default_sigv, ARRAY_SIZE (default_sigv)); if (extra_sigc) @@ -2002,7 +2115,7 @@ pies_check_status (pid_t *ppid) { pid_t pid = pidfile_read (0); - if (pid <= 0) + if (pid <= 0 || pid == getpid ()) return pies_status_ctr; *ppid = pid; @@ -2263,21 +2376,49 @@ set_state_file_names (const char *base) qotdfile = mkfilename (statedir, base, ".qotd"); } -/* Return 1 if pies is run from docker and 0 otherwise. */ static int is_docker (void) { FILE *fp; - char *id = NULL; - int res; - + + // 0 1 + // 0123456789012345678 + static char alphabet[] = "0123456789docker:/\n"; + static unsigned char transition[][20] = { + // 0 1 2 3 4 5 6 7 8 9 d o c k e r : / \n + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,10,10,10,10,10,10, 1,10, 0, 10 }, + { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 0, 1 }, + { 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, 3, 0, 10 }, + { 10,10,10,10,10,10,10,10,10,10, 4,10,10,10,10,10,10,10, 0, 10 }, + { 10,10,10,10,10,10,10,10,10,10,10, 5,10,10,10,10,10,10, 0, 10 }, + { 10,10,10,10,10,10,10,10,10,10,10,10, 6,10,10,10,10,10, 0, 10 }, + { 10,10,10,10,10,10,10,10,10,10,10,10,10, 7,10,10,10,10, 0, 10 }, + { 10,10,10,10,10,10,10,10,10,10,10,10,10,10, 8,10,10,10, 0, 10 }, + { 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, 9,10,10, 0, 10 }, + { 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,11, 0, 10 }, + { 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, 0, 10 }, + }; + enum { state_init = 0, state_success = 11, state_eof = 12 }; + int state = state_init; + fp = fopen ("/proc/self/cgroup", "r"); if (!fp) return 0; - res = fscanf (fp, "%*d:%*[^:]:/docker/%ms\n", &id) == 1; + + while (state != state_success && state != state_eof) + { + int c = fgetc (fp); + if (c == EOF) + state = state_eof; + else + { + char *p = strchr (alphabet, c); + int a = p ? p - alphabet : sizeof (alphabet) - 1; + state = transition[state][a]; + } + } fclose (fp); - free (id); - return res; + return state == state_success; } /* @@ -2312,13 +2453,17 @@ no_init_option (int argc, char **argv) static void init_detect (int argc, char **argv) { - init_process = getpid () == 1; - if (init_process) + if (getpid () == 1) { int s[] = { SIGCHLD }; setsigvhan (sigchld_early, s, 1); - if (no_init_option (argc, argv) || is_docker ()) - init_process = 0; + + init_process = PIES_SYSVINIT_ENABLED; + if (init_process) + { + if (no_init_option (argc, argv) || is_docker ()) + init_process = 0; + } } } @@ -2332,7 +2477,6 @@ main (int argc, char **argv) extern char **environ; struct grecs_list_entry *ep; int diag_flags; - int i; set_program_name (argv[0]); #ifdef ENABLE_NLS @@ -2354,7 +2498,7 @@ main (int argc, char **argv) /* Set default logging */ if (SYSVINIT_ACTIVE) { - log_facility = LOG_DAEMON; + pies_log_facility = LOG_DAEMON; diag_flags = DIAG_TO_STDERR | DIAG_REOPEN_LOG; } else @@ -2383,7 +2527,7 @@ main (int argc, char **argv) instance++; } setenv ("PIES_INSTANCE", instance, 1); - log_tag = grecs_strdup (instance); + pies_log_tag = grecs_strdup (instance); set_conf_file_names (instance); @@ -2399,7 +2543,7 @@ main (int argc, char **argv) struct config_file *file = ep->data; if (file->syntax == &config_syntax_tab[CONF_PIES] - && grecs_preproc_run (file->name, grecs_preprocessor)) + && grecs_preprocess (file->name, 0)) exit (EX_CONFIG); } exit (0); @@ -2412,6 +2556,32 @@ main (int argc, char **argv) set_state_file_names (instance); set_mailer_argcv (); + if (pies_envop) + { + environ_t *env; + + if ((env = environ_create (environ)) == NULL) + { + logmsg (LOG_CRIT, "environ_create: %s", strerror (errno)); + exit (EX_OSERR); + } + if (envop_exec (pies_envop, env)) + { + logmsg (LOG_CRIT, "environ_exec: %s", strerror (errno)); + exit (EX_OSERR); + } + environ = environ_ptr (env); + + if (debug_level >= 4) + { + int i; + logmsg_printf (LOG_DEBUG, "environment: "); + for (i = 0; environ[i]; i++) + logmsg_printf (LOG_DEBUG, "%s ", environ[i]); + logmsg_printf (LOG_DEBUG, "\n"); + } + } + if (lint_mode) exit (0); @@ -2459,6 +2629,10 @@ main (int argc, char **argv) components_trace (argv, depmap_col); exit (0); + case COM_LIST_SHUTDOWN_SEQUENCE: + components_list_shutdown_sequence (); + exit (0); + default: pies_priv_setup (&pies_privs); if (pies_umask) @@ -2548,10 +2722,12 @@ main (int argc, char **argv) component_config_commit (); if (SYSVINIT_ACTIVE) sysvinit_runlevel_setup (PIES_COMP_DEFAULT); + if (children_op_toggle (PIES_CHLD_GC)) + progman_gc (); progman_create_sockets (); progman_start (); - pies_schedule_children (PIES_CHLD_WAKEUP); + //pies_schedule_children (PIES_CHLD_WAKEUP); action = ACTION_CONT; break; @@ -2588,15 +2764,16 @@ main (int argc, char **argv) } if (action == ACTION_CONT) { - if (children_op & PIES_CHLD_RESCHEDULE_ALARM) - progman_recompute_alarm (); - if (children_op & PIES_CHLD_GC) + if (children_op_toggle (PIES_CHLD_GC)) progman_gc (); - if (children_op & PIES_CHLD_CLEANUP) - progman_cleanup (0); - if (children_op & PIES_CHLD_WAKEUP) + if (children_op_toggle (PIES_CHLD_CLEANUP)) + progman_cleanup (CLEANUP_DEFAULT); + /* The order is important here: progman_wake_sleeping + can raise PIES_CHLD_RESCHEDULE_ALARM */ + if (children_op_toggle (PIES_CHLD_WAKEUP)) progman_wake_sleeping (1); - children_op = PIES_CHLD_NONE; + if (children_op_toggle (PIES_CHLD_RESCHEDULE_ALARM)) + progman_recompute_alarm (); } } while (SYSVINIT_ACTIVE || action == ACTION_CONT); @@ -2606,14 +2783,8 @@ main (int argc, char **argv) if (action == ACTION_RESTART) { - int minfd = DIAG_OUTPUT (DIAG_TO_STDERR) ? 2 : 0; - int i; - - for (i = getmaxfd (); i > minfd; i--) - close (i); - + pies_close_fds (3); signal_setup (SIG_DFL); - execv (pies_master_argv[0], pies_master_argv); } |