summaryrefslogtreecommitdiffabout
Unidiff
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
26 26
27/* 0 on the first load, and 1 on all subsequent reloads. Tells the
28 component_config_commit whether we're starting from scratch or just
29 updating an already loaded configuration */
30static int loaded;
31
27static struct complist comp_list[2]; 32static struct complist comp_list[2];
@@ -34,3 +39,3 @@ static pies_depmap_t depmap;
34 39
35static int 40static inline int
36next_index (void) 41next_index (void)
@@ -40,3 +45,3 @@ next_index (void)
40 45
41static int 46static inline int
42prev_index (void) 47prev_index (void)
@@ -87,2 +92,18 @@ component_append (struct component *comp)
87void 92void
93comp_array_remove (size_t i)
94{
95 struct component *comp = comp_array[i];
96
97 depmap_remove (depmap, i);
98 while (i < comp_count -1)
99 {
100 comp_array[i] = comp_array[i+1];
101 comp_array[i]->arridx = i;
102 i++;
103 }
104 component_free (comp);
105 comp_count--;
106}
107
108void
88component_unlink (struct component *comp) 109component_unlink (struct component *comp)
@@ -203,3 +224,8 @@ component_ref_decr (struct component *comp)
203 if (--comp->ref_count == 0) 224 if (--comp->ref_count == 0)
204 component_free (comp); 225 {
226 if (component_is_active (comp))
227 comp_array_remove (comp->arridx);
228 else
229 component_free (comp);
230 }
205} 231}
@@ -427,13 +453,2 @@ report_cyclic_dependency (pies_depmap_t dp, size_t idx)
427void 453void
428comp_array_remove (size_t i)
429{
430 struct component *comp = comp_array[i];
431 if (i < comp_count - 1)
432 memmove (&comp_array[i], &comp_array[i+1],
433 (comp_count - i - 1) * sizeof comp_array[0]);
434 component_free (comp);
435 comp_count--;
436}
437
438void
439component_build_depmap (void) 454component_build_depmap (void)
@@ -462,3 +477,2 @@ component_build_depmap (void)
462 comp_array_remove (i); 477 comp_array_remove (i);
463 depmap_remove (depmap, i);
464 continue; 478 continue;
@@ -499,6 +513,3 @@ component_build_depmap (void)
499 if (comp_array[i]->flags & CF_REMOVE) 513 if (comp_array[i]->flags & CF_REMOVE)
500 { 514 comp_array_remove (i);
501 comp_array_remove (i);
502 depmap_remove (depmap, i);
503 }
504 else 515 else
@@ -530,18 +541,32 @@ component_config_commit (void)
530 541
531 /* Rearrange components, registering prog entries for the new ones */ 542 /* Rearrange components, registering entries for the new ones */
532 for (comp = list->head, i = 0; comp; comp = comp->next, i++) 543 for (comp = list->head, i = 0; comp; )
533 { 544 {
534 match = complist_find_match (prev, comp); 545 struct component *next = comp->next;
535 if (match) 546 if (loaded && comp->mode == pies_comp_startup)
536 { 547 {
537 component_merge (match, comp); 548 /* Ignore startup components */
538 component_unlink (match); 549 component_unlink (comp);
539 match->listidx = cur;
540 component_link (match, comp->prev);
541 component_free (comp); 550 component_free (comp);
542 comp = match;
543 } 551 }
544 comp_array[i] = comp; 552 else
545 comp->arridx = i; 553 {
554 match = complist_find_match (prev, comp);
555 if (match)
556 {
557 component_merge (match, comp);
558 component_unlink (match);
559 match->listidx = cur;
560 component_link (match, comp->prev);
561 component_free (comp);
562 comp = match;
563 }
564 comp_array[i] = comp;
565 comp->arridx = i;
566 i++;
567 }
568 comp = next;
546 } 569 }
570 /* Adjust comp_count */
571 comp_count = i;
547 572
@@ -562,2 +587,4 @@ component_config_commit (void)
562 register_prog (comp); 587 register_prog (comp);
588
589 loaded = 1;
563} 590}
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)
134 struct grecs_list_entry *ep; 134 struct grecs_list_entry *ep;
135 135
136 for (ep = config_list->head; ep; ep = ep->next) 136 for (ep = config_list->head; ep; ep = ep->next)
@@ -158,3 +158,3 @@ config_file_list_serialize (struct json_value *ar)
158 struct grecs_list_entry *ep; 158 struct grecs_list_entry *ep;
159 159
160 for (ep = config_list->head; ep; ep = ep->next) 160 for (ep = config_list->head; ep; ep = ep->next)
@@ -329,3 +329,3 @@ action_free (struct action *act)
329 free (act->command); 329 free (act->command);
330 330
331 free (act); 331 free (act);
@@ -361,3 +361,3 @@ create_action (struct component *comp,
361 size_t len = strlen (arg); 361 size_t len = strlen (arg);
362 362
363 if (isdigit (arg[0])) 363 if (isdigit (arg[0]))
@@ -396,3 +396,3 @@ create_action (struct component *comp,
396 } 396 }
397 397
398 /* Alles in ordnung */ 398 /* Alles in ordnung */
@@ -401,3 +401,3 @@ create_action (struct component *comp,
401 } 401 }
402 402
403 if (retc == 0 && !allflag) 403 if (retc == 0 && !allflag)
@@ -474,3 +474,3 @@ return_code_section_parser (enum grecs_callback_command cmd,
474 } 474 }
475 475
476 switch (value->type) 476 switch (value->type)
@@ -480,3 +480,3 @@ return_code_section_parser (enum grecs_callback_command cmd,
480 break; 480 break;
481 481
482 case GRECS_TYPE_ARRAY: 482 case GRECS_TYPE_ARRAY:
@@ -485,3 +485,3 @@ return_code_section_parser (enum grecs_callback_command cmd,
485 break; 485 break;
486 486
487 case GRECS_TYPE_LIST: 487 case GRECS_TYPE_LIST:
@@ -494,3 +494,3 @@ return_code_section_parser (enum grecs_callback_command cmd,
494 break; 494 break;
495 495
496 case grecs_callback_section_end: 496 case grecs_callback_section_end:
@@ -544,3 +544,3 @@ _cb_command (enum grecs_callback_command cmd,
544 break; 544 break;
545 545
546 case GRECS_TYPE_ARRAY: 546 case GRECS_TYPE_ARRAY:
@@ -704,3 +704,3 @@ _cb_redir (enum grecs_callback_command cmd,
704 int res; 704 int res;
705 705
706 switch (value->type) 706 switch (value->type)
@@ -721,3 +721,3 @@ _cb_redir (enum grecs_callback_command cmd,
721 break; 721 break;
722 722
723 case GRECS_TYPE_ARRAY: 723 case GRECS_TYPE_ARRAY:
@@ -741,3 +741,3 @@ _cb_redir (enum grecs_callback_command cmd,
741 return 0; 741 return 0;
742 742
743 switch (res) 743 switch (res)
@@ -746,3 +746,3 @@ _cb_redir (enum grecs_callback_command cmd,
746 break; 746 break;
747 747
748 case redir_syslog: 748 case redir_syslog:
@@ -757,3 +757,3 @@ _cb_redir (enum grecs_callback_command cmd,
757 break; 757 break;
758 758
759 case redir_file: 759 case redir_file:
@@ -766,3 +766,3 @@ _cb_redir (enum grecs_callback_command cmd,
766 break; 766 break;
767 767
768 default: 768 default:
@@ -770,3 +770,3 @@ _cb_redir (enum grecs_callback_command cmd,
770 } 770 }
771 771
772 return 0; 772 return 0;
@@ -775,4 +775,4 @@ _cb_redir (enum grecs_callback_command cmd,
775static struct tokendef socktype_xtab[] = { 775static struct tokendef socktype_xtab[] = {
776 { "stream", SOCK_STREAM }, 776 { "stream", SOCK_STREAM },
777 { "dgram", SOCK_DGRAM }, 777 { "dgram", SOCK_DGRAM },
778 { "seqpacket", SOCK_SEQPACKET }, 778 { "seqpacket", SOCK_SEQPACKET },
@@ -822,2 +822,4 @@ static struct tokendef modetab[] = {
822 {"pass", pies_comp_pass_fd}, 822 {"pass", pies_comp_pass_fd},
823 {"startup", pies_comp_startup},
824 {"shutdown", pies_comp_shutdown},
823 {"boot", pies_comp_boot}, 825 {"boot", pies_comp_boot},
@@ -827,3 +829,3 @@ static struct tokendef modetab[] = {
827 {"powerokwait", pies_comp_powerokwait}, 829 {"powerokwait", pies_comp_powerokwait},
828 {"ctrlaltdel", pies_comp_ctrlaltdel}, 830 {"ctrlaltdel", pies_comp_ctrlaltdel},
829 {"ondemand", pies_comp_ondemand}, 831 {"ondemand", pies_comp_ondemand},
@@ -922,3 +924,3 @@ _cb_flags (enum grecs_callback_command cmd,
922 break; 924 break;
923 925
924 case GRECS_TYPE_LIST: 926 case GRECS_TYPE_LIST:
@@ -926,3 +928,3 @@ _cb_flags (enum grecs_callback_command cmd,
926 struct grecs_list_entry *ep; 928 struct grecs_list_entry *ep;
927 929
928 for (ep = value->v.list->head; ep; ep = ep->next) 930 for (ep = value->v.list->head; ep; ep = ep->next)
@@ -941,3 +943,3 @@ _cb_flags (enum grecs_callback_command cmd,
941 break; 943 break;
942 944
943 case GRECS_TYPE_ARRAY: 945 case GRECS_TYPE_ARRAY:
@@ -1230,3 +1232,3 @@ find_component_keyword (const char *ident)
1230 struct grecs_keyword *kwp; 1232 struct grecs_keyword *kwp;
1231 1233
1232 for (kwp = component_keywords; kwp->ident; kwp++) 1234 for (kwp = component_keywords; kwp->ident; kwp++)
@@ -1258,3 +1260,3 @@ component_section_parser (enum grecs_callback_command cmd,
1258 break; 1260 break;
1259 1261
1260 case grecs_callback_set_value: 1262 case grecs_callback_set_value:
@@ -1536,3 +1538,3 @@ pies_config_parse (char const *name)
1536 return 1; 1538 return 1;
1537 1539
1538 for (node = tree; node; node = node->next) 1540 for (node = tree; node; node = node->next)
@@ -1552,3 +1554,3 @@ pies_config_parse (char const *name)
1552 return 1; 1554 return 1;
1553 1555
1554 return 0; 1556 return 0;
@@ -1575,3 +1577,3 @@ pies_read_config (void)
1575 component_config_begin (); 1577 component_config_begin ();
1576 1578
1577 for (ep = config_list->head; ep; ep = ep->next) 1579 for (ep = config_list->head; ep; ep = ep->next)
@@ -1585,6 +1587,6 @@ pies_read_config (void)
1585 err = 0; 1587 err = 0;
1586 1588
1587 if (err) 1589 if (err)
1588 component_config_rollback (); 1590 component_config_rollback ();
1589 1591
1590 return err; 1592 return err;
@@ -1658,3 +1660,3 @@ setsigvhan (RETSIGTYPE (*handler) (int signo), int *sigv, int sigc)
1658 struct sigaction act; 1660 struct sigaction act;
1659 1661
1660 act.sa_flags = 0; 1662 act.sa_flags = 0;
@@ -1781,3 +1783,3 @@ request_restart_components (size_t cc, char **cv)
1781 size_t i, j; 1783 size_t i, j;
1782 1784
1783 argv = grecs_calloc (5 + 3 * cc - 1, sizeof (*argv)); 1785 argv = grecs_calloc (5 + 3 * cc - 1, sizeof (*argv));
@@ -1805,3 +1807,3 @@ list_components (void)
1805 char *argv[5]; 1807 char *argv[5];
1806 1808
1807 argv[0] = "piesctl"; 1809 argv[0] = "piesctl";
@@ -1944,3 +1946,3 @@ set_mailer_argcv (void)
1944 struct wordsplit ws; 1946 struct wordsplit ws;
1945 1947
1946 if (wordsplit (mailer_command_line, &ws, WRDSF_DEFFLAGS)) 1948 if (wordsplit (mailer_command_line, &ws, WRDSF_DEFFLAGS))
@@ -2035,3 +2037,3 @@ main (int argc, char **argv)
2035 int i; 2037 int i;
2036 2038
2037 set_program_name (argv[0]); 2039 set_program_name (argv[0]);
@@ -2045,6 +2047,6 @@ main (int argc, char **argv)
2045 grecs_print_diag_fun = pies_diag_printer; 2047 grecs_print_diag_fun = pies_diag_printer;
2046 2048
2047 pies_master_argc = argc; 2049 pies_master_argc = argc;
2048 pies_master_argv = argv; 2050 pies_master_argv = argv;
2049 2051
2050 set_quoting_style (NULL, shell_quoting_style); 2052 set_quoting_style (NULL, shell_quoting_style);
@@ -2060,3 +2062,3 @@ main (int argc, char **argv)
2060 } 2062 }
2061 2063
2062 /* Set default logging */ 2064 /* Set default logging */
@@ -2069,5 +2071,5 @@ main (int argc, char **argv)
2069 diag_flags = DIAG_TO_SYSLOG | (stderr_closed_p () ? 0 : DIAG_TO_STDERR); 2071 diag_flags = DIAG_TO_SYSLOG | (stderr_closed_p () ? 0 : DIAG_TO_STDERR);
2070 2072
2071 diag_setup (diag_flags); 2073 diag_setup (diag_flags);
2072 2074
2073 config_init (); 2075 config_init ();
@@ -2075,3 +2077,3 @@ main (int argc, char **argv)
2075 parse_options (&argc, &argv); 2077 parse_options (&argc, &argv);
2076 2078
2077 if (argc && !(command == COM_RESTART_COMPONENT 2079 if (argc && !(command == COM_RESTART_COMPONENT
@@ -2083,3 +2085,3 @@ main (int argc, char **argv)
2083 } 2085 }
2084 2086
2085 if (!instance) 2087 if (!instance)
@@ -2121,3 +2123,3 @@ main (int argc, char **argv)
2121 set_mailer_argcv (); 2123 set_mailer_argcv ();
2122 2124
2123 if (lint_mode) 2125 if (lint_mode)
@@ -2127,3 +2129,3 @@ main (int argc, char **argv)
2127 diag_setup (log_to_stderr_only ? DIAG_TO_STDERR : 0); 2129 diag_setup (log_to_stderr_only ? DIAG_TO_STDERR : 0);
2128 2130
2129 if (!control.url) 2131 if (!control.url)
@@ -2139,3 +2141,3 @@ main (int argc, char **argv)
2139 } 2141 }
2140 2142
2141 switch (command) 2143 switch (command)
@@ -2147,3 +2149,3 @@ main (int argc, char **argv)
2147 exit (request_restart_components (argc, argv)); 2149 exit (request_restart_components (argc, argv));
2148 2150
2149 case COM_RELOAD: 2151 case COM_RELOAD:
@@ -2164,7 +2166,7 @@ main (int argc, char **argv)
2164 exit (0); 2166 exit (0);
2165 2167
2166 case COM_TRACE_PREREQ: 2168 case COM_TRACE_PREREQ:
2167 components_trace (argv, depmap_col); 2169 components_trace (argv, depmap_col);
2168 exit (0); 2170 exit (0);
2169 2171
2170 default: 2172 default:
@@ -2195,3 +2197,3 @@ main (int argc, char **argv)
2195 break; 2197 break;
2196 2198
2197 case pies_status_running: 2199 case pies_status_running:
@@ -2201,3 +2203,3 @@ main (int argc, char **argv)
2201 } 2203 }
2202 2204
2203 if (!foreground) 2205 if (!foreground)
@@ -2214,3 +2216,3 @@ main (int argc, char **argv)
2214 logmsg (LOG_INFO, _("%s %s starting"), proginfo.package, proginfo.version); 2216 logmsg (LOG_INFO, _("%s %s starting"), proginfo.package, proginfo.version);
2215 2217
2216 if (!init_process) 2218 if (!init_process)
@@ -2221,3 +2223,3 @@ main (int argc, char **argv)
2221 } 2223 }
2222 2224
2223 if (pies_master_argv[0][0] != '/') 2225 if (pies_master_argv[0][0] != '/')
@@ -2230,2 +2232,3 @@ main (int argc, char **argv)
2230 progman_create_sockets (); 2232 progman_create_sockets ();
2233 program_init_startup ();
2231 progman_start (); 2234 progman_start ();
@@ -2263,3 +2266,3 @@ main (int argc, char **argv)
2263 break; 2266 break;
2264 2267
2265 case ACTION_STOP: 2268 case ACTION_STOP:
@@ -2278,3 +2281,3 @@ main (int argc, char **argv)
2278 break; 2281 break;
2279 2282
2280 case ACTION_KBREQUEST: 2283 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
106 char *message; /* Notification mail. */ 106 char *message; /* Notification mail. */
107 char *command; /* Execute this command */ 107 char *command; /* Execute this command */
108}; 108};
@@ -139,3 +139,10 @@ enum pies_comp_mode
139 pies_comp_pass_fd, 139 pies_comp_pass_fd,
140 140
141 /* Components of this type runs once on program startup. Running other
142 components is delayed until the last startup component finishes. */
143 pies_comp_startup,
144
145 /* FIXME: Runs before program termination */
146 pies_comp_shutdown,
147
141 /* 148 /*
@@ -146,3 +153,3 @@ enum pies_comp_mode
146 for its termination */ 153 for its termination */
147 pies_comp_wait = pies_mark_sysvinit, 154 pies_comp_wait = pies_mark_sysvinit,
148 /* Execute the component once, when the specified runlevel is entered */ 155 /* Execute the component once, when the specified runlevel is entered */
@@ -164,3 +171,3 @@ enum pies_comp_mode
164 pressed the Ctrl+Alt+Del combination. */ 171 pressed the Ctrl+Alt+Del combination. */
165 pies_comp_ctrlaltdel, 172 pies_comp_ctrlaltdel,
166 /* Execute the component when a specified ondemand runlevel is called */ 173 /* Execute the component when a specified ondemand runlevel is called */
@@ -186,12 +193,12 @@ enum pies_comp_mode
186#define CF_PRECIOUS 0x002 /* The component is precious (should not 193#define CF_PRECIOUS 0x002 /* The component is precious (should not
187 be disabled) */ 194 be disabled) */
188#define CF_WAIT 0x004 /* Wait for the component instance to 195#define CF_WAIT 0x004 /* Wait for the component instance to
189 terminate. */ 196 terminate. */
190#define CF_TCPMUX 0x008 /* A plain TCPMUX service */ 197#define CF_TCPMUX 0x008 /* A plain TCPMUX service */
191#define CF_TCPMUXPLUS 0x010 /* A TCPMUX-plus service, i.e. pies 198#define CF_TCPMUXPLUS 0x010 /* A TCPMUX-plus service, i.e. pies
192 must emit a '+' response before starting 199 must emit a '+' response before starting
193 it */ 200 it */
194#define CF_INTERNAL 0x020 /* An internal inetd service */ 201#define CF_INTERNAL 0x020 /* An internal inetd service */
195#define CF_SOCKENV 0x040 /* Component wants socket information in 202#define CF_SOCKENV 0x040 /* Component wants socket information in
196 the environment */ 203 the environment */
197#define CF_RESOLVE 0x080 /* Resolve IP addresses */ 204#define CF_RESOLVE 0x080 /* Resolve IP addresses */
@@ -212,5 +219,5 @@ struct component
212 size_t arridx; /* Index of this component. */ 219 size_t arridx; /* Index of this component. */
213 size_t ref_count; /* Reference count. */ 220 size_t ref_count; /* Reference count. */
214 struct prog *prog; /* Prog associated with this component. */ 221 struct prog *prog; /* Prog associated with this component. */
215 222
216 enum pies_comp_mode mode; 223 enum pies_comp_mode mode;
@@ -234,3 +241,3 @@ struct component
234 char *runlevels; 241 char *runlevels;
235 242
236 /* For inetd components */ 243 /* For inetd components */
@@ -255,5 +262,5 @@ struct component
255 char *max_ip_connections_message; 262 char *max_ip_connections_message;
256 263
257 /* Redirectors: */ 264 /* Redirectors: */
258 int facility; /* Syslog facility. */ 265 int facility; /* Syslog facility. */
259 struct redirector redir[2]; /* Repeaters for stdout and stderr */ 266 struct redirector redir[2]; /* Repeaters for stdout and stderr */
@@ -336,2 +343,3 @@ int pies_reread_config (void);
336void register_prog (struct component *comp); 343void register_prog (struct component *comp);
344void program_init_startup (void);
337int progman_waiting_p (void); 345int progman_waiting_p (void);
@@ -596,3 +604,3 @@ struct sysvinit_request
596#define SYSV_ACCT_PROC_START 2 604#define SYSV_ACCT_PROC_START 2
597 #define SYSV_ACCT_PROC_STOP 3 605#define SYSV_ACCT_PROC_STOP 3
598 606
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)
67 return NULL; 67 return NULL;
68} 68}
69 69
@@ -124,3 +124,3 @@ link_prog (struct prog *prog, struct prog *ref)
124 prog->next = ref->next; 124 prog->next = ref->next;
125 125
126 if ((x = ref->next)) 126 if ((x = ref->next))
@@ -153,3 +153,3 @@ destroy_prog (struct prog **pp)
153 struct prog *p = *pp; 153 struct prog *p = *pp;
154 154
155 unlink_prog (p); 155 unlink_prog (p);
@@ -160,4 +160,4 @@ destroy_prog (struct prog **pp)
160 if (p->v.p.status == status_listener && p->v.p.socket != -1) 160 if (p->v.p.status == status_listener && p->v.p.socket != -1)
161 deregister_socket (p->v.p.socket); 161 deregister_socket (p->v.p.socket);
162 /* FIXME: Remove also all dependent progs (esp. tcpmux) */ 162 /* FIXME: Remove also all dependent progs (esp. tcpmux) */
163 if (p->v.p.redir[RETR_OUT]) 163 if (p->v.p.redir[RETR_OUT])
@@ -167,3 +167,3 @@ destroy_prog (struct prog **pp)
167 break; 167 break;
168 168
169 case TYPE_REDIRECTOR: 169 case TYPE_REDIRECTOR:
@@ -184,3 +184,3 @@ destroy_prog (struct prog **pp)
184 break; 184 break;
185 185
186 case TYPE_COMMAND: 186 case TYPE_COMMAND:
@@ -258,3 +258,3 @@ find_prog_ref (struct component *comp)
258 } 258 }
259 259
260 if (comp->prog) 260 if (comp->prog)
@@ -272,3 +272,3 @@ find_prog_ref (struct component *comp)
272} 272}
273 273
274static struct prog * 274static struct prog *
@@ -277,3 +277,3 @@ register_prog0 (struct component *comp)
277 struct prog *newp; 277 struct prog *newp;
278 278
279 newp = grecs_zalloc (sizeof (*newp)); 279 newp = grecs_zalloc (sizeof (*newp));
@@ -293,3 +293,3 @@ register_prog0 (struct component *comp)
293 newp->active = 1; 293 newp->active = 1;
294 294
295 if (comp->mode != pies_comp_exec) 295 if (comp->mode != pies_comp_exec)
@@ -319,2 +319,15 @@ register_command (char *tag, char *command, pid_t pid)
319 319
320static inline int
321progman_startup_phase (void)
322{
323 struct prog *prog;
324
325 for (prog = proghead; prog; prog = prog->next)
326 {
327 if (IS_COMPONENT (prog) && prog->v.p.comp->mode == pies_comp_startup)
328 return 1;
329 }
330 return 0;
331}
332
320int 333int
@@ -323,6 +336,8 @@ progman_waiting_p (void)
323 struct prog *prog; 336 struct prog *prog;
324 337
325 for (prog = proghead; prog; prog = prog->next) 338 for (prog = proghead; prog; prog = prog->next)
326 { 339 {
327 if (IS_COMPONENT (prog) && prog->wait && prog->pid > 0) 340 if (IS_COMPONENT (prog)
341 && prog->pid > 0
342 && (prog->wait || prog->v.p.comp->mode == pies_comp_startup))
328 { 343 {
@@ -408,3 +423,3 @@ open_redirector (struct prog *master, int stream)
408 return redirect_to_file (master, stream); 423 return redirect_to_file (master, stream);
409 424
410 case redir_syslog: 425 case redir_syslog:
@@ -412,3 +427,3 @@ open_redirector (struct prog *master, int stream)
412 } 427 }
413 428
414 if (pipe (p)) 429 if (pipe (p))
@@ -418,3 +433,3 @@ open_redirector (struct prog *master, int stream)
418 } 433 }
419 434
420 switch (pid = fork ()) 435 switch (pid = fork ())
@@ -430,6 +445,6 @@ open_redirector (struct prog *master, int stream)
430 close_fds (&fdset); 445 close_fds (&fdset);
431 446
432 diag_setup (0); 447 diag_setup (0);
433 signal_setup (redir_exit); 448 signal_setup (redir_exit);
434 449
435 close (p[1]); 450 close (p[1]);
@@ -443,3 +458,3 @@ open_redirector (struct prog *master, int stream)
443 _exit (0); 458 _exit (0);
444 459
445 case -1: 460 case -1:
@@ -468,3 +483,3 @@ conn_class_hasher (void *data, unsigned long n_buckets)
468 size_t len; 483 size_t len;
469 484
470 while ((ch = *tag++)) 485 while ((ch = *tag++))
@@ -532,3 +547,3 @@ conn_class_lookup (const char *tag,
532 } 547 }
533 548
534 probe->count = 0; 549 probe->count = 0;
@@ -727,3 +742,3 @@ env_concat (const char *name, size_t namelen, const char *a, const char *b)
727 size_t len; 742 size_t len;
728 743
729 if (a && b) 744 if (a && b)
@@ -755,3 +770,3 @@ env_concat (const char *name, size_t namelen, const char *a, const char *b)
755} 770}
756 771
757static void 772static void
@@ -762,3 +777,3 @@ environ_setup (char **hint)
762 size_t count, i, j, n; 777 size_t count, i, j, n;
763 778
764 if (!hint) 779 if (!hint)
@@ -771,3 +786,3 @@ environ_setup (char **hint)
771 } 786 }
772 787
773 /* Count new environment size */ 788 /* Count new environment size */
@@ -777,3 +792,3 @@ environ_setup (char **hint)
777 count++; 792 count++;
778 793
779 for (i = 0; hint[i]; i++) 794 for (i = 0; hint[i]; i++)
@@ -783,6 +798,6 @@ environ_setup (char **hint)
783 new_env = grecs_calloc (count + 1, sizeof new_env[0]); 798 new_env = grecs_calloc (count + 1, sizeof new_env[0]);
784 799
785 /* Populate the environment. */ 800 /* Populate the environment. */
786 n = 0; 801 n = 0;
787 802
788 if (old_env) 803 if (old_env)
@@ -797,3 +812,3 @@ environ_setup (char **hint)
797 char *p; 812 char *p;
798 813
799 if (hint[i][0] == '-') 814 if (hint[i][0] == '-')
@@ -808,3 +823,3 @@ environ_setup (char **hint)
808 j = n; 823 j = n;
809 824
810 if ((p = strchr (hint[i], '='))) 825 if ((p = strchr (hint[i], '=')))
@@ -813,3 +828,3 @@ environ_setup (char **hint)
813 continue; /* Ignore erroneous entry */ 828 continue; /* Ignore erroneous entry */
814 if (p[-1] == '+') 829 if (p[-1] == '+')
815 new_env[j] = env_concat (hint[i], p - hint[i] - 1, 830 new_env[j] = env_concat (hint[i], p - hint[i] - 1,
@@ -837,3 +852,3 @@ environ_setup (char **hint)
837 free (environ); 852 free (environ);
838 853
839 environ = new_env; 854 environ = new_env;
@@ -854,3 +869,3 @@ prog_sockenv (struct prog *prog)
854 const char *proto = NULL; 869 const char *proto = NULL;
855 870
856 if (!(prog->v.p.comp->flags & CF_SOCKENV)) 871 if (!(prog->v.p.comp->flags & CF_SOCKENV))
@@ -861,3 +876,3 @@ prog_sockenv (struct prog *prog)
861 add_env (ENV_SOCKTYPE, proto); 876 add_env (ENV_SOCKTYPE, proto);
862 877
863 if (prog->v.p.comp->socket_url) 878 if (prog->v.p.comp->socket_url)
@@ -870,3 +885,3 @@ prog_sockenv (struct prog *prog)
870 add_env (ENV_PROTO, proto); 885 add_env (ENV_PROTO, proto);
871 886
872 if (getsockname (prog->v.p.socket, 887 if (getsockname (prog->v.p.socket,
@@ -922,3 +937,3 @@ check_rate (struct prog *prog, unsigned testtime, size_t max_count)
922 time_t now; 937 time_t now;
923 938
924 time (&now); 939 time (&now);
@@ -932,3 +947,3 @@ check_rate (struct prog *prog, unsigned testtime, size_t max_count)
932 } 947 }
933 948
934 if (prog->v.p.failcount > max_count) 949 if (prog->v.p.failcount > max_count)
@@ -940,3 +955,3 @@ check_rate (struct prog *prog, unsigned testtime, size_t max_count)
940 } 955 }
941 956
942 return 0; 957 return 0;
@@ -963,3 +978,3 @@ check_connection_rate (struct prog *prog)
963 size_t max_rate = prog->v.p.comp->max_rate 978 size_t max_rate = prog->v.p.comp->max_rate
964 ? prog->v.p.comp->max_rate : default_max_rate; 979 ? prog->v.p.comp->max_rate : default_max_rate;
965 if (max_rate && check_rate (prog, 60, max_rate)) 980 if (max_rate && check_rate (prog, 60, max_rate))
@@ -1011,3 +1026,3 @@ prog_start_prologue (struct prog *prog)
1011 } 1026 }
1012 1027
1013 environ_setup (prog->v.p.comp->env ? 1028 environ_setup (prog->v.p.comp->env ?
@@ -1022,3 +1037,3 @@ prog_start_prologue (struct prog *prog)
1022 umask (prog->v.p.comp->umask); 1037 umask (prog->v.p.comp->umask);
1023 1038
1024 set_limits (prog_tag (prog), 1039 set_limits (prog_tag (prog),
@@ -1026,3 +1041,3 @@ prog_start_prologue (struct prog *prog)
1026 prog->v.p.comp->limits : pies_limits); 1041 prog->v.p.comp->limits : pies_limits);
1027 1042
1028 if (debug_level >= 1) 1043 if (debug_level >= 1)
@@ -1031,3 +1046,3 @@ prog_start_prologue (struct prog *prog)
1031 struct component *comp = prog->v.p.comp; 1046 struct component *comp = prog->v.p.comp;
1032 1047
1033 logmsg_printf (LOG_DEBUG, "executing"); 1048 logmsg_printf (LOG_DEBUG, "executing");
@@ -1049,3 +1064,3 @@ prog_execute (struct prog *prog)
1049 } 1064 }
1050 1065
1051 execvp (prog->v.p.comp->program ? 1066 execvp (prog->v.p.comp->program ?
@@ -1079,3 +1094,3 @@ prog_start (struct prog *prog)
1079 fd_set fdset; 1094 fd_set fdset;
1080 1095
1081 if (prog->pid > 0 || !IS_COMPONENT (prog)) 1096 if (prog->pid > 0 || !IS_COMPONENT (prog))
@@ -1125,3 +1140,3 @@ prog_start (struct prog *prog)
1125 break; 1140 break;
1126 1141
1127 case pies_comp_accept: 1142 case pies_comp_accept:
@@ -1141,5 +1156,5 @@ prog_start (struct prog *prog)
1141 } 1156 }
1142 1157
1143 debug (1, (_("starting %s"), prog_tag (prog))); 1158 debug (1, (_("starting %s"), prog_tag (prog)));
1144 1159
1145 if (prog->v.p.comp->rmfile) 1160 if (prog->v.p.comp->rmfile)
@@ -1160,3 +1175,3 @@ prog_start (struct prog *prog)
1160 redir[RETR_ERR] = open_redirector (prog, RETR_ERR); 1175 redir[RETR_ERR] = open_redirector (prog, RETR_ERR);
1161 1176
1162 switch (pid = fork ()) 1177 switch (pid = fork ())
@@ -1169,12 +1184,12 @@ prog_start (struct prog *prog)
1169 switch (prog->v.p.comp->mode) 1184 switch (prog->v.p.comp->mode)
1170 { 1185 {
1171 case pies_comp_accept: 1186 case pies_comp_accept:
1172 case pies_comp_inetd: 1187 case pies_comp_inetd:
1173 prog_sockenv (prog); 1188 prog_sockenv (prog);
1174 1189
1175 dup2 (prog->v.p.socket, 0); 1190 dup2 (prog->v.p.socket, 0);
1176 dup2 (prog->v.p.socket, 1); 1191 dup2 (prog->v.p.socket, 1);
1177 close (prog->v.p.socket); 1192 close (prog->v.p.socket);
1178 prog->v.p.socket = -1; 1193 prog->v.p.socket = -1;
1179 break; 1194 break;
1180 1195
@@ -1184,3 +1199,3 @@ prog_start (struct prog *prog)
1184 int fd = console_open (O_RDWR|O_NOCTTY); 1199 int fd = console_open (O_RDWR|O_NOCTTY);
1185 if (fd < 0) 1200 if (fd < 0)
1186 { 1201 {
@@ -1220,4 +1235,4 @@ prog_start (struct prog *prog)
1220 } 1235 }
1221 break; 1236 break;
1222 } 1237 }
1223 1238
@@ -1238,3 +1253,3 @@ prog_start (struct prog *prog)
1238 } 1253 }
1239 1254
1240 /* Close unneeded descripitors */ 1255 /* Close unneeded descripitors */
@@ -1249,4 +1264,4 @@ prog_start (struct prog *prog)
1249 prog_execute (prog); 1264 prog_execute (prog);
1250 1265
1251 1266
1252 case -1: 1267 case -1:
@@ -1293,3 +1308,3 @@ check_acl (pies_acl_t acl, struct sockaddr *s, socklen_t salen,
1293 int rc; 1308 int rc;
1294 1309
1295 if (!acl) 1310 if (!acl)
@@ -1300,3 +1315,3 @@ check_acl (pies_acl_t acl, struct sockaddr *s, socklen_t salen,
1300 input.identity = identity; 1315 input.identity = identity;
1301 1316
1302 rc = pies_acl_check (acl, &input, 1); 1317 rc = pies_acl_check (acl, &input, 1);
@@ -1317,3 +1332,3 @@ fd_report (int fd, const char *msg)
1317 size_t len; 1332 size_t len;
1318 1333
1319 if (!msg) 1334 if (!msg)
@@ -1336,3 +1351,3 @@ fd_report (int fd, const char *msg)
1336 } 1351 }
1337} 1352}
1338 1353
@@ -1346,3 +1361,3 @@ _prog_accept (struct prog *p)
1346 struct conn_class *pcclass; 1361 struct conn_class *pcclass;
1347 1362
1348 fd = accept (p->v.p.socket, (struct sockaddr*) &addr, &addrlen); 1363 fd = accept (p->v.p.socket, (struct sockaddr*) &addr, &addrlen);
@@ -1353,3 +1368,3 @@ _prog_accept (struct prog *p)
1353 } 1368 }
1354 1369
1355 if (debug_level >= 1) 1370 if (debug_level >= 1)
@@ -1396,3 +1411,3 @@ _prog_accept (struct prog *p)
1396 } 1411 }
1397 1412
1398 if (check_connection_rate (p)) 1413 if (check_connection_rate (p))
@@ -1449,3 +1464,3 @@ _prog_wait (struct prog *p)
1449} 1464}
1450 1465
1451int 1466int
@@ -1458,3 +1473,3 @@ progman_accept (int socket, void *data)
1458 return _prog_accept (p); 1473 return _prog_accept (p);
1459 1474
1460 return _prog_wait (p); 1475 return _prog_wait (p);
@@ -1528,2 +1543,21 @@ progman_recompute_alarm (void)
1528void 1543void
1544program_init_startup (void)
1545{
1546 struct prog *prog;
1547
1548 for (prog = proghead; prog; prog = prog->next)
1549 if (IS_COMPONENT (prog) && prog->v.p.comp->mode == pies_comp_startup)
1550 {
1551 debug (1, ("running startup components"));
1552 break;
1553 }
1554
1555 for (; prog; prog = prog->next)
1556 if (IS_COMPONENT (prog) && prog->v.p.comp->mode == pies_comp_startup)
1557 {
1558 prog_start (prog);
1559 }
1560}
1561
1562void
1529progman_start (void) 1563progman_start (void)
@@ -1533,5 +1567,6 @@ progman_start (void)
1533 if (progman_waiting_p ()) 1567 if (progman_waiting_p ())
1534 /* Noting to do if there are processes left in the previous runlevel */ 1568 /* Noting to do if there are processes left in the previous runlevel
1569 (in sysv-init mode) or startup components running. */
1535 return; 1570 return;
1536 1571
1537 debug (1, ("starting components")); 1572 debug (1, ("starting components"));
@@ -1567,4 +1602,4 @@ check_stopping (struct prog *prog, time_t now)
1567 if (prog->pid == 0) 1602 if (prog->pid == 0)
1568 logmsg (LOG_EMERG, 1603 logmsg (LOG_EMERG,
1569 _("INTERNAL ERROR: attempting to kill unexisting process %s"), 1604 _("INTERNAL ERROR: attempting to kill unexisting process %s"),
1570 prog_tag (prog)); 1605 prog_tag (prog));
@@ -1627,3 +1662,3 @@ progman_wake_sleeping (int onalrm)
1627 break; 1662 break;
1628 1663
1629 case status_stopping: 1664 case status_stopping:
@@ -1636,3 +1671,3 @@ progman_wake_sleeping (int onalrm)
1636 break; 1671 break;
1637 1672
1638 default: 1673 default:
@@ -1649,3 +1684,3 @@ prog_start_prerequisites (struct prog *prog)
1649 int warned = 0; 1684 int warned = 0;
1650 1685
1651 if (!prog->active) 1686 if (!prog->active)
@@ -1657,3 +1692,3 @@ prog_start_prerequisites (struct prog *prog)
1657 struct prog *p; 1692 struct prog *p;
1658 1693
1659 if (!comp->prog || comp->flags & CF_PRECIOUS) 1694 if (!comp->prog || comp->flags & CF_PRECIOUS)
@@ -1671,3 +1706,3 @@ prog_start_prerequisites (struct prog *prog)
1671 } 1706 }
1672 1707
1673 p = comp->prog; 1708 p = comp->prog;
@@ -1677,6 +1712,6 @@ prog_start_prerequisites (struct prog *prog)
1677 continue; 1712 continue;
1678 1713
1679 case status_stopped: 1714 case status_stopped:
1680 break; 1715 break;
1681 1716
1682 case status_listener: 1717 case status_listener:
@@ -1702,3 +1737,3 @@ prog_start_prerequisites (struct prog *prog)
1702 depmap_end (pos); 1737 depmap_end (pos);
1703 1738
1704 return ret; 1739 return ret;
@@ -1759,3 +1794,3 @@ prog_stop (struct prog *prog, int sig)
1759 kill (prog->pid, sig); 1794 kill (prog->pid, sig);
1760} 1795}
1761 1796
@@ -1789,3 +1824,3 @@ print_status (const char *tag, pid_t pid, int status, int expect_term)
1789 prio = LOG_ERR; 1824 prio = LOG_ERR;
1790 1825
1791 if (WIFEXITED (status)) 1826 if (WIFEXITED (status))
@@ -1803,3 +1838,3 @@ print_status (const char *tag, pid_t pid, int status, int expect_term)
1803 char const *coremsg = ""; 1838 char const *coremsg = "";
1804 1839
1805 if (expect_term && WTERMSIG (status) == SIGTERM) 1840 if (expect_term && WTERMSIG (status) == SIGTERM)
@@ -1825,3 +1860,3 @@ print_status (const char *tag, pid_t pid, int status, int expect_term)
1825static void propagate_child_exit (pid_t) ATTRIBUTE_NORETURN; 1860static void propagate_child_exit (pid_t) ATTRIBUTE_NORETURN;
1826 1861
1827static void 1862static void
@@ -1857,3 +1892,3 @@ wordsplit_string (struct wordsplit const *ws)
1857 size_t len = 0; 1892 size_t len = 0;
1858 1893
1859 for (i = 0; i < count; i++) 1894 for (i = 0; i < count; i++)
@@ -1885,3 +1920,3 @@ send_msg (char *rcpts, const char *msg_text)
1885 size_t size; 1920 size_t size;
1886 1921
1887 ws.ws_offs = mailer_argc; 1922 ws.ws_offs = mailer_argc;
@@ -1898,3 +1933,3 @@ send_msg (char *rcpts, const char *msg_text)
1898 debug (1, (_("sending notification to %s"), rcpts)); 1933 debug (1, (_("sending notification to %s"), rcpts));
1899 1934
1900 /* Copy mailer arguments */ 1935 /* Copy mailer arguments */
@@ -1913,3 +1948,3 @@ send_msg (char *rcpts, const char *msg_text)
1913 size_t len; 1948 size_t len;
1914 1949
1915 while (*arg && c_isblank (*arg)) 1950 while (*arg && c_isblank (*arg))
@@ -1936,6 +1971,6 @@ send_msg (char *rcpts, const char *msg_text)
1936 ws.ws_wordv[k] = NULL; 1971 ws.ws_wordv[k] = NULL;
1937 1972
1938 /* Fork a child: */ 1973 /* Fork a child: */
1939 child_pid = fork (); 1974 child_pid = fork ();
1940 1975
1941 if (child_pid < 0) 1976 if (child_pid < 0)
@@ -1957,3 +1992,3 @@ send_msg (char *rcpts, const char *msg_text)
1957 } 1992 }
1958 1993
1959 /* Child process */ 1994 /* Child process */
@@ -1969,3 +2004,3 @@ send_msg (char *rcpts, const char *msg_text)
1969 } 2004 }
1970 2005
1971 grand_child_pid = fork (); 2006 grand_child_pid = fork ();
@@ -2032,3 +2067,3 @@ notify_get_tag (char **ret, void *data)
2032 *ret = s; 2067 *ret = s;
2033 return WRDSE_OK; 2068 return WRDSE_OK;
2034} 2069}
@@ -2041,3 +2076,3 @@ notify_get_termination (char **ret, void *data)
2041 char *s; 2076 char *s;
2042 2077
2043 if (WIFEXITED (clos->status)) 2078 if (WIFEXITED (clos->status))
@@ -2055,5 +2090,5 @@ notify_get_termination (char **ret, void *data)
2055 *ret = s; 2090 *ret = s;
2056 return WRDSE_OK; 2091 return WRDSE_OK;
2057} 2092}
2058 2093
2059static int 2094static int
@@ -2064,3 +2099,3 @@ notify_get_retcode (char **ret, void *data)
2064 size_t l = 0; 2099 size_t l = 0;
2065 2100
2066 if (WIFEXITED (clos->status)) 2101 if (WIFEXITED (clos->status))
@@ -2074,5 +2109,5 @@ notify_get_retcode (char **ret, void *data)
2074 *ret = s; 2109 *ret = s;
2075 return WRDSE_OK; 2110 return WRDSE_OK;
2076} 2111}
2077 2112
2078struct notify_variable 2113struct notify_variable
@@ -2092,3 +2127,3 @@ static struct notify_variable notify_vartab[] = {
2092}; 2127};
2093 2128
2094static int 2129static int
@@ -2102,3 +2137,3 @@ notify_getvar (char **ret, const char *vptr, size_t vlen, void *data)
2102} 2137}
2103 2138
2104static void 2139static void
@@ -2122,3 +2157,3 @@ notify (const char *tag, int status, struct action *act)
2122 closure.act = act; 2157 closure.act = act;
2123 2158
2124 env[PROGRAM_NAME_IDX] = program_name; 2159 env[PROGRAM_NAME_IDX] = program_name;
@@ -2146,3 +2181,3 @@ status_matches_p (struct action *act, unsigned status)
2146 int i; 2181 int i;
2147 2182
2148 if (act->nstat == 0) 2183 if (act->nstat == 0)
@@ -2186,3 +2221,3 @@ run_command (struct action *act, struct prog *prog, unsigned retcode,
2186 close_fds (NULL); 2221 close_fds (NULL);
2187 2222
2188 argv[0] = "/bin/sh"; 2223 argv[0] = "/bin/sh";
@@ -2210,3 +2245,3 @@ react (struct prog *prog, int status, pid_t pid)
2210 list = default_component.act_list; 2245 list = default_component.act_list;
2211 2246
2212 if (WIFEXITED (status)) 2247 if (WIFEXITED (status))
@@ -2235,3 +2270,3 @@ react (struct prog *prog, int status, pid_t pid)
2235 struct action *act = ep->data; 2270 struct action *act = ep->data;
2236 2271
2237 if (status_matches_p (act, retcode)) 2272 if (status_matches_p (act, retcode))
@@ -2242,3 +2277,3 @@ react (struct prog *prog, int status, pid_t pid)
2242 } 2277 }
2243 2278
2244 switch (act->act) 2279 switch (act->act)
@@ -2249,3 +2284,3 @@ react (struct prog *prog, int status, pid_t pid)
2249 break; 2284 break;
2250 2285
2251 case action_disable: 2286 case action_disable:
@@ -2265,3 +2300,3 @@ react (struct prog *prog, int status, pid_t pid)
2265 } 2300 }
2266 2301
2267 if (!list && prog->v.p.comp->mode != pies_comp_inetd) 2302 if (!list && prog->v.p.comp->mode != pies_comp_inetd)
@@ -2296,3 +2331,3 @@ progman_cleanup (int expect_term)
2296 struct prog *listener = prog->v.p.listener; 2331 struct prog *listener = prog->v.p.listener;
2297 2332
2298 listener->v.p.num_instances--; 2333 listener->v.p.num_instances--;
@@ -2309,3 +2344,3 @@ progman_cleanup (int expect_term)
2309 } 2344 }
2310 2345
2311 prog_stop_redirectors (prog); 2346 prog_stop_redirectors (prog);
@@ -2323,2 +2358,10 @@ progman_cleanup (int expect_term)
2323 } 2358 }
2359 else if (prog->v.p.comp->mode == pies_comp_startup)
2360 {
2361 debug (1, (_("removing startup component %s, pid=%lu"),
2362 prog_tag (prog), (unsigned long)pid));
2363 destroy_prog (&prog);
2364 if (!progman_startup_phase ())
2365 pies_schedule_children (PIES_CHLD_WAKEUP);
2366 }
2324 else 2367 else
@@ -2331,3 +2374,3 @@ progman_cleanup (int expect_term)
2331 prog->v.p.status = status_finished; 2374 prog->v.p.status = status_finished;
2332 2375
2333 if (prog->wait) 2376 if (prog->wait)
@@ -2353,3 +2396,3 @@ progman_cleanup (int expect_term)
2353 } 2396 }
2354 2397
2355 break; 2398 break;
@@ -2373,3 +2416,3 @@ progman_cleanup (int expect_term)
2373 } 2416 }
2374 2417
2375 if (!expect_term) 2418 if (!expect_term)
@@ -2391,3 +2434,3 @@ progman_stop_component (struct prog **progptr)
2391 break; 2434 break;
2392 2435
2393 case status_listener: 2436 case status_listener:
@@ -2415,3 +2458,3 @@ progman_stop_component (struct prog **progptr)
2415 break; 2458 break;
2416 2459
2417 case status_finished: 2460 case status_finished:
@@ -2443,3 +2486,3 @@ prog_activate_listener (struct prog *prog)
2443 struct component *comp = prog->v.p.comp; 2486 struct component *comp = prog->v.p.comp;
2444 2487
2445 logmsg (LOG_INFO, _("activating listener %s"), prog_tag (prog)); 2488 logmsg (LOG_INFO, _("activating listener %s"), prog_tag (prog));
@@ -2537,7 +2580,7 @@ progman_gc (void)
2537 } 2580 }
2538 2581
2539 /* FIXME: Report remaining programs */ 2582 /* FIXME: Report remaining programs */
2540 2583
2541} 2584}
2542 2585
2543/* EOF */ 2586/* 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)
25 mode_t omask = umask (*pumask); 25 mode_t omask = umask (*pumask);
26 26
27 if (setegid (*pgid)) 27 if ((*puid && *puid != ouid) || (*pgid && *pgid != ogid))
28 logmsg (LOG_ERR, _("cannot switch to EGID %lu: %s"), 28 {
29 (unsigned long) *pgid, strerror (errno)); 29 if (setegid (*pgid))
30 if (seteuid (*puid)) 30 logmsg (LOG_ERR, _("cannot switch to EGID %lu: %s"),
31 logmsg (LOG_ERR, _("cannot switch to EUID %lu: %s"), 31 (unsigned long) *pgid, strerror (errno));
32 (unsigned long) *puid, strerror (errno)); 32 if (seteuid (*puid))
33 logmsg (LOG_ERR, _("cannot switch to EUID %lu: %s"),
34 (unsigned long) *puid, strerror (errno));
35 }
33 *puid = ouid; 36 *puid = ouid;
@@ -53,3 +56,3 @@ create_socket (struct pies_url *url, int socket_type,
53 int switch_back; 56 int switch_back;
54 57
55 if (strcmp (url->scheme, "unix") == 0 58 if (strcmp (url->scheme, "unix") == 0
@@ -60,3 +63,3 @@ create_socket (struct pies_url *url, int socket_type,
60 const char *group = NULL; 63 const char *group = NULL;
61 64
62 user = url->user; 65 user = url->user;
@@ -101,3 +104,3 @@ create_socket (struct pies_url *url, int socket_type,
101 } 104 }
102 105
103 if (user) 106 if (user)
@@ -113,3 +116,3 @@ create_socket (struct pies_url *url, int socket_type,
113 } 116 }
114 117
115 if (group) 118 if (group)
@@ -124,3 +127,3 @@ create_socket (struct pies_url *url, int socket_type,
124 } 127 }
125 128
126 if (strlen (url->path) > sizeof addr.s_un.sun_path) 129 if (strlen (url->path) > sizeof addr.s_un.sun_path)
@@ -161,3 +164,3 @@ create_socket (struct pies_url *url, int socket_type,
161 short port = url->port; 164 short port = url->port;
162 165
163 uid = 0; 166 uid = 0;
@@ -168,3 +171,3 @@ create_socket (struct pies_url *url, int socket_type,
168 socklen = sizeof (addr.s_in); 171 socklen = sizeof (addr.s_in);
169 172
170 if (!host) 173 if (!host)
@@ -187,3 +190,3 @@ create_socket (struct pies_url *url, int socket_type,
187 break; 190 break;
188 191
189 default: 192 default:
@@ -200,3 +203,3 @@ create_socket (struct pies_url *url, int socket_type,
200 } 203 }
201 204
202 fd = socket (addr.sa.sa_family, socket_type, url->proto); 205 fd = socket (addr.sa.sa_family, socket_type, url->proto);
@@ -252,3 +255,3 @@ pass_fd0 (int fd, int payload)
252# endif /* ! CMSG_SPACE */ 255# endif /* ! CMSG_SPACE */
253 256
254 char control[CMSG_SPACE (sizeof (int))]; 257 char control[CMSG_SPACE (sizeof (int))];
@@ -292,3 +295,3 @@ pass_fd (const char *socket_name, int fd, unsigned maxtime)
292 struct sockaddr_un addr; 295 struct sockaddr_un addr;
293 296
294 if (strlen (socket_name) > sizeof addr.sun_path) 297 if (strlen (socket_name) > sizeof addr.sun_path)
@@ -300,3 +303,3 @@ pass_fd (const char *socket_name, int fd, unsigned maxtime)
300 strcpy (addr.sun_path, socket_name); 303 strcpy (addr.sun_path, socket_name);
301 304
302 for (;;) 305 for (;;)
@@ -364,3 +367,3 @@ pass_fd (const char *socket_name, int fd, unsigned maxtime)
364 struct timeval tv; 367 struct timeval tv;
365 368
366 FD_ZERO (&fds); 369 FD_ZERO (&fds);
@@ -432,3 +435,3 @@ calc_fd_max (void)
432void * 435void *
433register_socket (int fd, 436register_socket (int fd,
434 socket_handler_t rd, 437 socket_handler_t rd,
@@ -456,3 +459,3 @@ register_socket (int fd,
456 } 459 }
457 460
458 si_tail = sip; 461 si_tail = sip;
@@ -495,3 +498,3 @@ delete_sockinst (struct sockinst *sp)
495 fd_max = -1; 498 fd_max = -1;
496 499
497 if (sp->prev) 500 if (sp->prev)
@@ -574,3 +577,3 @@ pies_pause (void)
574 return; 577 return;
575 578
576 if (fd_max == -1) 579 if (fd_max == -1)
@@ -583,3 +586,3 @@ pies_pause (void)
583 fd_set exset = fdset[PIES_EVT_EX]; 586 fd_set exset = fdset[PIES_EVT_EX];
584 587
585 int rc = select (fd_max + 1, &rdset, &wrset, &exset, NULL); 588 int rc = select (fd_max + 1, &rdset, &wrset, &exset, NULL);
@@ -639,2 +642 @@ pies_pause (void)
639} }
640
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 @@
16 16
17EXTRA_DIST = $(TESTSUITE_AT) testsuite package.m4 respawn retcode mailer 17AUXTOOLS = \
18 aux/respawn\
19 aux/retcode\
20 aux/mailer\
21 aux/startup
22
23EXTRA_DIST = $(TESTSUITE_AT) testsuite package.m4 $(AUXTOOLS)
18DISTCLEANFILES = atconfig $(check_SCRIPTS) 24DISTCLEANFILES = atconfig $(check_SCRIPTS)
@@ -48,2 +54,3 @@ TESTSUITE_AT = \
48 ret-notify.at\ 54 ret-notify.at\
55 startup.at\
49 version.at 56 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
6XFAILFILE=$abs_builddir/.badversion 6XFAILFILE=$abs_builddir/.badversion
7 7auxdir="$abs_srcdir/aux"
8trimws() { 8trimws() {
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 @@
1#!/bin/sh
2dir=${1:?}
3time=${2:?}
4tag=${3:?}
5
6touch $dir/$tag
7sleep $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 {
26 mode respawn; 26 mode respawn;
27 command "$abs_srcdir/respawn -tag respawn -append -pid $comp_pid_file"; 27 command "$auxdir/respawn -tag respawn -append -pid $comp_pid_file";
28 stdout file "$outfile"; 28 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 {
25 mode respawn; 25 mode respawn;
26 command "$abs_srcdir/respawn -append -pid $comp_pid_file"; 26 command "$auxdir/respawn -append -pid $comp_pid_file";
27} 27}
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 {
28 return-code 10 { 28 return-code 10 {
29 exec "$abs_srcdir/retcode $report_file"; 29 exec "$auxdir/retcode $report_file";
30 action disable; 30 action disable;
31 } 31 }
32 command "$abs_srcdir/respawn -sleep 2 -pid $comp_pid_file -exit 10"; 32 command "$auxdir/respawn -sleep 2 -pid $comp_pid_file -exit 10";
33} 33}
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
24cat > pies.conf <<_EOT 24cat > pies.conf <<_EOT
25mailer-program "$abs_srcdir/mailer"; 25mailer-program "$auxdir/mailer";
26mailer-command-line "$abs_srcdir/mailer $report_file"; 26mailer-command-line "$auxdir/mailer $report_file";
27component test { 27component test {
@@ -32,3 +32,3 @@ component test {
32 } 32 }
33 command "$abs_srcdir/respawn -sleep 2 -exit 10"; 33 command "$auxdir/respawn -sleep 2 -exit 10";
34} 34}
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 @@
1# This file is part of GNU pies testsuite. -*- Autotest -*-
2# Copyright (C) 2019 Sergey Poznyakoff
3#
4# GNU pies is free software; you can redistribute it and/or modify
5# it under the terms of the GNU General Public License as published by
6# the Free Software Foundation; either version 3, or (at your option)
7# any later version.
8#
9# GNU pies is distributed in the hope that it will be useful,
10# but WITHOUT ANY WARRANTY; without even the implied warranty of
11# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12# GNU General Public License for more details.
13#
14# You should have received a copy of the GNU General Public License
15# along with GNU pies. If not, see <http://www.gnu.org/licenses/>.
16
17AT_SETUP([Startup components])
18
19AT_CHECK([
20PIES_XFAIL_CHECK
21PIES_CONTROL_INIT
22comp_pid_file=$PWD/comp.pid
23
24cat > pies.conf <<_EOT
25component b1 {
26 mode startup;
27 command "$auxdir/startup $PWD 1 b1";
28}
29
30component b2 {
31 mode startup;
32 command "$auxdir/startup $PWD 2 b2";
33}
34
35component test {
36 mode respawn;
37 command "$auxdir/respawn -append -pid $comp_pid_file";
38}
39_EOT
40
41pies --config-file control.conf --config-file pies.conf
42
43n=0
44res=
45b1=
46b2=
47while :
48do
49 echo "n=$n" >> tracefile
50 if test -z "$b1" && test -f b1; then
51 res="${res}b1"
52 b1=1
53 echo "got b1" >> tracefile
54 fi
55 if test -z "$b2" && test -f b2; then
56 res="${res}b2"
57 b2=1
58 echo "got b2" >> tracefile
59 fi
60 if test -f $comp_pid_file; then
61 echo "got pidfile" >> tracefile
62 res="${res}pid"
63 break
64 fi
65 sleep 1
66 n=$(($n + 1))
67 if test $n -gt 10; then
68 echo >&2 "timed out"
69 break
70 fi
71done
72
73PIES_STOP
74case $res in
75b1b2pid|b2b1pid) echo b1b2pid;;
76*) echo $res
77esac
78],
79[0],
80[b1b2pid
81])
82
83AT_CLEANUP
84
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])
67m4_include([ret-notify.at]) 67m4_include([ret-notify.at])
68m4_include([startup.at])

Return to:

Send suggestions and report system problems to the System administrator.