.
[gnulib.git] / lib / nanosleep.c
index b833c01..42f179c 100644 (file)
 /* written by Jim Meyering */
 
 #include <config.h>
-
+#include <stdio.h>
 #include <sys/types.h>
+#include <signal.h>
+
+#include <errno.h>
+#ifndef errno
+extern int errno;
+#endif
+
+#if HAVE_UNISTD_H
+# include <unistd.h>
+#endif
 
 #include <time.h>
 /* FIXME: is including both like this kosher?  */
 #include <sys/time.h>
 
-static interrupted;
+static int suspended;
+int first_call = 1;
 
-/* Sleep for USEC microseconds. */
+/* Handle SIGCONT. */
 
 static void
-usleep (const struct timespec *ts_delay)
+sighandler (int sig)
+{
+  suspended = 1;
+}
+
+/* FIXME: comment */
+
+static void
+my_usleep (const struct timespec *ts_delay)
 {
   struct timeval tv_delay;
   tv_delay.tv_sec = ts_delay->tv_sec;
-  tv_delay.tv_usec = 1000 * ts_delay->tv_nsec;
-  select (0, (void *) 0, (void *) 0, (void *) 0, tv_delay);
+  tv_delay.tv_usec = ts_delay->tv_nsec / 1000;
+  select (0, (void *) 0, (void *) 0, (void *) 0, &tv_delay);
 }
 
+/* FIXME: comment */
+
 int
 nanosleep (const struct timespec *requested_delay,
           struct timespec *remaining_delay)
 {
-  interrupted = 0;
+#ifdef SA_INTERRUPT
+  struct sigaction oldact, newact;
+#endif
+
+  suspended = 0;
 
-  /* set up sig handler -- but maybe only do this the first time?  */
-  /* FIXME */
+  /* set up sig handler */
+  if (first_call)
+    {
+#ifdef SA_INTERRUPT
+      newact.sa_handler = sighandler;
+      sigemptyset (&newact.sa_mask);
+      newact.sa_flags = 0;
+
+      sigaction (SIGCONT, NULL, &oldact);
+      if (oldact.sa_handler != SIG_IGN)
+       sigaction (SIGCONT, &newact, NULL);
+#else
+      if (signal (SIGCONT, SIG_IGN) != SIG_IGN)
+       signal (SIGCONT, sighandler);
+#endif
+      first_call = 0;
+    }
 
-  usleep (requested_delay);
+  my_usleep (requested_delay);
 
-  if (interrupted)
+  if (suspended)
     {
       /* Calculate time remaining.  */
       /* FIXME: the code in sleep doesn't use this, so there's no
         rush to implement it.  */
+
+      errno = EINTR;
     }
 
   /* FIXME: Restore sig handler?  */
 
-  return interrupted;
+  return suspended;
 }