123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193 |
- #include <errno.h>
- #include <time.h>
- #include <signal.h>
- #include <unistd.h>
- #if defined __UCLIBC_HAS_REALTIME__
- # if 0
- unsigned int sleep (unsigned int sec)
- {
- unsigned int res;
- struct timespec ts = { .tv_sec = (long int) seconds, .tv_nsec = 0 };
- res = nanosleep(&ts, &ts);
- if (res) res = (unsigned int) ts.tv_sec + (ts.tv_nsec >= 500000000L);
- return res;
- }
- # else
- unsigned int sleep (unsigned int seconds)
- {
- struct timespec ts = { .tv_sec = (long int) seconds, .tv_nsec = 0 };
- sigset_t set;
- struct sigaction oact;
- unsigned int result;
-
- if (seconds == 0) {
- # ifdef CANCELLATION_P
- int cancelhandling;
- CANCELLATION_P (THREAD_SELF);
- # endif
- return 0;
- }
-
- __sigemptyset (&set);
- __sigaddset (&set, SIGCHLD);
-
- sigaction (SIGCHLD, NULL, &oact);
- if (oact.sa_handler == SIG_IGN) {
-
- sigprocmask (SIG_BLOCK, &set, &set);
- }
-
- result = nanosleep (&ts, &ts);
- if (result != 0) {
-
- result = (unsigned int) ts.tv_sec + (ts.tv_nsec >= 500000000L);
- }
- if (!__sigismember (&set, SIGCHLD)) {
-
-
- sigprocmask (SIG_SETMASK, &set, NULL);
- }
- return result;
- }
- # endif
- #else
- static void sleep_alarm_handler(int attribute_unused sig)
- {
- }
- unsigned int sleep (unsigned int seconds)
- {
- struct sigaction act, oact;
- sigset_t set, oset;
- unsigned int result, remaining;
- time_t before, after;
- int old_errno = errno;
-
- if (seconds == 0)
- return 0;
-
- __sigemptyset (&set);
- __sigaddset (&set, SIGALRM);
- sigprocmask (SIG_BLOCK, &set, &oset);
- act.sa_handler = sleep_alarm_handler;
- act.sa_flags = 0;
- act.sa_mask = oset;
- sigaction(SIGALRM, &act, &oact);
- before = time(NULL);
- remaining = alarm(seconds);
- if (remaining && remaining > seconds) {
-
- sigaction(SIGALRM, &oact, NULL);
- alarm(remaining);
- sigsuspend(&oset);
- after = time(NULL);
- } else {
- sigsuspend (&oset);
- after = time(NULL);
- sigaction (SIGALRM, &oact, NULL);
- }
- result = after - before;
- alarm(remaining > result ? remaining - result : 0);
- sigprocmask (SIG_SETMASK, &oset, NULL);
- __set_errno(old_errno);
- return result > seconds ? 0 : seconds - result;
- }
- #endif
- libc_hidden_def(sleep)
|