Added main rutines for killing and waiting for childs' dead.
--- a/signals.c Sun May 14 16:11:01 2006 +0200
+++ b/signals.c Sun May 14 16:11:32 2006 +0200
@@ -8,7 +8,7 @@
int result;
my_action.sa_handler = SIG_IGN;
- my_action.sa_flags = SA_NOCLDSTOP;
+ my_action.sa_flags = 0;
memset(&my_action.sa_mask, 0, sizeof(my_action.sa_mask));
result = sigaction(SIGHUP, &my_action, NULL);
@@ -27,3 +27,16 @@
result = sigaction(SIGCHLD, &my_action, NULL);
assert(result == 0);
}
+
+void program_handler(int signum, void (*handler)(int))
+{
+ struct sigaction my_action;
+ int result;
+
+ my_action.sa_handler = handler;
+ my_action.sa_flags = 0;
+ memset(&my_action.sa_mask, 0, sizeof(my_action.sa_mask));
+
+ result = sigaction(signum, &my_action, NULL);
+ assert(result == 0);
+}
--- a/syslog.h Sun May 14 16:11:01 2006 +0200
+++ b/syslog.h Sun May 14 16:11:32 2006 +0200
@@ -30,3 +30,4 @@
/* signals.c */
void program_child_handler(void (*child_handler)(int));
void program_ignore_hup();
+void program_handler(int signum, void (*handler)(int));
--- a/syslog_kernel.c Sun May 14 16:11:01 2006 +0200
+++ b/syslog_kernel.c Sun May 14 16:11:32 2006 +0200
@@ -14,12 +14,11 @@
#include "syslog.h"
/* Program names */
-const char syslog_in_unix[] = "syslog_in_unix";
-const char syslog_in_npipe[] = "syslog_in_npipe";
-const char syslog_in_udp[] = "syslog_in_udp";
+static const char syslog_in_unix[] = "syslog_in_unix";
+static const char syslog_in_npipe[] = "syslog_in_npipe";
+static const char syslog_in_udp[] = "syslog_in_udp";
/* Global variables */
-bool program_initialized = false;
enum echilds {
CHILD_NPIPE,
@@ -28,16 +27,23 @@
END_CHILDS
};
-struct {
+static struct {
int pid;
int input_pipe[2];
bool running;
} child[END_CHILDS];
+static int childs_alive = 0;
+
+/* Prototypes */
+static void term_childs();
+
+/* Code */
static void child_handler(int parameter)
{
pid_t pid;
int status;
+ enum echilds i;
do
{
@@ -48,6 +54,7 @@
{
/* We don't have more childs! */
fprintf(stderr, "We don't have more childs.\n");
+ childs_alive = 0;
break;
} else
{
@@ -57,16 +64,30 @@
}
}
/* Debug */
- if (WIFEXITED(status))
+ if (pid > 0)
{
- fprintf(stderr, "Child %i died fine:%i\n",
- pid, WEXITSTATUS(status));
- } else
- fprintf(stderr, "Child %i signaled strange: %08x\n",
+ fprintf(stderr, "Child %i died: 0x%08x\n",
pid, status);
+ /* We update the child status */
+ for(i=0;i<END_CHILDS;i++)
+ {
+ if(child[i].pid == pid)
+ {
+ child[i].running = false;
+ break;
+ }
+ }
+ childs_alive--;
+ }
} while(pid > 0);
}
+static void term_handler(int parameter)
+{
+ term_childs();
+}
+
+
static int run_program(const char * restrict programname,
const char * restrict parameter1, const int comm_pipe[])
{
@@ -91,6 +112,7 @@
{
fprintf(stderr, "Child forked(%s %s): %i\n",
programname, parameter1, pid);
+ childs_alive++;
return pid;
}
}
@@ -183,6 +205,7 @@
res_r = read(input_pipe[0], missatge, MESSAGE_LENGTH);
errno_r = errno;
+ res_w = 1; /* To bypass further error checking */
if (res_r > 0)
{
/* Add a ZERO for displaying */
@@ -202,7 +225,10 @@
}
else if (res_r == -1 && errno == EINTR)
/* The call was interrupted by a signal */
- continue;
+ if (childs_alive == 0)
+ break;
+ else
+ continue;
else /* End of read: res_r -1 or 0 */
break;
}
@@ -227,8 +253,49 @@
static void install_signal_handlers()
{
program_child_handler(child_handler);
+ program_handler(SIGTERM, term_handler);
}
+static void term_childs()
+{
+ enum echilds i;
+ int res;
+
+ /* Send SIGTERM */
+ for(i=0;i<END_CHILDS;i++)
+ {
+ if(child[i].running)
+ {
+ res = kill(child[i].pid, SIGTERM);
+ /* Accepting the res == -1 && errno == ESRCH saves us
+ * from the race condition possible kill error */
+ if (res == -1)
+ assert( errno == ESRCH );
+ }
+ }
+
+}
+
+static void wait_childs_die()
+{
+ /* the signal handler for SIGALRM should be restored here */
+ int total;
+ enum echilds i;
+
+ /* Wait for the end */
+ while(childs_alive > 0)
+ {
+ total=0;
+ for(i=0;i<END_CHILDS;i++)
+ {
+ if(child[i].running)
+ total++;
+ }
+ if (total == 0)
+ break;
+ sleep(1);
+ }
+}
int main(int argn, char *argv[])
{
@@ -237,4 +304,8 @@
init_config();
kernel_loop();
+
+ term_childs();
+
+ wait_childs_die();
}