Minor changes.
authorAdam Dickmeiss <adam@indexdata.dk>
Wed, 3 May 1995 09:16:17 +0000 (09:16 +0000)
committerAdam Dickmeiss <adam@indexdata.dk>
Wed, 3 May 1995 09:16:17 +0000 (09:16 +0000)
kernel/monitor.c

index 84b5896..d1a0422 100644 (file)
@@ -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