aboutsummaryrefslogtreecommitdiff
path: root/src/pies.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/pies.c')
-rw-r--r--src/pies.c417
1 files changed, 294 insertions, 123 deletions
diff --git a/src/pies.c b/src/pies.c
index 0e84979..2aef512 100644
--- a/src/pies.c
+++ b/src/pies.c
@@ -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);
}

Return to:

Send suggestions and report system problems to the System administrator.