/* Configures the program to die with SIGALRM 'secs' seconds from now, if * 'secs' is nonzero, or disables the feature if 'secs' is zero. */ void time_alarm(unsigned int secs) { sigset_t oldsigs; time_init(); block_sigalrm(&oldsigs); deadline = secs ? time_add(time_now(), secs) : TIME_MIN; unblock_sigalrm(&oldsigs); }
/* Like poll(), except: * * - On error, returns a negative error code (instead of setting errno). * * - If interrupted by a signal, retries automatically until the original * 'timeout' expires. (Because of this property, this function will * never return -EINTR.) * * - As a side effect, refreshes the current time (like time_refresh()). */ int time_poll(struct pollfd *pollfds, int n_pollfds, int timeout) { long long int start; sigset_t oldsigs; bool blocked; int retval; time_refresh(); start = time_msec(); blocked = false; for (;;) { int time_left; if (timeout > 0) { long long int elapsed = time_msec() - start; time_left = timeout >= elapsed ? timeout - elapsed : 0; } else { time_left = timeout; } retval = poll(pollfds, n_pollfds, time_left); if (retval < 0) { retval = -errno; } if (retval != -EINTR) { break; } if (!blocked && deadline == TIME_MIN) { block_sigalrm(&oldsigs); blocked = true; } time_refresh(); } if (blocked) { unblock_sigalrm(&oldsigs); } return retval; }
/* * Unhook signal-handlers and optionally chain to previous handlers * if we caught signals. */ void _sock_sig_restore (void) { if (signal_depth == 0) return; if (--signal_depth > 0) return; _sock_stop_timer(); watcbroke = 0; wathndlcbrk = wat_brkmode; #if defined(SIGALRM) && TRAP_SIGALRM signal (SIGALRM, old_sigalrm); unblock_sigalrm(); #if 0 /* don't do this since a socket function might be called from an * alarm handler. This could cause serious recursion and stack fault. */ if (sigalrm_caught && old_sigalrm != SIG_IGN && old_sigalrm != SIG_DFL) { sigalrm_caught = 0; (*old_sigalrm) (SIGALRM); } #endif #endif #if defined(SIGBREAK) signal (SIGBREAK, old_sigbrk); if (sigbrk_caught && old_sigbrk != SIG_IGN && old_sigbrk != SIG_DFL) { sigbrk_caught = 0; (*old_sigbrk) (SIGBREAK); } #endif #if defined(SIGPIPE) signal (SIGPIPE, old_sigpipe); if (sigpipe_caught) { if (old_sigpipe != SIG_IGN && old_sigpipe != SIG_DFL) { sigpipe_caught = 0; (*old_sigpipe) (SIGPIPE); } else { outsnl (_LANG("Terminating on SIGPIPE")); exit (-1); } } #endif #if defined(SIGQUIT) signal (SIGQUIT, old_sigquit); if (sigquit_caught) { if (old_sigquit != SIG_IGN && old_sigquit != SIG_DFL) { sigquit_caught = 0; (*old_sigquit) (SIGQUIT); } else { SOCK_DEBUGF ((NULL, "\nExiting stuck program")); exit (-1); } } #endif signal (SIGINT, old_sigint); if (sigint_caught && old_sigint != SIG_IGN && old_sigint != SIG_DFL) { sigint_caught = 0; (*old_sigint) (SIGINT); } sigalrm_caught = sigbrk_caught = 0; sigint_caught = sigquit_caught = 0; sigpipe_caught = 0; }