ssize_t vlc_write(int fd, const void *buf, size_t len) { struct iovec iov = { .iov_base = (void *)buf, .iov_len = len }; return vlc_writev(fd, &iov, 1); } ssize_t vlc_writev(int fd, const struct iovec *iov, int count) { sigset_t set, oset; sigemptyset(&set); sigaddset(&set, SIGPIPE); pthread_sigmask(SIG_BLOCK, &set, &oset); ssize_t val = writev(fd, iov, count); if (val < 0 && errno == EPIPE) { siginfo_t info; struct timespec ts = { 0, 0 }; while (sigtimedwait(&set, &info, &ts) >= 0 || errno != EAGAIN); } if (!sigismember(&oset, SIGPIPE)) /* Restore the signal mask if changed */ pthread_sigmask(SIG_SETMASK, &oset, NULL); return val; }
int main() { int signum=SIGRTMIN+1; sigset_t ss; sigemptyset(&ss); sigaddset(&ss,signum); sigaddset(&ss,SIGIO); sigprocmask(SIG_BLOCK,&ss,0); fcntl(0 /* fd */,F_SETOWN,getpid()); fcntl(0 /* fd */,F_SETSIG,signum); #if defined(O_ONESIGFD) && defined(F_SETAUXFL) fcntl(0 /* fd */, F_SETAUXFL, O_ONESIGFD); #endif fcntl(0 /* fd */,F_SETFL,fcntl(0 /* fd */,F_GETFL)|O_NONBLOCK|O_ASYNC); { siginfo_t info; struct timespec timeout; int r; timeout.tv_sec=1; timeout.tv_nsec=0; switch ((r=sigtimedwait(&ss,&info,&timeout))) { case SIGIO: /* signal queue overflow */ signal(signum,SIG_DFL); /* do poll */ break; default: if (r==signum) { printf("event %c%c on fd #%d\n",info.si_band&POLLIN?'r':'-',info.si_band&POLLOUT?'w':'-',info.si_fd); } } } return 0; }
// Отправка пакета адресату. bool NetHub::SendToAddress(ConnectionData &oConnectionData, bool bResetPointer) { int iLength; #ifndef WIN32 sigset_t ssOldset, ssNewset; siginfo_t sI; struct timespec tsTime = {0, 0}; sigset_t* p_ssNewset; // p_ssNewset = &ssNewset; sigemptyset(&ssNewset); sigaddset(&ssNewset, SIGPIPE); pthread_sigmask(SIG_BLOCK, &ssNewset, &ssOldset); iLength = (int)(p_chPocketsBufferPositionPointer - m_chPocketsBuffer); oConnectionData.iStatus = (int)send(oConnectionData.iSocket, (void*)m_chPocketsBuffer, (size_t)iLength, 0); #else iLength = (int)(p_chPocketsBufferPositionPointer - m_chPocketsBuffer); oConnectionData.iStatus = send(oConnectionData.iSocket, (const char*)m_chPocketsBuffer, (size_t)iLength, 0); #endif #ifndef WIN32 while(sigtimedwait(p_ssNewset, &sI, &tsTime) >= 0 || errno != EAGAIN); pthread_sigmask(SIG_SETMASK, &ssOldset, nullptr); #endif if(bResetPointer) ResetPocketsBufferPositionPointer(); if(oConnectionData.iStatus == -1) { return false; } return true; }
static void waittermsig(int sig, const char* waiter) { struct timespec ts = {.tv_sec = 1 }; sigset_t set; siginfo_t si; sigemptyset(&set); sigaddset(&set, sig); sigtimedwait(&set, &si, &ts); atomic_printf("FAILED: %s: signal %d either not caught or didn't terminate " "process within 1 second\n", waiter, sig); } static void* kill_thread(void* dontcare) { const int termsig = SIGTERM; atomic_puts("killing..."); kill(getpid(), termsig); waittermsig(termsig, "kill_thread"); return NULL; /* not reached */ } int main(int argc, char* argv[]) { pthread_t t; pthread_create(&t, NULL, kill_thread, NULL); pthread_join(t, NULL); atomic_puts("FAILED: joined thread that should have died"); return 0; }
/* * Another thread body for the pthread_kill + sigwait tests. */ void * sigwaiter(void *arg) { int rval; siginfo_t info; sigset_t set; oskit_timespec_t timeout = { 1, 0 }; pthread_cleanup_push(cleaner, arg); sigemptyset(&set); sigaddset(&set, SIGUSR1); pthread_sigmask(SIG_BLOCK, &set, 0); printf("sigwaiter:%d ready\n", (int) pthread_self()); while (1) { memset(&info, 0, sizeof(info)); if ((rval = sigtimedwait(&set, &info, &timeout)) != 0) oskit_error(rval, "sigwaiter"); printf("sigwaiter:%d rval:0x%x sig:%d code:%d val:%d\n", (int) pthread_self(), rval, info.si_signo, info.si_code, info.si_value.sival_int); oskit_pthread_sleep(20); } pthread_cleanup_pop(1); return 0; }
int sigsuspend( const sigset_t *sigmask ) { sigset_t saved_signals_blocked; sigset_t current_unblocked_signals; int status; POSIX_API_Control *api; api = _Thread_Executing->API_Extensions[ THREAD_API_POSIX ]; /* * We use SIG_BLOCK and not SIG_SETMASK because there may be * signals which might be pending, which might get caught here. * We want the signals to be caught inside sigtimedwait. */ status = sigprocmask( SIG_BLOCK, sigmask, &saved_signals_blocked ); current_unblocked_signals = ~(*sigmask); status = sigtimedwait( ¤t_unblocked_signals, NULL, NULL ); (void) sigprocmask( SIG_SETMASK, &saved_signals_blocked, NULL ); /* * sigtimedwait() returns the signal number while sigsuspend() * is supposed to return -1 and EINTR when a signal is caught. */ #if defined(RTEMS_DEBUG) assert( status != -1 ); #endif rtems_set_errno_and_return_minus_one( EINTR ); }
void Signal::wait() { sigset_t a, b; timespec t = {0, 0}; sigfillset(&a); sigprocmask(SIG_BLOCK, &a, NULL); sigemptyset(&a); sigaddset(&a, SIGTERM); sigaddset(&a, SIGINT); sigaddset(&a, SIGUSR1); sigemptyset(&b); sigaddset(&b, SIGTERM); sigaddset(&b, SIGINT); switch (sigwaitinfo(&a, NULL)) { case SIGUSR1: if (-1 == sigtimedwait(&b, NULL, &t)) break; case SIGINT: case SIGTERM: Logger::info("Terminate"); if (m_token) m_token->requestCancellation(); break; } }
int sigwaitinfo( const sigset_t *set, siginfo_t *info ) { return sigtimedwait( set, info, NULL ); }
int main (void) { sigset_t ensemble; int numero; struct timespec delai; fprintf(stderr, "PID=%ld\n", (long) getpid()); /* Blocage de tous les signaux */ sigfillset(& ensemble); sigprocmask(SIG_BLOCK, & ensemble, NULL); /* Attente de tous les signaux pendant 10 secondes */ delai.tv_sec = 10; delai.tv_nsec = 0; sigfillset(& ensemble); while (1) { if ((numero = sigtimedwait(& ensemble, NULL, & delai)) < 0) { perror("sigtimedwait"); break; } fprintf(stderr, "sigtimedwait : %d recu \n", numero); } return EXIT_SUCCESS; }
int main( int argc, char *argv[] ) { int result = 0; sigset_t waitset; siginfo_t info; struct timespec timeout; sigemptyset( &waitset ); sigaddset( &waitset, SIGALRM ); sigprocmask( SIG_BLOCK, &waitset, NULL ); timeout.tv_sec = 5; /* Number of seconds to wait */ timeout.tv_nsec = 1000; /* Number of nanoseconds to wait */ alarm(5); timestamp( "before sigtimedwait()" ); result = sigtimedwait( &waitset, &info, &timeout ); if( result < 0 ) { printf("sigtimedwait failed : \n"); exit(1); } printf( "sigtimedwait returned for signal %d\n",info.si_signo ); timestamp( "after sigtimedwait()" ); return( result ); }
void * time_cron(void *arg) { struct server *s = (struct server *) arg; struct timespec tv = { 0 }; sigset_t waitset; siginfo_t info; int ret; sigemptyset(&waitset); sigaddset(&waitset, SIGUSR1); // pthread_mutex_init(&gnlock, NULL); global_now = time(NULL); while (1) { tv.tv_sec = 1; tv.tv_nsec = 0; ret = sigtimedwait(&waitset, &info, &tv); if (ret > 0) s->refreshflag = 1; // pthread_mutex_lock(&gnlock); // global_now++; // pthread_mutex_unlock(&gnlock); //printf("time %lu\n",global_now); // if ((global_now % 100) == 0) { // pthread_mutex_lock(&gnlock); global_now = time(NULL); // pthread_mutex_unlock(&gnlock); // } } return NULL; }
int run_sigtimedwait(sigwait_params_t *params) { int ret = sigtimedwait(¶ms->waitset, ¶ms->info, ¶ms->timeout); if (-1 == ret && EAGAIN == errno) return 1; return 0; }
int sigwait(const sigset_t *mask, int *sig) { siginfo_t si; if (sigtimedwait(mask, &si, NULL) < 0) return -1; *sig = si.si_signo; return 0; }
static void do_test(int i) { pid_t cpid; cpid = tst_fork(); if (cpid < 0) tst_brkm(TBROK | TERRNO, cleanup, "fork() failed"); if (cpid == 0) do_child(i); fd = SAFE_OPEN(cleanup, "file", O_RDONLY); TEST(fcntl(fd, F_SETLEASE, test_cases[i].lease_type)); if (TEST_RETURN == -1) { tst_resm(TFAIL | TTERRNO, "fcntl() failed to set lease"); SAFE_WAITPID(cleanup, cpid, NULL, 0); SAFE_CLOSE(cleanup, fd); fd = 0; return; } /* Wait for SIGIO caused by lease breaker. */ TEST(sigtimedwait(&newset, NULL, &timeout)); if (TEST_RETURN == -1) { if (TEST_ERRNO == EAGAIN) { tst_resm(TFAIL | TTERRNO, "failed to receive SIGIO " "within %lis", timeout.tv_sec); SAFE_WAITPID(cleanup, cpid, NULL, 0); SAFE_CLOSE(cleanup, fd); fd = 0; return; } tst_brkm(TBROK | TTERRNO, cleanup, "sigtimedwait() failed"); } /* Try to downgrade or remove the lease. */ switch (test_cases[i].lease_type) { case F_WRLCK: TEST(fcntl(fd, F_SETLEASE, F_RDLCK)); if (TEST_RETURN == 0) break; case F_RDLCK: TEST(fcntl(fd, F_SETLEASE, F_UNLCK)); if (TEST_RETURN == -1) { tst_resm(TFAIL | TTERRNO, "fcntl() failed to remove the lease"); } break; default: break; } tst_record_childstatus(cleanup, cpid); SAFE_CLOSE(cleanup, fd); fd = 0; }
/* * Signal handler. * * This thread is reponsible for allowing switches between the * silent and verbose ttys, and for cleanup tasks after reception * of SIGTERM. */ void* thf_sighandler(void *unusued) { sigset_t sigset, sigset_switch; int sig; /* We don't handle SIGALRM. */ sigemptyset(&sigset); sigaddset(&sigset, SIGALRM); pthread_sigmask(SIG_BLOCK, &sigset, NULL); sigemptyset(&sigset); sigaddset(&sigset, SIGUSR1); sigaddset(&sigset, SIGUSR2); sigaddset(&sigset, SIGTERM); sigaddset(&sigset, SIGINT); sigemptyset(&sigset_switch); sigaddset(&sigset_switch, SIGUSR1); sigaddset(&sigset_switch, SIGUSR2); while (1) { sigwait(&sigset, &sig); process_switch_sig(sig); /* Internally generated terminate signal */ if (sig == SIGINT) { struct timespec timeout; timeout.tv_sec = 0; timeout.tv_nsec = 0; bool pending = true; /* * Process any remaining signals. There are no guarantees as to the * order in which the signals are delivered, so we have to make sure * all pending signals are processed before exiting. */ while (pending) { sig = sigtimedwait(&sigset_switch, NULL, &timeout); if (sig == -1) { /* No more pending signals. */ if (errno == EAGAIN) pending = false; } else { process_switch_sig(sig); } } do_cleanup(); pthread_exit(NULL); } else if (sig == SIGTERM) { do_cleanup(); exit(0); } } }
int main(int argc, char *argv[]) { struct server server; sigset_t sigset; siginfo_t siginfo; struct timespec tmo; { // setup server server.server_socket.addr = INADDR_ANY; server.server_socket.port = 8000; server.nrequest_max = 1024; server.nworker_min = 16; server.nworker_max = 32; server.nevent = 10; server.event_tmo = 10; if (server_init(&server)) { perror("server_init"); return -1; } } { // blocking all signals sigfillset(&sigset); if (pthread_sigmask(SIG_BLOCK, &sigset, NULL) != 0) { perror("pthread_sigmask"); return -1; } } server_startup(&server); { // signal handling tmo.tv_sec = 0; tmo.tv_nsec = 100000000; // 100 ms sigemptyset(&sigset); sigaddset(&sigset, SIGINT); sigfillset(&sigset); do { int signo = sigtimedwait(&sigset, &siginfo, &tmo); //int signo = sigwaitinfo(&sigset, &siginfo); if (signo == -1) { if (errno == EAGAIN || errno == EINTR) { continue; } perror("sigwaitinfo"); break; } //dispatch_signal(siginfo); printf("got signal %d\n", siginfo.si_signo); if (siginfo.si_signo == SIGINT) { printf("interrupted, quittingx\n"); break; } } while (1); } printf("shuting down\n"); server_shutdown(&server); return 0; }
static int wait_child(pid_t pid, int* status, int ms) { sigset_t set, oldset; struct sigaction act, oldact; struct timespec timeout; int ret = 0; /* Block SIGCHLD */ sigemptyset(&set); sigaddset(&set, SIGCHLD); sigprocmask(SIG_BLOCK, &set, &oldset); /* Register handler for SIGCHLD to ensure it is processed */ act.sa_handler = sigchld_handler; sigemptyset(&act.sa_mask); act.sa_flags = 0; sigaction(SIGCHLD, &act, &oldact); /* Check if the child already exited before we blocked the signal */ if (waitpid(pid, status, WNOHANG) == pid) { /* It did, so we are done */ ret = 0; goto done; } timeout.tv_sec = ms / 1000; timeout.tv_nsec = (ms % 1000) * 1000000; /* Otherwise, wait for it to exit with a timeout */ sigtimedwait(&set, NULL, &timeout); /* Check one more time for status */ if (waitpid(pid, status, WNOHANG) == pid) { /* It finally exited */ ret = 0; goto done; } else { /* Kill the thing and wait once more to reap the zombie process */ kill(pid, SIGKILL); waitpid(pid, NULL, 0); ret = -1; goto done; } done: /* Finally, restore old signal handler/signal masks */ sigprocmask(SIG_SETMASK, &oldset, NULL); sigaction(SIGCHLD, &oldact, NULL); return ret; }
static int fdevent_linux_rtsig_poll(fdevents * ev, int timeout_ms) { struct timespec ts; int r; #if 0 fdevent_linux_rtsig_event_compress(ev); #endif ev->in_sigio = 1; ts.tv_sec = timeout_ms / 1000; ts.tv_nsec = (timeout_ms % 1000) * 1000000; r = sigtimedwait(&(ev->sigset), &(ev->siginfo), &(ts)); if (r == -1) { if (errno == EAGAIN) return 0; return r; } else if (r == SIGIO) { struct sigaction act; /* * flush the signal queue */ memset(&act, 0, sizeof(act)); act.sa_handler = SIG_IGN; sigaction(ev->signum, &act, NULL); /* * re-enable the signal queue */ act.sa_handler = SIG_DFL; sigaction(ev->signum, &act, NULL); ev->in_sigio = 0; r = poll(ev->pollfds, ev->used, timeout_ms); return r; } else if (r == ev->signum) { # if 0 fprintf(stderr, "event: %d %02lx\n", ev->siginfo.si_fd, ev->siginfo.si_band); # endif return bitset_test_bit(ev->sigbset, ev->siginfo.si_fd); } else { /* * ? */ return -1; } }
int main(int argc, char *argv[]) { struct vme_sg_simple_time ttime, ttime2; int ttfd; /* File descriptor for the TrueTime device */ int i; int signo; setpriority(PRIO_PROCESS, (0), 100); if((ttfd = open("/dev/vme_sg_simple", O_RDWR, 0)) < 0) { perror("Can't open TrueTIme"); exit(-1); } timeout.tv_sec = 0; timeout.tv_nsec = 10000000; sigemptyset(&sigs); sigaddset(&sigs, SIGINT); for(i = 0; i < 10; i++) { #if 1 if(read(ttfd, &ttime, sizeof(ttime)) < 0) { perror("Trouble reading the truetime"); return(-1); } #endif #if TESTSIGTIMEDWAIT if((signo = sigtimedwait(&sigs, &extra, &timeout)) < 0) { switch(errno) { case EAGAIN: break; case EINTR: printf("Received SIGINT\n"); exit(0); case EINVAL: printf("invalid tv_nsec = %d\n", (int)timeout.tv_nsec); exit(1); } } else { printf("Signal %d arrived\n", signo); exit(0); } #if 1 if(read(ttfd, &ttime2, sizeof(ttime2)) < 0) { perror("Trouble reading the truetime"); return(-1); } printf("usec before %6d, after %6d\n", ttime.usec, ttime2.usec); for(signo = 0; signo < 240000; signo++) { } #endif #else printf("day = %d %d:%d:%d.%06d\n", ttime.yday, ttime.hour, ttime.min, ttime.sec, ttime.usec); usleep(10000); #endif } return(0); }
void *alpha_func(void *p) { omg1 = newOmega(); omg2 = newOmega(); omg3 = newOmega(); sigset_t ss; siginfo_t siginfo; int signum; sigemptyset(&ss); if (sigaddset(&ss, SIGUSR1) != 0) { return NULL; } if (sigprocmask(SIG_BLOCK, &ss, NULL)) { return NULL; } struct timespec interval; interval.tv_sec = 0; interval.tv_nsec = 500000000; pid_t pid = getpid(); printf("pid = %d\n", pid); while (1) { signum = sigtimedwait(&ss, &siginfo, &interval); if (signum >= 0) { switch (signum) { case SIGUSR1: puts("GET END SIGNAL"); return NULL; default: break; } } else if (signum == -1) { //printf("sigerrno = %d\n", siginfo.si_errno); if (errno == EAGAIN) { puts("Could not catch any signal in signal set while timeout."); continue; } if (errno == EINTR) { perror("Sigwait interrupted by another signal handler."); continue; } if (errno == EINVAL) { perror("Timeout value is invalid."); return NULL; } } else { perror("Unknown Error in alpha function."); return NULL; } } return NULL; }
void xt::Process::WaitForSignal(int signal, int timeout) { sigset_t signalMask; if (timeout >= 0) { static const uint32_t MsecToNsec = 1000000; static const uint32_t SecToMsec = 1000; int seconds = timeout / SecToMsec; /* Remove seconds from timeout */ timeout -= seconds * SecToMsec; struct timespec ts = { seconds, timeout * MsecToNsec }; sigemptyset(&signalMask); sigaddset(&signalMask, signal); int received = 0; do { errno = 0; received = sigtimedwait(&signalMask, NULL, &ts); if (received == -1) { /* Just retry if we got signalled */ if (errno != EINTR) { std::stringstream ss; ss << "sigtimedwait: " << strerror(errno); throw std::runtime_error(ss.str()); } } } while (errno != 0); return; } else { sigemptyset(&signalMask); sigaddset(&signalMask, signal); errno = 0; int received = sigwaitinfo(&signalMask, NULL); if (received != signal) { std::stringstream ss; ss << "sigwaitinfo: " << strerror(errno); } } }
int kill_and_wait_sigchild(pid_t child_pid, int signal, uint32_t timeout_seconds) { sigset_t sigs; struct timespec wait_timeout = {timeout_seconds, 0}; if (kill(child_pid, signal) == -1) { ERRMSG("kill() failed"); return -1; } if (sigemptyset(&sigs) == -1) { ERRMSG("sigemptyset() failed"); return -1; } if (sigaddset(&sigs, SIGCHLD) == -1) { ERRMSG("sigaddset() failed"); return -1; } if (sigtimedwait(&sigs, NULL, &wait_timeout) == -1) { if(errno != EAGAIN) { ERRMSG("sigtimedwait() failed"); } return -1; } return 0; }
int main() { struct sigaction act; sigset_t selectset; struct timespec ts; /* struct sigevent ev; timer_t tid; struct itimerspec its; its.it_interval.tv_sec = 0; its.it_interval.tv_nsec = 0; its.it_value.tv_sec = TIMERSEC; its.it_value.tv_nsec = 0; ev.sigev_notify = SIGEV_SIGNAL; ev.sigev_signo = TIMERSIGNAL; */ act.sa_flags=0; act.sa_handler=myhandler; sigemptyset(&act.sa_mask); sigaction(TIMERSIGNAL, &act, 0); sigemptyset(&selectset); sigaddset(&selectset, SIGTOTEST); ts.tv_sec=SIGTIMEDWAITSEC; ts.tv_nsec=0; /* if (timer_create(CLOCK_REALTIME, &ev, &tid) != 0) { perror("timer_create() did not return success\n"); return PTS_UNRESOLVED; } if (timer_settime(tid, 0, &its, NULL) != 0) { perror("timer_settime() did not return success\n"); return PTS_UNRESOLVED; } */ if (sigtimedwait(&selectset, NULL, &ts) != -1) { printf ("Test UNRESOLVED: sigtimedwait() did not return -1\n"); return PTS_UNRESOLVED; } if (errno != EAGAIN) { printf ("Test FAILED: sigtimedwait() did set errno to EAGAIN\n"); return PTS_FAIL; } printf("Test PASSED\n"); return PTS_PASS; }
size_t TcpSocketImpl::beginWrite(const char* buffer, size_t n) { log_debug("::send(" << _fd << ", buffer, " << n << ')'); #if defined(HAVE_MSG_NOSIGNAL) ssize_t ret = ::send(_fd, (const void*)buffer, n, MSG_NOSIGNAL); #elif defined(HAVE_SO_NOSIGPIPE) ssize_t ret = ::send(_fd, (const void*)buffer, n, 0); #else // block SIGPIPE sigset_t sigpipeMask, oldSigmask; sigemptyset(&sigpipeMask); sigaddset(&sigpipeMask, SIGPIPE); pthread_sigmask(SIG_BLOCK, &sigpipeMask, &oldSigmask); // execute send ssize_t ret = ::send(_fd, (const void*)buffer, n, 0); // clear possible SIGPIPE sigset_t pending; sigemptyset(&pending); sigpending(&pending); if (sigismember(&pending, SIGPIPE)) { static const struct timespec nowait = { 0, 0 }; while (sigtimedwait(&sigpipeMask, 0, &nowait) == -1 && errno == EINTR) ; } // unblock SIGPIPE pthread_sigmask(SIG_SETMASK, &oldSigmask, 0); #endif log_debug("send returned " << ret); if (ret > 0) return static_cast<size_t>(ret); if (ret == 0 || errno == ECONNRESET || errno == EPIPE) throw IOError("lost connection to peer"); if(_pfd) { _pfd->events |= POLLOUT; } return 0; }
int sigwaitinfo(FAR const sigset_t *set, FAR struct siginfo *info) { int ret; /* sigwaitinfo() is a cancellation point */ (void)enter_cancellation_point(); /* Just a wrapper around sigtimedwait() */ ret = sigtimedwait(set, info, NULL); leave_cancellation_point(); return ret; }
ATF_TC_BODY(sigtimedwait_small_timeout, tc) { sigset_t block; struct timespec ts; siginfo_t info; int r; sigemptyset(&block); ts.tv_sec = 5; ts.tv_nsec = 0; r = sigtimedwait(&block, &info, &ts); ATF_REQUIRE(r == -1); ATF_REQUIRE_ERRNO(EAGAIN, errno); }
void usleep(useconds_t usec) { sigset_t set; struct timespec ts; struct siginfo value; if (usec) { (void)sigemptyset(&set); ts.tv_sec = usec / 1000000; ts.tv_nsec = (usec % 1000000) * 1000; (void)sigtimedwait(&set, &value, &ts); } }
int abrt_oops_signaled_sleep(int seconds) { sigset_t set; sigemptyset(&set); sigaddset(&set, SIGTERM); sigaddset(&set, SIGINT); sigaddset(&set, SIGHUP); struct timespec timeout; timeout.tv_sec = seconds; timeout.tv_nsec = 0; return g_abrt_oops_sleep_woke_up_on_signal = sigtimedwait(&set, NULL, &timeout); }
void *info_thrd(void *arg) { sigset_t sigmask; struct timespec timespec = { .tv_sec = 1, .tv_nsec = 0 }; int sig, waiting = 0; sigemptyset(&sigmask); sigaddset(&sigmask, SIGQUIT); sigaddset(&sigmask, SIGHUP); while(1) { if(waiting) sig = sigtimedwait(&sigmask, NULL, ×pec); else sig = sigwaitinfo(&sigmask, NULL); if(sig == -1) { switch(errno) { case EAGAIN: /* interval timed out */ waiting = 0; /* FALLTHROUGH */ case EINTR: /* if waiting, the wait will be longer, but that's OK */ continue; default: BAD_ERROR("sigtimedwait/sigwaitinfo failed " "because %s\n", strerror(errno)); } } if(sig == SIGQUIT && !waiting) { if(pathname) INFO("%s\n", pathname); /* set one second interval period, if ^\ received within then, dump queue and cache status */ waiting = 1; } else dump_state(); } } void init_info() { pthread_create(&info_thread, NULL, info_thrd, NULL); }
unsigned int sleep(unsigned int seconds) { sigset_t set; struct timespec ts; struct siginfo value; if (seconds) { (void)sigemptyset(&set); ts.tv_sec = seconds; ts.tv_nsec = 0; (void)sigtimedwait(&set, &value, &ts); } return 0; }