static void general_handler( int sig ) { sigset_t badsigs ; const char *func = "general_handler" ; /* * Do this here to catch problems like SIGSEGV in msg() */ sigemptyset( &badsigs ) ; sigaddset( &badsigs, sig ) ; (void) sigprocmask( SIG_UNBLOCK, &badsigs, SIGSET_NULL ) ; switch ( sig ) { case SIGBUS: case SIGSEGV: msg( LOG_CRIT, func, "(%d) Unexpected signal: %s", getpid(), sig_name( sig ) ) ; if ( debug.on ) { /* Generate a core dump */ signal(SIGABRT, SIG_DFL); abort(); } else bad_signal() ; break ; default: msg( LOG_NOTICE, func, "Unexpected signal %s", sig_name( sig ) ) ; if ( debug.on && sig == SIGINT ) exit( 1 ) ; } }
void check_pipe(void) { int i; #if NSIG < 256 unsigned char sig; #else int sig; #endif const char *func = "check_pipe"; if (signals_pending[0] < 0) return; if( ioctl(signals_pending[0], FIONREAD, &i) != 0 ) { msg(LOG_ERR, func, "Can't get the number of pending signals: %m"); return; } #if NSIG >= 256 i /= sizeof(int); #endif while( --i >= 0 ) { ssize_t ret_val; do { ret_val = read(signals_pending[0], &sig, sizeof(sig)); } while (ret_val == (ssize_t)-1 && errno == EINTR); if (ret_val != (ssize_t)sizeof(sig) ) { msg(LOG_ERR, func, "Error retrieving pending signal: %m"); return; } if( debug.on ) { msg(LOG_DEBUG, func, "Got signal %s", sig_name(sig)); } switch(sig) { case SERVER_EXIT_SIG: child_exit(); break; case RECONFIG_HARD_SIG: hard_reconfig(); break; case OLD_RECONFIG_HARD_SIG: hard_reconfig(); break; case TERMINATION_SIG: terminate_program(); break; case STATE_DUMP_SIG: dump_internal_state(); break; case CONSISTENCY_CHECK_SIG: user_requested_check(); break; case QUIT_SIG: quit_program(); break; default: msg(LOG_ERR, func, "unexpected signal: %s in signal pipe", sig_name(sig)); } } }
/* * Install signal handlers for all signals that can be caught. * This implies that no core dumps are generated by default. */ status_e signal_init(void) { int sig ; const char *func = "install_signal_handlers" ; sigemptyset( &reset_sigs ) ; if ( pipe(signals_pending) || fcntl(signals_pending[0], F_SETFD, FD_CLOEXEC) || fcntl(signals_pending[1], F_SETFD, FD_CLOEXEC) ) { msg( LOG_CRIT, func, "Failed to create signal pipe: %m" ); return( FAILED ); } for ( sig = 1 ;; sig++ ) if ( handle_signal( sig ) == FAILED ) { if ( errno == EINVAL ) { nsig = sig ; break ; } else { msg( LOG_CRIT, func, "Failed to install signal handler for signal %s: %m", sig_name( sig ) ) ; return( FAILED ) ; } } return( OK ) ; }
//------------------------------------------------------------------------------ sigset_t sig_members_parse(const string& a_signals, utxx::src_info&& a_si) { vector<string> signals; auto s = boost::to_lower_copy(a_signals); boost::split(signals, s, boost::is_any_of(":;,| "), boost::token_compress_on); sigset_t res; sigemptyset(&res); for (auto& s : signals) { if (s.empty()) continue; bool found = false; for (int i=1; i < 64; ++i) { auto signame = sig_name(i); if ((strcasecmp(s.c_str(), signame) == 0) || (s.size() > 3 && s.substr(0,3) != "sig" && strcasecmp(("sig" + s).c_str(), signame) == 0)) { sigaddset(&res, i); found = true; break; } } if (!found) UTXX_SRC_THROW(utxx::runtime_error, std::move(a_si), "Unrecognized signal name: ", s); } return res; }
//------------------------------------------------------------------------------ std::string sig_members(const sigset_t& a_set) { std::stringstream s; int n = 0; for (int i=1; i < 64; ++i) if (sigismember(&a_set, i)) { if (n++) s << '|'; s << sig_name(i); } return s.str(); }
int _sock_sig_setup (void) { volatile int sig; if (signal_depth > 0) return (0); if (++signal_depth > 1) return (0); _sock_start_timer(); wat_brkmode = wathndlcbrk; wathndlcbrk = 0; watcbroke = 0; sigalrm_caught = sigbrk_caught = 0; sigint_caught = sigquit_caught = 0; old_sigint = signal (SIGINT, sig_catch); #if defined(SIGQUIT) old_sigquit = signal (SIGQUIT, sig_catch); #endif #if defined(SIGBREAK) old_sigbrk = signal (SIGBREAK, sig_catch); #endif #if defined(SIGPIPE) old_sigpipe = signal (SIGPIPE, sig_catch); #endif #if defined(SIGALRM) && TRAP_SIGALRM old_sigalrm = signal (SIGALRM, sig_catch); block_sigalrm(); #endif sig = setjmp (sig_jmp); if (sig == 0) return (0); /* We'll get here only when sig_catch() calls longjmp() */ SOCK_DEBUGF ((NULL, ", interrupted by %s\n", sig_name(sig))); _sock_sig_restore(); return (-1); }
static void _kill (pid_t pid, int sig) { char buf[UINT_FMT]; unsigned int u; u = pid; buf[uint_fmt (buf, u)] = 0; aa_bs_noflush (AA_OUT, "kill("); if (u == (unsigned int) -1) aa_bs_noflush (AA_OUT, "-1"); else aa_bs_noflush (AA_OUT, buf); aa_bs_noflush (AA_OUT, ","); aa_bs_noflush (AA_OUT, sig_name (sig)); aa_bs_flush (AA_OUT, ")\n"); }
/* * Reset all signals to default action. Reset the signal mask * * This function is invoked from a forked process. That is why we * invoke _exit instead of exit (to avoid the possible stdio buffer flushes) */ void signal_default_state(void) { int sig ; sigset_t empty ; for ( sig = 1 ; sig < nsig ; sig++ ) if ( sigismember( &reset_sigs, sig ) == 1 ) if ( signal( sig, SIG_DFL ) == SIG_ERR ) { msg( LOG_ERR, "reset_signals", "signal failed for signal %s: %m", sig_name( sig ) ) ; if ( debug.on ) _exit( 1 ) ; } sigemptyset( &empty ) ; (void) sigprocmask( SIG_SETMASK, &empty, SIGSET_NULL ) ; }
static void signal_status(int signum) { shell_psignal(NULL, signum, " terminated your process", sig_name(signum)); }
static void stop_status(int signum) { shell_psignal(NULL, signum, " paused your process", sig_name(signum)); }
/* void catch_signal(int sig, int code, struct sigcontext *scp) { */ void catch_signal(int sig) { char *sptr; cStr *sigstr; cData arg1; Bool do_shutdown = NO; signal(sig, catch_signal); sptr = sig_name(sig); sigstr = string_from_chars(sptr, strlen(sptr)); write_err("Caught signal %d: %S", sig, sigstr); string_discard(sigstr); /* figure out what to do */ switch (sig) { #ifdef __UNIX__ case SIGHUP: atomic = NO; handle_connection_output(); flush_files(); #endif #ifndef __MSVC__ case SIGUSR2: /* let the db do what it wants from here */ break; case SIGUSR1: { cData *d; cList *l; /* First cancel all preempted and suspended tasks */ l = vm_list(); for (d = list_first(l); d; d = list_next(l, d)) { /* boggle */ if (d->type != INTEGER) continue; vm_cancel(d->u.val); } list_discard(l); /* now cancel the current task if it is valid */ if (vm_lookup(task_id) != NULL) { vm_cancel(task_id); } /* jump back to the main loop */ longjmp(main_jmp, 1); break; } #endif case SIGILL: /* lets panic and hopefully shutdown without frobbing the db */ panic(sig_name(sig)); break; case SIGTERM: if (running) { write_err("*** Attempting normal shutdown ***"); running = NO; /* jump back to the main loop, ignore any current tasks; *drip*, *drip*, leaky */ longjmp(main_jmp, 1); } else { panic(sig_name(sig)); } break; default: do_shutdown = YES; break; } /* only pass onto the db if we are 'executing' */ if (!running) return; /* send a message to the system object */ arg1.type = SYMBOL; arg1.u.symbol = ident_get(sptr); vm_task(SYSTEM_OBJNUM, signal_id, 1, &arg1); if (do_shutdown) running = NO; }