X-Git-Url: http://git.indexdata.com/?a=blobdiff_plain;f=kernel%2Fmonitor.c;h=d1a0422c342dd5ae037846e64cf6c982a69b5c2e;hb=2ce3ad841cdc9c0254436a02b27ca9f0aef092e1;hp=84b5896bde6e3f35666578f9b1e7561ce0dc4eb9;hpb=e34e380795cac32a6a1d4ed126560c90a68301b3;p=egate.git diff --git a/kernel/monitor.c b/kernel/monitor.c index 84b5896..d1a0422 100644 --- a/kernel/monitor.c +++ b/kernel/monitor.c @@ -2,7 +2,10 @@ * Europagate, 1995 * * $Log: monitor.c,v $ - * Revision 1.5 1995/05/03 07:37:42 adam + * Revision 1.6 1995/05/03 09:16:17 adam + * Minor changes. + * + * Revision 1.5 1995/05/03 07:37:42 adam * CCL commands stop/continue implemented. New functions gw_res_{int,bool} * are used when possible. * @@ -58,8 +61,13 @@ static int no_process = 0; static int max_process = 1; static int got_sighup = 0; static int got_term = 0; +static int got_int = 0; const char *default_res = "default.res"; +/* + * reread_resources: reread monitor resources. The static variable, + * max_process, is updated. + */ static void reread_resources (void) { if (monitor_res) @@ -75,15 +83,21 @@ static void reread_resources (void) } struct ke_info { - pid_t pid; - int id; - GIP gip; - struct str_queue *queue; - struct ke_info *next; + int id; /* email user-id */ + pid_t pid; /* pid of email kernel child */ + GIP gip; /* fifo information */ + struct str_queue *queue; /* message queue */ + struct ke_info *next; /* link to next */ }; -struct ke_info *ke_info_list = NULL; +/* list of email kernel infos */ +static struct ke_info *ke_info_list = NULL; +/* + * ke_info_add: add/lookup of email kernel info. + * id: email user-id to search for. + * return: pointer to info structure. + */ struct ke_info *ke_info_add (int id) { struct ke_info **kip; @@ -111,6 +125,10 @@ static void ke_info_del (void) free (ki); } +/* + * catch_child: catch SIGCHLD. Set email kernel pid to -1 + * to indicate that child has exited + */ static void catch_child (int num) { pid_t pid; @@ -126,23 +144,48 @@ static void catch_child (int num) signal (SIGCHLD, catch_child); } +/* + * catch_int: catch SIGHUP. + */ static void catch_hup (int num) { got_sighup = 1; signal (SIGHUP, catch_hup); } +/* + * catch_int: catch SIGTERM. + */ static void catch_term (int num) { got_term = 1; signal (SIGTERM, catch_term); } +/* + * catch_int: catch SIGINT. + */ +static void catch_int (int num) +{ + got_int = 1; + signal (SIGINT, catch_int); +} + +/* + * pipe_handle: handle SIGPIPE when transferring message to kernel + */ static void pipe_handle (int dummy) { longjmp (retry_jmp, 1); } +/* + * start_kernel: start email kernel. + * argc: argc of email kernel + * argv: argv of email kernel + * id: email user-id + * return: pid of email kernel child + */ static pid_t start_kernel (int argc, char **argv, int id) { pid_t pid; @@ -179,6 +222,27 @@ static pid_t start_kernel (int argc, char **argv, int id) return pid; } +/* + * deliver: deliver message to child (email kernel). + * argc: exec argc to child (if it need to be started) + * argv: exec argv to child (if it need to be started) + * id: email userid + * queue: message queue to be transferred + * gip: pointer to FIFO info. if *gip is NULL prior invocation + * it will be created (initialized) and the pointer will be + * updated. + * pidp: pointer to pid. Will hold process-id of child (if it need to + * be started) + * dont_exec: if non-zero a child will never be started; otherwise child + * will be started if not already running. + * return: 0 if message couldn't be transferred, i.e. dont_exec is non-zero + * and the child is not already running. + * 1 if message was transferred and the child was already running. + * 2 if message was transferred and the child was started and + * dont_exec was zero. + * 3 serious error. Permissions denied or kernel couldn't be + * started at all. + */ static int deliver (int argc, char **argv, int id, struct str_queue *queue, GIP *gip, pid_t *pidp, int dont_exec) { @@ -201,55 +265,53 @@ static int deliver (int argc, char **argv, int id, struct str_queue *queue, setjmp (retry_jmp); ++pass; if (pass == 1) - { - gipc_close (*gip); - r = gipc_open (*gip, fifo_server_name, 0); + { /* assume child is running */ + gipc_close (*gip); /* shut down existing FIFOs */ + r = gipc_open (*gip, fifo_server_name, 0); /* try re-open ... */ } else if (pass == 2) - { + { /* assume child is NOT running */ pid_t pid; if (dont_exec) - { + { /* we aren't allowed to start */ signal (SIGPIPE, oldsig); return 0; } mknod (fifo_server_name, S_IFIFO|0666, 0); pid = start_kernel (argc, argv, id); - if (pidp) + if (pidp) /* set pid of child */ *pidp = pid; r = gipc_open (*gip, fifo_server_name, 1); } else - { + { /* message couldn't be transferred */ signal (SIGPIPE, oldsig); gw_log (GW_LOG_WARN, module, "Cannot start kernel"); - return 0; + return 3; } - if (r < 0) + if (r < 0) /* gipc_open fail? */ { if (r == -2) - { gw_log (GW_LOG_DEBUG|GW_LOG_ERRNO, module, "r==-2"); - longjmp (retry_jmp, 1); - } else if (r == -1) - { gw_log (GW_LOG_DEBUG|GW_LOG_ERRNO, module, "r==-1"); - longjmp (retry_jmp, 1); - } else - { gw_log (GW_LOG_WARN|GW_LOG_ERRNO, module, "gipc_open"); - } + longjmp (retry_jmp, 1); /* yet another pass */ } - index = 0; + index = 0; /* transfer. may be interrupted */ while ((msg = str_queue_get (queue, index++))) gip_wline (*gip, msg); signal (SIGPIPE, oldsig); - return pass; + return pass; /* successful transfer */ } +/* + * monitor_events: Event loop of monitor + * argc: argc of monitor (used in exec of Email kernel children) + * argv: argv of monitor (used in exec of Email kernel children) + */ static void monitor_events (int argc, char **argv) { GIP gip_m; @@ -283,6 +345,14 @@ static void monitor_events (int argc, char **argv) unlink (MONITOR_FIFO_C); exit (0); } + if (got_int) + { + gw_log (GW_LOG_STAT, module, "Got SIGINT. Exiting..."); + unlink (MONITOR_FIFO_S); + unlink (MONITOR_FIFO_C); + exit (0); + } + /* deliver any unsent messages to Email kernels */ for (ki = ke_info_list; ki; ki = ki->next) { if (!ki->queue) @@ -290,9 +360,9 @@ static void monitor_events (int argc, char **argv) gw_log (GW_LOG_DEBUG, module, "Transfer mail to %d", ki->id); r = deliver (argc, argv, ki->id, ki->queue, &ki->gip, &ki->pid, no_process >= max_process); - if (r == 2) + if (r == 2) /* new child was spawned? */ ++no_process; - if (r == 1 || r == 2) + if (r == 1 || r == 2) /* transfer at all? */ str_queue_rm (&ki->queue); } FD_ZERO (&set_r); @@ -306,14 +376,14 @@ static void monitor_events (int argc, char **argv) if (ki->gip) { if (ki->pid == -1) - { + { /* child has exited */ gw_log (GW_LOG_DEBUG, module, "Close of %d", ki->id); gipc_close (ki->gip); gipc_destroy (ki->gip); ki->gip = NULL; } else if ((fd = gip_infileno (ki->gip)) != -1) - { + { /* read select on child FIFO */ gw_log (GW_LOG_DEBUG, module, "set fd %d", fd); FD_SET (fd, &set_r); if (fd > fd_max) @@ -328,12 +398,14 @@ static void monitor_events (int argc, char **argv) if (r != -1) break; if (errno != EINTR) - { + { /* select aborted. And it was not due to interrupt */ gw_log (GW_LOG_FATAL|GW_LOG_ERRNO, module, "select"); exit (1); } + /* select was interrupted. Probably child has died */ gw_log (GW_LOG_DEBUG|GW_LOG_ERRNO, module, "select"); } + /* go through list of Email kernels. See if any message has arrived */ gw_log (GW_LOG_DEBUG, module, "Testing ke_info_list"); for (ki = ke_info_list; ki; ki = ki->next) { @@ -357,6 +429,7 @@ static void monitor_events (int argc, char **argv) } } } + /* see if any message from eti has arrived */ gw_log (GW_LOG_DEBUG, module, "Testing gip_m_fd %d", gip_m_fd); if (FD_ISSET (gip_m_fd, &set_r)) { @@ -396,6 +469,9 @@ static void monitor_events (int argc, char **argv) } } +/* + * main: main of monitor + */ int main (int argc, char **argv) { int argno = 0; @@ -428,6 +504,7 @@ int main (int argc, char **argv) signal (SIGCHLD, catch_child); signal (SIGHUP, catch_hup); signal (SIGTERM, catch_term); + signal (SIGINT, catch_int); #if 0 gw_log_file (GW_LOG_ALL, "monitor.log"); #endif