#include #include #include #include #include static void sig_alrm(int arg) { return; // nothing to do, just returning wakes up sigsuspend } unsigned int msec_sleep(unsigned int msec) { struct sigaction newact, oldact; sigset_t newmask, oldmask, suspmask; unsigned int unslept; struct itimerval itimer, itimerafter; newact.sa_handler = sig_alrm; sigemptyset(&newact.sa_mask); newact.sa_flags = 0; sigaction(SIGALRM, &newact, &oldact); sigemptyset(&newmask); sigaddset(&newmask, SIGALRM); sigprocmask(SIG_BLOCK, &newmask, &oldmask); itimer.it_interval.tv_sec = 0; itimer.it_interval.tv_usec = 0; itimer.it_value.tv_sec = msec / 1000; itimer.it_value.tv_usec = (msec % 1000) * 1000; setitimer(ITIMER_REAL, &itimer, 0); suspmask = oldmask; sigdelset(&suspmask, SIGALRM); sigsuspend(&suspmask); getitimer(ITIMER_REAL, &itimerafter); unslept = itimerafter.it_value.tv_sec * 1000 + itimerafter.it_value.tv_usec / 1000; sigaction(SIGALRM, &oldact, NULL); sigprocmask(SIG_SETMASK, &oldmask, NULL); return unslept; }