Back to index

glibc  2.9
sleep.c File Reference
#include <signal.h>
#include <time.h>
#include <unistd.h>
#include <errno.h>

Go to the source code of this file.


static void sleep_handler (int sig)
unsigned int __sleep (unsigned int seconds)

Function Documentation

unsigned int __sleep ( unsigned int  seconds)

Definition at line 41 of file sleep.c.

  unsigned int remaining, slept;
  time_t before, after;
  sigset_t set, oset;
  struct sigaction act, oact;
  int save = errno;

  if (seconds == 0)
    return 0;

  /* Block SIGALRM signals while frobbing the handler.  */
  if (sigemptyset (&set) < 0 ||
      sigaddset (&set, SIGALRM) < 0 ||
      sigprocmask (SIG_BLOCK, &set, &oset))
    return seconds;

  act.sa_handler = sleep_handler;
  act.sa_flags = 0;
  act.sa_mask = oset;       /* execute handler with original mask */
  if (sigaction (SIGALRM, &act, &oact) < 0)
    return seconds;

  before = time ((time_t *) NULL);
  remaining = alarm (seconds);

  if (remaining > 0 && remaining < seconds)
      /* The user's alarm will expire before our own would.
        Restore the user's signal action state and let his alarm happen.  */
      (void) sigaction (SIGALRM, &oact, (struct sigaction *) NULL);
      alarm (remaining);    /* Restore sooner alarm.  */
      sigsuspend (&oset);   /* Wait for it to go off.  */
      after = time ((time_t *) NULL);
      /* Atomically restore the old signal mask
        (which had better not block SIGALRM),
        and wait for a signal to arrive.  */
      sigsuspend (&oset);

      after = time ((time_t *) NULL);

      /* Restore the old signal action state.  */
      (void) sigaction (SIGALRM, &oact, (struct sigaction *) NULL);

  /* Notice how long we actually slept.  */
  slept = after - before;

  /* Restore the user's alarm if we have not already past it.
     If we have, be sure to turn off the alarm in case a signal
     other than SIGALRM was what woke us up.  */
  (void) alarm (remaining > slept ? remaining - slept : 0);

  /* Restore the original signal mask.  */
  (void) sigprocmask (SIG_SETMASK, &oset, (sigset_t *) NULL);

  /* Restore the `errno' value we started with.
     Some of the calls we made might have failed, but we didn't care.  */
  __set_errno (save);

  return slept > seconds ? 0 : seconds - slept;

Here is the call graph for this function:

static void sleep_handler ( int  sig) [static]

Definition at line 28 of file sleep.c.


Here is the caller graph for this function: