Include <config.h> instead of "config.h".
[bpt/emacs.git] / lib-src / timer.c
index d49925f..c5265d5 100644 (file)
@@ -9,7 +9,7 @@
 
    This program is intended to be used with the lisp package called
    timer.el.  It was written anonymously in 1990.  This version was
-   documented and rewritten for portability by esr@snark,thyrsus.com,
+   documented and rewritten for portability by esr@snark.thyrsus.com,
    Aug 7 1992.  */
 
 #include <stdio.h>
 #include <fcntl.h>      /* FASYNC */
 #include <sys/types.h>  /* time_t */
 
-#include "../src/config.h"
+#include <../src/config.h>
 #ifdef USG
 #undef SIGIO
 #define SIGIO  SIGUSR1
 #endif
 
+#ifdef LINUX
+/* Perhaps this is correct unconditionally.  */
+#undef signal
+#endif
+
+
 extern int errno;
 extern char *sys_errlist[], *malloc ();
 extern time_t time ();
@@ -46,14 +52,14 @@ struct event *events;               /* events[0 .. num_events-1] are the
 
 char *pname;      /* programme name for error messages */
 
-/* Accepts a string of two fields seperated by FS.
-   First field is string for getdate, saying when to wake-up.
+/* Accepts a string of two fields separated by FS.
+   First field is string for get_date, saying when to wake-up.
    Second field is a token to identify the request.  */
 void
 schedule (str)
      char *str;
 {
-  extern time_t getdate ();
+  extern time_t get_date ();
   extern char *strcpy ();
   time_t now;
   register char *p;
@@ -121,9 +127,16 @@ schedule (str)
 void
 notify ()
 {
-  time_t now, tdiff, waitfor;
+  time_t now, tdiff, waitfor = -1;
   register struct event *ep;
 
+  /* If an alarm timer runs out while this function is executing,
+     it could get called recursively.  This would be bad, because
+     it's not re-entrant.  So we must try to suspend the signal. */
+#if 0   /* This function isn't right for BSD.  Fix it later.  */
+  sighold(SIGIO);
+#endif
+
   now = time ((time_t *) NULL);
 
   for (ep = events; ep < events + num_events; ep++)
@@ -137,8 +150,8 @@ notify ()
 
        /* We now have a hole in the event array; fill it with the last
           event.  */
-       ep->token = events[num_events].token;
-       ep->reply_at = events[num_events].reply_at;
+       ep->token = events[num_events - 1].token;
+       ep->reply_at = events[num_events - 1].reply_at;
        num_events--;
 
        /* We ought to scan this event again.  */
@@ -154,6 +167,10 @@ notify ()
   /* If there are no more events, we needn't bother setting an alarm.  */
   if (num_events > 0)
     alarm (waitfor);
+
+#if 0  /* This function isn't right for BSD.  */
+  sigrelse(SIGIO);
+#endif
 }
 
 void
@@ -213,7 +230,7 @@ getevent ()
   notify ();
 }
 
-void
+SIGTYPE
 sigcatch (sig)
      int sig;
 /* dispatch on incoming signal, then restore it */
@@ -262,10 +279,26 @@ main (argc, argv)
   signal (SIGTERM, sigcatch);
 
 #ifndef USG
-  fcntl (0, F_SETFL, FASYNC);
+  if (fcntl (0, F_SETOWN, getpid ()) == -1)
+    {
+      fprintf (stderr, "%s: can't set ownership of stdin\n", pname);
+      fprintf (stderr, "%s\n", sys_errlist[errno]);
+      exit (1);
+    }
+  if (fcntl (0, F_SETFL, fcntl (0, F_GETFL, 0) | FASYNC) == -1)
+    {
+      fprintf (stderr, "%s: can't request asynchronous I/O on stdin\n", pname);
+      fprintf (stderr, "%s\n", sys_errlist[errno]);
+      exit (1);
+    }
 #endif /* USG */
 
-  while (1) pause ();
+  /* In case Emacs sent some input before we set up
+     the handling of SIGIO, read it now.  */
+  kill (0, SIGIO);
+
+  for (;;)
+    pause ();
 }
 
 /* timer.c ends here */