summaryrefslogtreecommitdiffabout
Side-by-side diff
Diffstat (more/less context) (ignore whitespace changes)
-rw-r--r--src/comp.c87
-rw-r--r--src/pies.c115
-rw-r--r--src/pies.h38
-rw-r--r--src/progman.c291
-rw-r--r--src/socket.c54
-rw-r--r--tests/Makefile.am9
-rw-r--r--tests/atlocal.in2
-rwxr-xr-xtests/aux/mailer (renamed from tests/mailer)0
-rwxr-xr-xtests/aux/respawn (renamed from tests/respawn)0
-rwxr-xr-xtests/aux/retcode (renamed from tests/retcode)0
-rwxr-xr-xtests/aux/startup7
-rw-r--r--tests/redirect.at2
-rw-r--r--tests/respawn.at2
-rw-r--r--tests/ret-exec.at4
-rw-r--r--tests/ret-notify.at6
-rw-r--r--tests/startup.at84
-rw-r--r--tests/testsuite.at1
17 files changed, 442 insertions, 260 deletions
diff --git a/src/comp.c b/src/comp.c
index c3e998a..2346306 100644
--- a/src/comp.c
+++ b/src/comp.c
@@ -26,2 +26,7 @@ struct complist
+/* 0 on the first load, and 1 on all subsequent reloads. Tells the
+ component_config_commit whether we're starting from scratch or just
+ updating an already loaded configuration */
+static int loaded;
+
static struct complist comp_list[2];
@@ -34,3 +39,3 @@ static pies_depmap_t depmap;
-static int
+static inline int
next_index (void)
@@ -40,3 +45,3 @@ next_index (void)
-static int
+static inline int
prev_index (void)
@@ -87,2 +92,18 @@ component_append (struct component *comp)
void
+comp_array_remove (size_t i)
+{
+ struct component *comp = comp_array[i];
+
+ depmap_remove (depmap, i);
+ while (i < comp_count -1)
+ {
+ comp_array[i] = comp_array[i+1];
+ comp_array[i]->arridx = i;
+ i++;
+ }
+ component_free (comp);
+ comp_count--;
+}
+
+void
component_unlink (struct component *comp)
@@ -203,3 +224,8 @@ component_ref_decr (struct component *comp)
if (--comp->ref_count == 0)
- component_free (comp);
+ {
+ if (component_is_active (comp))
+ comp_array_remove (comp->arridx);
+ else
+ component_free (comp);
+ }
}
@@ -427,13 +453,2 @@ report_cyclic_dependency (pies_depmap_t dp, size_t idx)
void
-comp_array_remove (size_t i)
-{
- struct component *comp = comp_array[i];
- if (i < comp_count - 1)
- memmove (&comp_array[i], &comp_array[i+1],
- (comp_count - i - 1) * sizeof comp_array[0]);
- component_free (comp);
- comp_count--;
-}
-
-void
component_build_depmap (void)
@@ -462,3 +477,2 @@ component_build_depmap (void)
comp_array_remove (i);
- depmap_remove (depmap, i);
continue;
@@ -499,6 +513,3 @@ component_build_depmap (void)
if (comp_array[i]->flags & CF_REMOVE)
- {
- comp_array_remove (i);
- depmap_remove (depmap, i);
- }
+ comp_array_remove (i);
else
@@ -530,18 +541,32 @@ component_config_commit (void)
- /* Rearrange components, registering prog entries for the new ones */
- for (comp = list->head, i = 0; comp; comp = comp->next, i++)
+ /* Rearrange components, registering entries for the new ones */
+ for (comp = list->head, i = 0; comp; )
{
- match = complist_find_match (prev, comp);
- if (match)
+ struct component *next = comp->next;
+ if (loaded && comp->mode == pies_comp_startup)
{
- component_merge (match, comp);
- component_unlink (match);
- match->listidx = cur;
- component_link (match, comp->prev);
+ /* Ignore startup components */
+ component_unlink (comp);
component_free (comp);
- comp = match;
}
- comp_array[i] = comp;
- comp->arridx = i;
+ else
+ {
+ match = complist_find_match (prev, comp);
+ if (match)
+ {
+ component_merge (match, comp);
+ component_unlink (match);
+ match->listidx = cur;
+ component_link (match, comp->prev);
+ component_free (comp);
+ comp = match;
+ }
+ comp_array[i] = comp;
+ comp->arridx = i;
+ i++;
+ }
+ comp = next;
}
+ /* Adjust comp_count */
+ comp_count = i;
@@ -562,2 +587,4 @@ component_config_commit (void)
register_prog (comp);
+
+ loaded = 1;
}
diff --git a/src/pies.c b/src/pies.c
index 89c0b7e..98488a6 100644
--- a/src/pies.c
+++ b/src/pies.c
@@ -134,3 +134,3 @@ config_file_remove (const char *name)
struct grecs_list_entry *ep;
-
+
for (ep = config_list->head; ep; ep = ep->next)
@@ -158,3 +158,3 @@ config_file_list_serialize (struct json_value *ar)
struct grecs_list_entry *ep;
-
+
for (ep = config_list->head; ep; ep = ep->next)
@@ -329,3 +329,3 @@ action_free (struct action *act)
free (act->command);
-
+
free (act);
@@ -361,3 +361,3 @@ create_action (struct component *comp,
size_t len = strlen (arg);
-
+
if (isdigit (arg[0]))
@@ -396,3 +396,3 @@ create_action (struct component *comp,
}
-
+
/* Alles in ordnung */
@@ -401,3 +401,3 @@ create_action (struct component *comp,
}
-
+
if (retc == 0 && !allflag)
@@ -474,3 +474,3 @@ return_code_section_parser (enum grecs_callback_command cmd,
}
-
+
switch (value->type)
@@ -480,3 +480,3 @@ return_code_section_parser (enum grecs_callback_command cmd,
break;
-
+
case GRECS_TYPE_ARRAY:
@@ -485,3 +485,3 @@ return_code_section_parser (enum grecs_callback_command cmd,
break;
-
+
case GRECS_TYPE_LIST:
@@ -494,3 +494,3 @@ return_code_section_parser (enum grecs_callback_command cmd,
break;
-
+
case grecs_callback_section_end:
@@ -544,3 +544,3 @@ _cb_command (enum grecs_callback_command cmd,
break;
-
+
case GRECS_TYPE_ARRAY:
@@ -704,3 +704,3 @@ _cb_redir (enum grecs_callback_command cmd,
int res;
-
+
switch (value->type)
@@ -721,3 +721,3 @@ _cb_redir (enum grecs_callback_command cmd,
break;
-
+
case GRECS_TYPE_ARRAY:
@@ -741,3 +741,3 @@ _cb_redir (enum grecs_callback_command cmd,
return 0;
-
+
switch (res)
@@ -746,3 +746,3 @@ _cb_redir (enum grecs_callback_command cmd,
break;
-
+
case redir_syslog:
@@ -757,3 +757,3 @@ _cb_redir (enum grecs_callback_command cmd,
break;
-
+
case redir_file:
@@ -766,3 +766,3 @@ _cb_redir (enum grecs_callback_command cmd,
break;
-
+
default:
@@ -770,3 +770,3 @@ _cb_redir (enum grecs_callback_command cmd,
}
-
+
return 0;
@@ -775,4 +775,4 @@ _cb_redir (enum grecs_callback_command cmd,
static struct tokendef socktype_xtab[] = {
- { "stream", SOCK_STREAM },
- { "dgram", SOCK_DGRAM },
+ { "stream", SOCK_STREAM },
+ { "dgram", SOCK_DGRAM },
{ "seqpacket", SOCK_SEQPACKET },
@@ -822,2 +822,4 @@ static struct tokendef modetab[] = {
{"pass", pies_comp_pass_fd},
+ {"startup", pies_comp_startup},
+ {"shutdown", pies_comp_shutdown},
{"boot", pies_comp_boot},
@@ -827,3 +829,3 @@ static struct tokendef modetab[] = {
{"powerokwait", pies_comp_powerokwait},
- {"ctrlaltdel", pies_comp_ctrlaltdel},
+ {"ctrlaltdel", pies_comp_ctrlaltdel},
{"ondemand", pies_comp_ondemand},
@@ -922,3 +924,3 @@ _cb_flags (enum grecs_callback_command cmd,
break;
-
+
case GRECS_TYPE_LIST:
@@ -926,3 +928,3 @@ _cb_flags (enum grecs_callback_command cmd,
struct grecs_list_entry *ep;
-
+
for (ep = value->v.list->head; ep; ep = ep->next)
@@ -941,3 +943,3 @@ _cb_flags (enum grecs_callback_command cmd,
break;
-
+
case GRECS_TYPE_ARRAY:
@@ -1230,3 +1232,3 @@ find_component_keyword (const char *ident)
struct grecs_keyword *kwp;
-
+
for (kwp = component_keywords; kwp->ident; kwp++)
@@ -1258,3 +1260,3 @@ component_section_parser (enum grecs_callback_command cmd,
break;
-
+
case grecs_callback_set_value:
@@ -1536,3 +1538,3 @@ pies_config_parse (char const *name)
return 1;
-
+
for (node = tree; node; node = node->next)
@@ -1552,3 +1554,3 @@ pies_config_parse (char const *name)
return 1;
-
+
return 0;
@@ -1575,3 +1577,3 @@ pies_read_config (void)
component_config_begin ();
-
+
for (ep = config_list->head; ep; ep = ep->next)
@@ -1585,6 +1587,6 @@ pies_read_config (void)
err = 0;
-
+
if (err)
component_config_rollback ();
-
+
return err;
@@ -1658,3 +1660,3 @@ setsigvhan (RETSIGTYPE (*handler) (int signo), int *sigv, int sigc)
struct sigaction act;
-
+
act.sa_flags = 0;
@@ -1781,3 +1783,3 @@ request_restart_components (size_t cc, char **cv)
size_t i, j;
-
+
argv = grecs_calloc (5 + 3 * cc - 1, sizeof (*argv));
@@ -1805,3 +1807,3 @@ list_components (void)
char *argv[5];
-
+
argv[0] = "piesctl";
@@ -1944,3 +1946,3 @@ set_mailer_argcv (void)
struct wordsplit ws;
-
+
if (wordsplit (mailer_command_line, &ws, WRDSF_DEFFLAGS))
@@ -2035,3 +2037,3 @@ main (int argc, char **argv)
int i;
-
+
set_program_name (argv[0]);
@@ -2045,6 +2047,6 @@ main (int argc, char **argv)
grecs_print_diag_fun = pies_diag_printer;
-
+
pies_master_argc = argc;
pies_master_argv = argv;
-
+
set_quoting_style (NULL, shell_quoting_style);
@@ -2060,3 +2062,3 @@ main (int argc, char **argv)
}
-
+
/* Set default logging */
@@ -2069,5 +2071,5 @@ main (int argc, char **argv)
diag_flags = DIAG_TO_SYSLOG | (stderr_closed_p () ? 0 : DIAG_TO_STDERR);
-
+
diag_setup (diag_flags);
-
+
config_init ();
@@ -2075,3 +2077,3 @@ main (int argc, char **argv)
parse_options (&argc, &argv);
-
+
if (argc && !(command == COM_RESTART_COMPONENT
@@ -2083,3 +2085,3 @@ main (int argc, char **argv)
}
-
+
if (!instance)
@@ -2121,3 +2123,3 @@ main (int argc, char **argv)
set_mailer_argcv ();
-
+
if (lint_mode)
@@ -2127,3 +2129,3 @@ main (int argc, char **argv)
diag_setup (log_to_stderr_only ? DIAG_TO_STDERR : 0);
-
+
if (!control.url)
@@ -2139,3 +2141,3 @@ main (int argc, char **argv)
}
-
+
switch (command)
@@ -2147,3 +2149,3 @@ main (int argc, char **argv)
exit (request_restart_components (argc, argv));
-
+
case COM_RELOAD:
@@ -2164,7 +2166,7 @@ main (int argc, char **argv)
exit (0);
-
- case COM_TRACE_PREREQ:
+
+ case COM_TRACE_PREREQ:
components_trace (argv, depmap_col);
exit (0);
-
+
default:
@@ -2195,3 +2197,3 @@ main (int argc, char **argv)
break;
-
+
case pies_status_running:
@@ -2201,3 +2203,3 @@ main (int argc, char **argv)
}
-
+
if (!foreground)
@@ -2214,3 +2216,3 @@ main (int argc, char **argv)
logmsg (LOG_INFO, _("%s %s starting"), proginfo.package, proginfo.version);
-
+
if (!init_process)
@@ -2221,3 +2223,3 @@ main (int argc, char **argv)
}
-
+
if (pies_master_argv[0][0] != '/')
@@ -2230,2 +2232,3 @@ main (int argc, char **argv)
progman_create_sockets ();
+ program_init_startup ();
progman_start ();
@@ -2263,3 +2266,3 @@ main (int argc, char **argv)
break;
-
+
case ACTION_STOP:
@@ -2278,3 +2281,3 @@ main (int argc, char **argv)
break;
-
+
case ACTION_KBREQUEST:
diff --git a/src/pies.h b/src/pies.h
index a7f6567..bdc406b 100644
--- a/src/pies.h
+++ b/src/pies.h
@@ -106,3 +106,3 @@ struct action
char *message; /* Notification mail. */
- char *command; /* Execute this command */
+ char *command; /* Execute this command */
};
@@ -139,3 +139,10 @@ enum pies_comp_mode
pies_comp_pass_fd,
-
+
+ /* Components of this type runs once on program startup. Running other
+ components is delayed until the last startup component finishes. */
+ pies_comp_startup,
+
+ /* FIXME: Runs before program termination */
+ pies_comp_shutdown,
+
/*
@@ -146,3 +153,3 @@ enum pies_comp_mode
for its termination */
- pies_comp_wait = pies_mark_sysvinit,
+ pies_comp_wait = pies_mark_sysvinit,
/* Execute the component once, when the specified runlevel is entered */
@@ -164,3 +171,3 @@ enum pies_comp_mode
pressed the Ctrl+Alt+Del combination. */
- pies_comp_ctrlaltdel,
+ pies_comp_ctrlaltdel,
/* Execute the component when a specified ondemand runlevel is called */
@@ -186,12 +193,12 @@ enum pies_comp_mode
#define CF_PRECIOUS 0x002 /* The component is precious (should not
- be disabled) */
+ be disabled) */
#define CF_WAIT 0x004 /* Wait for the component instance to
- terminate. */
+ terminate. */
#define CF_TCPMUX 0x008 /* A plain TCPMUX service */
#define CF_TCPMUXPLUS 0x010 /* A TCPMUX-plus service, i.e. pies
- must emit a '+' response before starting
- it */
+ must emit a '+' response before starting
+ it */
#define CF_INTERNAL 0x020 /* An internal inetd service */
#define CF_SOCKENV 0x040 /* Component wants socket information in
- the environment */
+ the environment */
#define CF_RESOLVE 0x080 /* Resolve IP addresses */
@@ -212,5 +219,5 @@ struct component
size_t arridx; /* Index of this component. */
- size_t ref_count; /* Reference count. */
+ size_t ref_count; /* Reference count. */
struct prog *prog; /* Prog associated with this component. */
-
+
enum pies_comp_mode mode;
@@ -234,3 +241,3 @@ struct component
char *runlevels;
-
+
/* For inetd components */
@@ -255,5 +262,5 @@ struct component
char *max_ip_connections_message;
-
+
/* Redirectors: */
- int facility; /* Syslog facility. */
+ int facility; /* Syslog facility. */
struct redirector redir[2]; /* Repeaters for stdout and stderr */
@@ -336,2 +343,3 @@ int pies_reread_config (void);
void register_prog (struct component *comp);
+void program_init_startup (void);
int progman_waiting_p (void);
@@ -596,3 +604,3 @@ struct sysvinit_request
#define SYSV_ACCT_PROC_START 2
-#define SYSV_ACCT_PROC_STOP 3
+#define SYSV_ACCT_PROC_STOP 3
diff --git a/src/progman.c b/src/progman.c
index 1b09cd5..5bc4eb3 100644
--- a/src/progman.c
+++ b/src/progman.c
@@ -67,3 +67,3 @@ progman_lookup_component (const char *tag)
return NULL;
-}
+}
@@ -124,3 +124,3 @@ link_prog (struct prog *prog, struct prog *ref)
prog->next = ref->next;
-
+
if ((x = ref->next))
@@ -153,3 +153,3 @@ destroy_prog (struct prog **pp)
struct prog *p = *pp;
-
+
unlink_prog (p);
@@ -160,4 +160,4 @@ destroy_prog (struct prog **pp)
if (p->v.p.status == status_listener && p->v.p.socket != -1)
- deregister_socket (p->v.p.socket);
- /* FIXME: Remove also all dependent progs (esp. tcpmux) */
+ deregister_socket (p->v.p.socket);
+ /* FIXME: Remove also all dependent progs (esp. tcpmux) */
if (p->v.p.redir[RETR_OUT])
@@ -167,3 +167,3 @@ destroy_prog (struct prog **pp)
break;
-
+
case TYPE_REDIRECTOR:
@@ -184,3 +184,3 @@ destroy_prog (struct prog **pp)
break;
-
+
case TYPE_COMMAND:
@@ -258,3 +258,3 @@ find_prog_ref (struct component *comp)
}
-
+
if (comp->prog)
@@ -272,3 +272,3 @@ find_prog_ref (struct component *comp)
}
-
+
static struct prog *
@@ -277,3 +277,3 @@ register_prog0 (struct component *comp)
struct prog *newp;
-
+
newp = grecs_zalloc (sizeof (*newp));
@@ -293,3 +293,3 @@ register_prog0 (struct component *comp)
newp->active = 1;
-
+
if (comp->mode != pies_comp_exec)
@@ -319,2 +319,15 @@ register_command (char *tag, char *command, pid_t pid)
+static inline int
+progman_startup_phase (void)
+{
+ struct prog *prog;
+
+ for (prog = proghead; prog; prog = prog->next)
+ {
+ if (IS_COMPONENT (prog) && prog->v.p.comp->mode == pies_comp_startup)
+ return 1;
+ }
+ return 0;
+}
+
int
@@ -323,6 +336,8 @@ progman_waiting_p (void)
struct prog *prog;
-
+
for (prog = proghead; prog; prog = prog->next)
{
- if (IS_COMPONENT (prog) && prog->wait && prog->pid > 0)
+ if (IS_COMPONENT (prog)
+ && prog->pid > 0
+ && (prog->wait || prog->v.p.comp->mode == pies_comp_startup))
{
@@ -408,3 +423,3 @@ open_redirector (struct prog *master, int stream)
return redirect_to_file (master, stream);
-
+
case redir_syslog:
@@ -412,3 +427,3 @@ open_redirector (struct prog *master, int stream)
}
-
+
if (pipe (p))
@@ -418,3 +433,3 @@ open_redirector (struct prog *master, int stream)
}
-
+
switch (pid = fork ())
@@ -430,6 +445,6 @@ open_redirector (struct prog *master, int stream)
close_fds (&fdset);
-
+
diag_setup (0);
signal_setup (redir_exit);
-
+
close (p[1]);
@@ -443,3 +458,3 @@ open_redirector (struct prog *master, int stream)
_exit (0);
-
+
case -1:
@@ -468,3 +483,3 @@ conn_class_hasher (void *data, unsigned long n_buckets)
size_t len;
-
+
while ((ch = *tag++))
@@ -532,3 +547,3 @@ conn_class_lookup (const char *tag,
}
-
+
probe->count = 0;
@@ -727,3 +742,3 @@ env_concat (const char *name, size_t namelen, const char *a, const char *b)
size_t len;
-
+
if (a && b)
@@ -755,3 +770,3 @@ env_concat (const char *name, size_t namelen, const char *a, const char *b)
}
-
+
static void
@@ -762,3 +777,3 @@ environ_setup (char **hint)
size_t count, i, j, n;
-
+
if (!hint)
@@ -771,3 +786,3 @@ environ_setup (char **hint)
}
-
+
/* Count new environment size */
@@ -777,3 +792,3 @@ environ_setup (char **hint)
count++;
-
+
for (i = 0; hint[i]; i++)
@@ -783,6 +798,6 @@ environ_setup (char **hint)
new_env = grecs_calloc (count + 1, sizeof new_env[0]);
-
+
/* Populate the environment. */
n = 0;
-
+
if (old_env)
@@ -797,3 +812,3 @@ environ_setup (char **hint)
char *p;
-
+
if (hint[i][0] == '-')
@@ -808,3 +823,3 @@ environ_setup (char **hint)
j = n;
-
+
if ((p = strchr (hint[i], '=')))
@@ -813,3 +828,3 @@ environ_setup (char **hint)
continue; /* Ignore erroneous entry */
- if (p[-1] == '+')
+ if (p[-1] == '+')
new_env[j] = env_concat (hint[i], p - hint[i] - 1,
@@ -837,3 +852,3 @@ environ_setup (char **hint)
free (environ);
-
+
environ = new_env;
@@ -854,3 +869,3 @@ prog_sockenv (struct prog *prog)
const char *proto = NULL;
-
+
if (!(prog->v.p.comp->flags & CF_SOCKENV))
@@ -861,3 +876,3 @@ prog_sockenv (struct prog *prog)
add_env (ENV_SOCKTYPE, proto);
-
+
if (prog->v.p.comp->socket_url)
@@ -870,3 +885,3 @@ prog_sockenv (struct prog *prog)
add_env (ENV_PROTO, proto);
-
+
if (getsockname (prog->v.p.socket,
@@ -922,3 +937,3 @@ check_rate (struct prog *prog, unsigned testtime, size_t max_count)
time_t now;
-
+
time (&now);
@@ -932,3 +947,3 @@ check_rate (struct prog *prog, unsigned testtime, size_t max_count)
}
-
+
if (prog->v.p.failcount > max_count)
@@ -940,3 +955,3 @@ check_rate (struct prog *prog, unsigned testtime, size_t max_count)
}
-
+
return 0;
@@ -963,3 +978,3 @@ check_connection_rate (struct prog *prog)
size_t max_rate = prog->v.p.comp->max_rate
- ? prog->v.p.comp->max_rate : default_max_rate;
+ ? prog->v.p.comp->max_rate : default_max_rate;
if (max_rate && check_rate (prog, 60, max_rate))
@@ -1011,3 +1026,3 @@ prog_start_prologue (struct prog *prog)
}
-
+
environ_setup (prog->v.p.comp->env ?
@@ -1022,3 +1037,3 @@ prog_start_prologue (struct prog *prog)
umask (prog->v.p.comp->umask);
-
+
set_limits (prog_tag (prog),
@@ -1026,3 +1041,3 @@ prog_start_prologue (struct prog *prog)
prog->v.p.comp->limits : pies_limits);
-
+
if (debug_level >= 1)
@@ -1031,3 +1046,3 @@ prog_start_prologue (struct prog *prog)
struct component *comp = prog->v.p.comp;
-
+
logmsg_printf (LOG_DEBUG, "executing");
@@ -1049,3 +1064,3 @@ prog_execute (struct prog *prog)
}
-
+
execvp (prog->v.p.comp->program ?
@@ -1079,3 +1094,3 @@ prog_start (struct prog *prog)
fd_set fdset;
-
+
if (prog->pid > 0 || !IS_COMPONENT (prog))
@@ -1125,3 +1140,3 @@ prog_start (struct prog *prog)
break;
-
+
case pies_comp_accept:
@@ -1141,5 +1156,5 @@ prog_start (struct prog *prog)
}
-
+
debug (1, (_("starting %s"), prog_tag (prog)));
-
+
if (prog->v.p.comp->rmfile)
@@ -1160,3 +1175,3 @@ prog_start (struct prog *prog)
redir[RETR_ERR] = open_redirector (prog, RETR_ERR);
-
+
switch (pid = fork ())
@@ -1169,12 +1184,12 @@ prog_start (struct prog *prog)
switch (prog->v.p.comp->mode)
- {
- case pies_comp_accept:
- case pies_comp_inetd:
+ {
+ case pies_comp_accept:
+ case pies_comp_inetd:
prog_sockenv (prog);
- dup2 (prog->v.p.socket, 0);
- dup2 (prog->v.p.socket, 1);
- close (prog->v.p.socket);
+ dup2 (prog->v.p.socket, 0);
+ dup2 (prog->v.p.socket, 1);
+ close (prog->v.p.socket);
prog->v.p.socket = -1;
- break;
+ break;
@@ -1184,3 +1199,3 @@ prog_start (struct prog *prog)
int fd = console_open (O_RDWR|O_NOCTTY);
- if (fd < 0)
+ if (fd < 0)
{
@@ -1220,4 +1235,4 @@ prog_start (struct prog *prog)
}
- break;
- }
+ break;
+ }
@@ -1238,3 +1253,3 @@ prog_start (struct prog *prog)
}
-
+
/* Close unneeded descripitors */
@@ -1249,4 +1264,4 @@ prog_start (struct prog *prog)
prog_execute (prog);
-
-
+
+
case -1:
@@ -1293,3 +1308,3 @@ check_acl (pies_acl_t acl, struct sockaddr *s, socklen_t salen,
int rc;
-
+
if (!acl)
@@ -1300,3 +1315,3 @@ check_acl (pies_acl_t acl, struct sockaddr *s, socklen_t salen,
input.identity = identity;
-
+
rc = pies_acl_check (acl, &input, 1);
@@ -1317,3 +1332,3 @@ fd_report (int fd, const char *msg)
size_t len;
-
+
if (!msg)
@@ -1336,3 +1351,3 @@ fd_report (int fd, const char *msg)
}
-}
+}
@@ -1346,3 +1361,3 @@ _prog_accept (struct prog *p)
struct conn_class *pcclass;
-
+
fd = accept (p->v.p.socket, (struct sockaddr*) &addr, &addrlen);
@@ -1353,3 +1368,3 @@ _prog_accept (struct prog *p)
}
-
+
if (debug_level >= 1)
@@ -1396,3 +1411,3 @@ _prog_accept (struct prog *p)
}
-
+
if (check_connection_rate (p))
@@ -1449,3 +1464,3 @@ _prog_wait (struct prog *p)
}
-
+
int
@@ -1458,3 +1473,3 @@ progman_accept (int socket, void *data)
return _prog_accept (p);
-
+
return _prog_wait (p);
@@ -1528,2 +1543,21 @@ progman_recompute_alarm (void)
void
+program_init_startup (void)
+{
+ struct prog *prog;
+
+ for (prog = proghead; prog; prog = prog->next)
+ if (IS_COMPONENT (prog) && prog->v.p.comp->mode == pies_comp_startup)
+ {
+ debug (1, ("running startup components"));
+ break;
+ }
+
+ for (; prog; prog = prog->next)
+ if (IS_COMPONENT (prog) && prog->v.p.comp->mode == pies_comp_startup)
+ {
+ prog_start (prog);
+ }
+}
+
+void
progman_start (void)
@@ -1533,5 +1567,6 @@ progman_start (void)
if (progman_waiting_p ())
- /* Noting to do if there are processes left in the previous runlevel */
+ /* Noting to do if there are processes left in the previous runlevel
+ (in sysv-init mode) or startup components running. */
return;
-
+
debug (1, ("starting components"));
@@ -1567,4 +1602,4 @@ check_stopping (struct prog *prog, time_t now)
if (prog->pid == 0)
- logmsg (LOG_EMERG,
- _("INTERNAL ERROR: attempting to kill unexisting process %s"),
+ logmsg (LOG_EMERG,
+ _("INTERNAL ERROR: attempting to kill unexisting process %s"),
prog_tag (prog));
@@ -1627,3 +1662,3 @@ progman_wake_sleeping (int onalrm)
break;
-
+
case status_stopping:
@@ -1636,3 +1671,3 @@ progman_wake_sleeping (int onalrm)
break;
-
+
default:
@@ -1649,3 +1684,3 @@ prog_start_prerequisites (struct prog *prog)
int warned = 0;
-
+
if (!prog->active)
@@ -1657,3 +1692,3 @@ prog_start_prerequisites (struct prog *prog)
struct prog *p;
-
+
if (!comp->prog || comp->flags & CF_PRECIOUS)
@@ -1671,3 +1706,3 @@ prog_start_prerequisites (struct prog *prog)
}
-
+
p = comp->prog;
@@ -1677,6 +1712,6 @@ prog_start_prerequisites (struct prog *prog)
continue;
-
+
case status_stopped:
break;
-
+
case status_listener:
@@ -1702,3 +1737,3 @@ prog_start_prerequisites (struct prog *prog)
depmap_end (pos);
-
+
return ret;
@@ -1759,3 +1794,3 @@ prog_stop (struct prog *prog, int sig)
kill (prog->pid, sig);
-}
+}
@@ -1789,3 +1824,3 @@ print_status (const char *tag, pid_t pid, int status, int expect_term)
prio = LOG_ERR;
-
+
if (WIFEXITED (status))
@@ -1803,3 +1838,3 @@ print_status (const char *tag, pid_t pid, int status, int expect_term)
char const *coremsg = "";
-
+
if (expect_term && WTERMSIG (status) == SIGTERM)
@@ -1825,3 +1860,3 @@ print_status (const char *tag, pid_t pid, int status, int expect_term)
static void propagate_child_exit (pid_t) ATTRIBUTE_NORETURN;
-
+
static void
@@ -1857,3 +1892,3 @@ wordsplit_string (struct wordsplit const *ws)
size_t len = 0;
-
+
for (i = 0; i < count; i++)
@@ -1885,3 +1920,3 @@ send_msg (char *rcpts, const char *msg_text)
size_t size;
-
+
ws.ws_offs = mailer_argc;
@@ -1898,3 +1933,3 @@ send_msg (char *rcpts, const char *msg_text)
debug (1, (_("sending notification to %s"), rcpts));
-
+
/* Copy mailer arguments */
@@ -1913,3 +1948,3 @@ send_msg (char *rcpts, const char *msg_text)
size_t len;
-
+
while (*arg && c_isblank (*arg))
@@ -1936,6 +1971,6 @@ send_msg (char *rcpts, const char *msg_text)
ws.ws_wordv[k] = NULL;
-
+
/* Fork a child: */
child_pid = fork ();
-
+
if (child_pid < 0)
@@ -1957,3 +1992,3 @@ send_msg (char *rcpts, const char *msg_text)
}
-
+
/* Child process */
@@ -1969,3 +2004,3 @@ send_msg (char *rcpts, const char *msg_text)
}
-
+
grand_child_pid = fork ();
@@ -2032,3 +2067,3 @@ notify_get_tag (char **ret, void *data)
*ret = s;
- return WRDSE_OK;
+ return WRDSE_OK;
}
@@ -2041,3 +2076,3 @@ notify_get_termination (char **ret, void *data)
char *s;
-
+
if (WIFEXITED (clos->status))
@@ -2055,5 +2090,5 @@ notify_get_termination (char **ret, void *data)
*ret = s;
- return WRDSE_OK;
+ return WRDSE_OK;
}
-
+
static int
@@ -2064,3 +2099,3 @@ notify_get_retcode (char **ret, void *data)
size_t l = 0;
-
+
if (WIFEXITED (clos->status))
@@ -2074,5 +2109,5 @@ notify_get_retcode (char **ret, void *data)
*ret = s;
- return WRDSE_OK;
-}
-
+ return WRDSE_OK;
+}
+
struct notify_variable
@@ -2092,3 +2127,3 @@ static struct notify_variable notify_vartab[] = {
};
-
+
static int
@@ -2102,3 +2137,3 @@ notify_getvar (char **ret, const char *vptr, size_t vlen, void *data)
}
-
+
static void
@@ -2122,3 +2157,3 @@ notify (const char *tag, int status, struct action *act)
closure.act = act;
-
+
env[PROGRAM_NAME_IDX] = program_name;
@@ -2146,3 +2181,3 @@ status_matches_p (struct action *act, unsigned status)
int i;
-
+
if (act->nstat == 0)
@@ -2186,3 +2221,3 @@ run_command (struct action *act, struct prog *prog, unsigned retcode,
close_fds (NULL);
-
+
argv[0] = "/bin/sh";
@@ -2210,3 +2245,3 @@ react (struct prog *prog, int status, pid_t pid)
list = default_component.act_list;
-
+
if (WIFEXITED (status))
@@ -2235,3 +2270,3 @@ react (struct prog *prog, int status, pid_t pid)
struct action *act = ep->data;
-
+
if (status_matches_p (act, retcode))
@@ -2242,3 +2277,3 @@ react (struct prog *prog, int status, pid_t pid)
}
-
+
switch (act->act)
@@ -2249,3 +2284,3 @@ react (struct prog *prog, int status, pid_t pid)
break;
-
+
case action_disable:
@@ -2265,3 +2300,3 @@ react (struct prog *prog, int status, pid_t pid)
}
-
+
if (!list && prog->v.p.comp->mode != pies_comp_inetd)
@@ -2296,3 +2331,3 @@ progman_cleanup (int expect_term)
struct prog *listener = prog->v.p.listener;
-
+
listener->v.p.num_instances--;
@@ -2309,3 +2344,3 @@ progman_cleanup (int expect_term)
}
-
+
prog_stop_redirectors (prog);
@@ -2323,2 +2358,10 @@ progman_cleanup (int expect_term)
}
+ else if (prog->v.p.comp->mode == pies_comp_startup)
+ {
+ debug (1, (_("removing startup component %s, pid=%lu"),
+ prog_tag (prog), (unsigned long)pid));
+ destroy_prog (&prog);
+ if (!progman_startup_phase ())
+ pies_schedule_children (PIES_CHLD_WAKEUP);
+ }
else
@@ -2331,3 +2374,3 @@ progman_cleanup (int expect_term)
prog->v.p.status = status_finished;
-
+
if (prog->wait)
@@ -2353,3 +2396,3 @@ progman_cleanup (int expect_term)
}
-
+
break;
@@ -2373,3 +2416,3 @@ progman_cleanup (int expect_term)
}
-
+
if (!expect_term)
@@ -2391,3 +2434,3 @@ progman_stop_component (struct prog **progptr)
break;
-
+
case status_listener:
@@ -2415,3 +2458,3 @@ progman_stop_component (struct prog **progptr)
break;
-
+
case status_finished:
@@ -2443,3 +2486,3 @@ prog_activate_listener (struct prog *prog)
struct component *comp = prog->v.p.comp;
-
+
logmsg (LOG_INFO, _("activating listener %s"), prog_tag (prog));
@@ -2537,7 +2580,7 @@ progman_gc (void)
}
-
+
/* FIXME: Report remaining programs */
-
+
}
-
+
/* EOF */
diff --git a/src/socket.c b/src/socket.c
index aa01543..40c7aa7 100644
--- a/src/socket.c
+++ b/src/socket.c
@@ -25,9 +25,12 @@ switch_eids (uid_t *puid, gid_t *pgid, mode_t *pumask)
mode_t omask = umask (*pumask);
-
- if (setegid (*pgid))
- logmsg (LOG_ERR, _("cannot switch to EGID %lu: %s"),
- (unsigned long) *pgid, strerror (errno));
- if (seteuid (*puid))
- logmsg (LOG_ERR, _("cannot switch to EUID %lu: %s"),
- (unsigned long) *puid, strerror (errno));
+
+ if ((*puid && *puid != ouid) || (*pgid && *pgid != ogid))
+ {
+ if (setegid (*pgid))
+ logmsg (LOG_ERR, _("cannot switch to EGID %lu: %s"),
+ (unsigned long) *pgid, strerror (errno));
+ if (seteuid (*puid))
+ logmsg (LOG_ERR, _("cannot switch to EUID %lu: %s"),
+ (unsigned long) *puid, strerror (errno));
+ }
*puid = ouid;
@@ -53,3 +56,3 @@ create_socket (struct pies_url *url, int socket_type,
int switch_back;
-
+
if (strcmp (url->scheme, "unix") == 0
@@ -60,3 +63,3 @@ create_socket (struct pies_url *url, int socket_type,
const char *group = NULL;
-
+
user = url->user;
@@ -101,3 +104,3 @@ create_socket (struct pies_url *url, int socket_type,
}
-
+
if (user)
@@ -113,3 +116,3 @@ create_socket (struct pies_url *url, int socket_type,
}
-
+
if (group)
@@ -124,3 +127,3 @@ create_socket (struct pies_url *url, int socket_type,
}
-
+
if (strlen (url->path) > sizeof addr.s_un.sun_path)
@@ -161,3 +164,3 @@ create_socket (struct pies_url *url, int socket_type,
short port = url->port;
-
+
uid = 0;
@@ -168,3 +171,3 @@ create_socket (struct pies_url *url, int socket_type,
socklen = sizeof (addr.s_in);
-
+
if (!host)
@@ -187,3 +190,3 @@ create_socket (struct pies_url *url, int socket_type,
break;
-
+
default:
@@ -200,3 +203,3 @@ create_socket (struct pies_url *url, int socket_type,
}
-
+
fd = socket (addr.sa.sa_family, socket_type, url->proto);
@@ -252,3 +255,3 @@ pass_fd0 (int fd, int payload)
# endif /* ! CMSG_SPACE */
-
+
char control[CMSG_SPACE (sizeof (int))];
@@ -292,3 +295,3 @@ pass_fd (const char *socket_name, int fd, unsigned maxtime)
struct sockaddr_un addr;
-
+
if (strlen (socket_name) > sizeof addr.sun_path)
@@ -300,3 +303,3 @@ pass_fd (const char *socket_name, int fd, unsigned maxtime)
strcpy (addr.sun_path, socket_name);
-
+
for (;;)
@@ -364,3 +367,3 @@ pass_fd (const char *socket_name, int fd, unsigned maxtime)
struct timeval tv;
-
+
FD_ZERO (&fds);
@@ -432,3 +435,3 @@ calc_fd_max (void)
void *
-register_socket (int fd,
+register_socket (int fd,
socket_handler_t rd,
@@ -456,3 +459,3 @@ register_socket (int fd,
}
-
+
si_tail = sip;
@@ -495,3 +498,3 @@ delete_sockinst (struct sockinst *sp)
fd_max = -1;
-
+
if (sp->prev)
@@ -574,3 +577,3 @@ pies_pause (void)
return;
-
+
if (fd_max == -1)
@@ -583,3 +586,3 @@ pies_pause (void)
fd_set exset = fdset[PIES_EVT_EX];
-
+
int rc = select (fd_max + 1, &rdset, &wrset, &exset, NULL);
@@ -639,2 +642 @@ pies_pause (void)
}
-
diff --git a/tests/Makefile.am b/tests/Makefile.am
index 447104b..b2f2719 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -16,3 +16,9 @@
-EXTRA_DIST = $(TESTSUITE_AT) testsuite package.m4 respawn retcode mailer
+AUXTOOLS = \
+ aux/respawn\
+ aux/retcode\
+ aux/mailer\
+ aux/startup
+
+EXTRA_DIST = $(TESTSUITE_AT) testsuite package.m4 $(AUXTOOLS)
DISTCLEANFILES = atconfig $(check_SCRIPTS)
@@ -48,2 +54,3 @@ TESTSUITE_AT = \
ret-notify.at\
+ startup.at\
version.at
diff --git a/tests/atlocal.in b/tests/atlocal.in
index 9069bbd..1992b80 100644
--- a/tests/atlocal.in
+++ b/tests/atlocal.in
@@ -6,3 +6,3 @@ PATH=@abs_builddir@:@abs_top_builddir@/src:$srcdir:$PATH
XFAILFILE=$abs_builddir/.badversion
-
+auxdir="$abs_srcdir/aux"
trimws() {
diff --git a/tests/mailer b/tests/aux/mailer
index f832ff5..f832ff5 100755
--- a/tests/mailer
+++ b/tests/aux/mailer
diff --git a/tests/respawn b/tests/aux/respawn
index 11d59f6..11d59f6 100755
--- a/tests/respawn
+++ b/tests/aux/respawn
diff --git a/tests/retcode b/tests/aux/retcode
index b827ba9..b827ba9 100755
--- a/tests/retcode
+++ b/tests/aux/retcode
diff --git a/tests/aux/startup b/tests/aux/startup
new file mode 100755
index 0000000..b9d92a3
--- a/dev/null
+++ b/tests/aux/startup
@@ -0,0 +1,7 @@
+#!/bin/sh
+dir=${1:?}
+time=${2:?}
+tag=${3:?}
+
+touch $dir/$tag
+sleep $time
diff --git a/tests/redirect.at b/tests/redirect.at
index 9e53ba2..3a8cca7 100644
--- a/tests/redirect.at
+++ b/tests/redirect.at
@@ -26,3 +26,3 @@ component test {
mode respawn;
- command "$abs_srcdir/respawn -tag respawn -append -pid $comp_pid_file";
+ command "$auxdir/respawn -tag respawn -append -pid $comp_pid_file";
stdout file "$outfile";
diff --git a/tests/respawn.at b/tests/respawn.at
index 8d72c40..4a8e3a7 100644
--- a/tests/respawn.at
+++ b/tests/respawn.at
@@ -25,3 +25,3 @@ component test {
mode respawn;
- command "$abs_srcdir/respawn -append -pid $comp_pid_file";
+ command "$auxdir/respawn -append -pid $comp_pid_file";
}
diff --git a/tests/ret-exec.at b/tests/ret-exec.at
index bf2c1a4..0b3d716 100644
--- a/tests/ret-exec.at
+++ b/tests/ret-exec.at
@@ -28,6 +28,6 @@ component test {
return-code 10 {
- exec "$abs_srcdir/retcode $report_file";
+ exec "$auxdir/retcode $report_file";
action disable;
}
- command "$abs_srcdir/respawn -sleep 2 -pid $comp_pid_file -exit 10";
+ command "$auxdir/respawn -sleep 2 -pid $comp_pid_file -exit 10";
}
diff --git a/tests/ret-notify.at b/tests/ret-notify.at
index d1a7f39..a7768aa 100644
--- a/tests/ret-notify.at
+++ b/tests/ret-notify.at
@@ -24,4 +24,4 @@ report_file=$PWD/report
cat > pies.conf <<_EOT
-mailer-program "$abs_srcdir/mailer";
-mailer-command-line "$abs_srcdir/mailer $report_file";
+mailer-program "$auxdir/mailer";
+mailer-command-line "$auxdir/mailer $report_file";
component test {
@@ -32,3 +32,3 @@ component test {
}
- command "$abs_srcdir/respawn -sleep 2 -exit 10";
+ command "$auxdir/respawn -sleep 2 -exit 10";
}
diff --git a/tests/startup.at b/tests/startup.at
new file mode 100644
index 0000000..72017ce
--- a/dev/null
+++ b/tests/startup.at
@@ -0,0 +1,84 @@
+# This file is part of GNU pies testsuite. -*- Autotest -*-
+# Copyright (C) 2019 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
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+#
+# GNU pies is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU pies. If not, see <http://www.gnu.org/licenses/>.
+
+AT_SETUP([Startup components])
+
+AT_CHECK([
+PIES_XFAIL_CHECK
+PIES_CONTROL_INIT
+comp_pid_file=$PWD/comp.pid
+
+cat > pies.conf <<_EOT
+component b1 {
+ mode startup;
+ command "$auxdir/startup $PWD 1 b1";
+}
+
+component b2 {
+ mode startup;
+ command "$auxdir/startup $PWD 2 b2";
+}
+
+component test {
+ mode respawn;
+ command "$auxdir/respawn -append -pid $comp_pid_file";
+}
+_EOT
+
+pies --config-file control.conf --config-file pies.conf
+
+n=0
+res=
+b1=
+b2=
+while :
+do
+ echo "n=$n" >> tracefile
+ if test -z "$b1" && test -f b1; then
+ res="${res}b1"
+ b1=1
+ echo "got b1" >> tracefile
+ fi
+ if test -z "$b2" && test -f b2; then
+ res="${res}b2"
+ b2=1
+ echo "got b2" >> tracefile
+ fi
+ if test -f $comp_pid_file; then
+ echo "got pidfile" >> tracefile
+ res="${res}pid"
+ break
+ fi
+ sleep 1
+ n=$(($n + 1))
+ if test $n -gt 10; then
+ echo >&2 "timed out"
+ break
+ fi
+done
+
+PIES_STOP
+case $res in
+b1b2pid|b2b1pid) echo b1b2pid;;
+*) echo $res
+esac
+],
+[0],
+[b1b2pid
+])
+
+AT_CLEANUP
+
diff --git a/tests/testsuite.at b/tests/testsuite.at
index 03ddd50..2a1167d 100644
--- a/tests/testsuite.at
+++ b/tests/testsuite.at
@@ -67 +67,2 @@ m4_include([ret-exec.at])
m4_include([ret-notify.at])
+m4_include([startup.at])

Return to:

Send suggestions and report system problems to the System administrator.