]> Pileus Git - ~andy/fetchmail/blobdiff - idle.c
Minor bug fixes for socket.c
[~andy/fetchmail] / idle.c
diff --git a/idle.c b/idle.c
index b3ecd503ad01ea9859fd5e716fb409a8d9d270b5..4ea21a3c4b4bfc74d712166b4fa900a2b4e3bf9c 100644 (file)
--- a/idle.c
+++ b/idle.c
@@ -1,23 +1,32 @@
-/*
- * idle.c -- pause code for fetchmail
- *
- * For license terms, see the file COPYING in this directory.
- */
-#include "config.h"
+/*****************************************************************************
+
+NAME:
+   idle.c -- code for interruptible delays without sleep(3).
+
+ENTRY POINTS:
+   interruptible_idle() -- delay for some time, interruptible by signal.
+
+THEORY:
+   Sometimes you need more than one time delay per program, so alarm(3)
+won't cut it.  This code illustrates time delays with select(2).
 
+AUTHOR:
+   Eric S. Raymond <esr@thyrsus.com>, 1997.  This source code example
+is part of fetchmail and the Unix Cookbook, and are released under the
+MIT license.  Compile with -DMAIN to build the demonstrator.
+
+******************************************************************************/
 #include <stdio.h>
-#if defined(STDC_HEADERS)
 #include <stdlib.h>
-#endif
-#if defined(HAVE_UNISTD_H)
 #include <unistd.h>
-#endif
 #include <signal.h>
 #include <errno.h>
-#include <sys/time.h>
+#include <fetchmail.h> /* for ROOT_UID */
 
-#include "fetchmail.h"
-#include "i18n.h"
+#ifndef TRUE
+#define TRUE 1
+#define FALSE 0
+#endif
 
 volatile int lastsig;          /* last signal received */
 
@@ -27,20 +36,15 @@ volatile int lastsig;               /* last signal received */
  * SIGALRM can hose the code (ALARM is triggered *before* pause() is called).
  * This is a bit of a kluge; the real right thing would use sigprocmask(),
  * sigsuspend().  This workaround lets the interval timer trigger the first
- * alarm after the required interval and will then generate alarms all 5
- * seconds, until it is certain, that the critical section (ie., the window)
- * is left.
+ * alarm after the required interval and will then generate alarms
+ * seconds until it is certain that the critical section (ie., the window)
+ * is exited.
  */
-#if defined(STDC_HEADERS)
 static sig_atomic_t    alarm_latch = FALSE;
-#else
-/* assume int can be written in one atomic operation on non ANSI-C systems */
-static int             alarm_latch = FALSE;
-#endif
 
 RETSIGTYPE gotsigalrm(int sig)
 {
-    signal(sig, gotsigalrm);
+    set_signal_handler(sig, gotsigalrm);
     lastsig = sig;
     alarm_latch = TRUE;
 }
@@ -63,24 +67,11 @@ void itimerthread(void* dummy)
 }
 #endif
 
-RETSIGTYPE donothing(int sig) {signal(sig, donothing); lastsig = sig;}
-
 int interruptible_idle(int seconds)
 /* time for a pause in the action; return TRUE if awakened by signal */
 {
     int awoken = FALSE;
 
-    /*
-     * With this simple hack, we make it possible for a foreground 
-     * fetchmail to wake up one in daemon mode.  What we want is the
-     * side effect of interrupting any sleep that may be going on,
-     * forcing fetchmail to re-poll its hosts.  The second line is
-     * for people who think all system daemons wake up on SIGHUP.
-     */
-    signal(SIGUSR1, donothing);
-    if (!getuid())
-       signal(SIGHUP, donothing);
-
 #ifndef __EMX__
 #ifdef SLEEP_WITH_ALARM                /* not normally on */
     /*
@@ -117,20 +108,19 @@ int interruptible_idle(int seconds)
     ntimeout.it_value.tv_sec  = seconds;
     ntimeout.it_value.tv_usec = 0;
 
-    siginterrupt(SIGALRM, 1);
     alarm_latch = FALSE;
-    signal(SIGALRM, gotsigalrm);       /* first trap signals */
+    set_signal_handler(SIGALRM, gotsigalrm);   /* first trap signals */
     setitimer(ITIMER_REAL,&ntimeout,NULL);     /* then start timer */
     /* there is a very small window between the next two lines */
     /* which could result in a deadlock.  But this will now be  */
-    /* caught by periodical alarms (see it_interval) */
+    /* caught by periodic alarms (see it_interval) */
     if (!alarm_latch)
        pause();
     /* stop timer */
     ntimeout.it_interval.tv_sec = ntimeout.it_interval.tv_usec = 0;
     ntimeout.it_value.tv_sec  = ntimeout.it_value.tv_usec = 0;
     setitimer(ITIMER_REAL,&ntimeout,NULL);     /* now stop timer */
-    signal(SIGALRM, SIG_IGN);
+    set_signal_handler(SIGALRM, SIG_IGN);
     }
 #else
     /* 
@@ -146,7 +136,7 @@ int interruptible_idle(int seconds)
     {
     struct timeval timeout;
 
-    timeout.tv_sec = run.poll_interval;
+    timeout.tv_sec = seconds;
     timeout.tv_usec = 0;
     do {
        lastsig = 0;
@@ -156,22 +146,34 @@ int interruptible_idle(int seconds)
 #endif
 #else /* EMX */
     alarm_latch = FALSE;
-    signal(SIGALRM, gotsigalrm);
+    set_signal_handler(SIGALRM, gotsigalrm);
     _beginthread(itimerthread, NULL, 32768, NULL);
     /* see similar code above */
     if (!alarm_latch)
        pause();
-    signal(SIGALRM, SIG_IGN);
+    set_signal_handler(SIGALRM, SIG_IGN);
 #endif /* ! EMX */
-    if (lastsig == SIGUSR1 || ((seconds && !getuid()) && lastsig == SIGHUP))
+    if (lastsig == SIGUSR1 || ((seconds && getuid() == ROOT_UID)
+       && lastsig == SIGHUP))
        awoken = TRUE;
 
     /* now lock out interrupts again */
-    signal(SIGUSR1, SIG_IGN);
-    if (!getuid())
-       signal(SIGHUP, SIG_IGN);
+    set_signal_handler(SIGUSR1, SIG_IGN);
+    if (getuid() == ROOT_UID)
+       set_signal_handler(SIGHUP, SIG_IGN);
 
     return(awoken ? lastsig : 0);
 }
 
+#ifdef MAIN
+int main(int argc, char **argv)
+{
+    for (;;)
+    {
+       printf("How may I serve you, master?\n");
+       interruptible_idle(5);
+    }
+}
+#endif /* MAIN */
+
 /* idle.c ends here */