/* Main executed at runtime */ int main(int argc, char ** argv){ // Declare Server and Socket HTTPserver httpServer; Socket sock; try{ // Sets the signals httpServer.setSignalHandler(); // Create socket sock.createSocket(argc, argv); // Start server with Socket object httpServer.runThreaded(sock); } catch (int signal){ // Create signal message and log it stringstream message; message << "Signal received: " << strsignal(signal) << " - " << signal << flush; // Output to console and log cout << message.str() << endl << flush; httpServer.logWrite(message.str()); } catch (exception &e){ // Create Error message stringstream message; message << "Fatal Exception: "<< e.what(); // Output to cerr and log cerr << message.str() << endl << flush; httpServer.logWrite(message.str()); } return (0); }
void VMBase::Free() { if (syscallLogFile) { std::error_code err; syscallLogFile.Close(err); } if (!IsActive()) return; // First send a message signaling an exit to the VM // then delete the socket. This is needed because // recvmsg in NaCl doesn't return when the socket has // been closed. Util::Writer writer; writer.Write<uint32_t>(IPC::ID_EXIT); rootChannel.SendMsg(writer); rootChannel = IPC::Channel(); if (type != TYPE_NATIVE_DLL) { #ifdef _WIN32 // Closing the job object should kill the child process CloseHandle(processHandle); #else int status; if (waitpid(processHandle, &status, WNOHANG) != 0) { if (WIFSIGNALED(status)) Log::Warn("VM exited with signal %d: %s\n", WTERMSIG(status), strsignal(WTERMSIG(status))); else if (WIFEXITED(status)) Log::Warn("VM exited with non-zero exit code %d\n", WEXITSTATUS(status)); } kill(processHandle, SIGKILL); waitpid(processHandle, nullptr, 0); #endif processHandle = Sys::INVALID_HANDLE; } else { FreeInProcessVM(); } }
/******************************************************************* * reaper - clean up zombie children *******************************************************************/ void reaper(int sig) { pid_t cpid; #if defined(SOLARIS) || defined(AIX) || defined(LINUX) int status; #else union wait status; #endif /* SOLARIS */ while ((cpid = wait3(&status, WNOHANG, (struct rusage *) 0)) > 0) { #ifdef PRE_FORK int i; #endif server->child++; #ifdef PRE_FORK for (i = 0; i < server->max_child; i++) { if ((server->childs)[i].pid == cpid) { (server->childs)[i].pid = 0x00; (server->childs)[i].status = S_ERROR; server->error++; #ifdef WEB_ERROR_LOG #if 1 request_rec->atime = time(0); xstrncpy(request_rec->fromhost, "127.0.0.1", HOSTLEN); #endif weblog_line(server->error_log, "ERR=\"Child unexpected return, pid=%d, status=%d (%s)\"", (int) cpid, (int) status, strsignal(status)); fflush(server->error_log); #endif } } #endif } (void) signal(SIGCHLD, reaper); /* 再度啟動 signal 接收 */ }
int main(int argc, char* argv[]) { pid_t child,waitsig; int status; printf("Fork now!\n"); child = fork(); if(child == 0) { printf("My parent's PID is %d\n",getppid()); execl(argv[1],NULL); } else { do { waitsig = waitpid(-1, &status, WNOHANG); if (waitsig == -1) { printf("Child Process error!!\n"); } if (WIFEXITED(status)) { printf("--------Child Exited--------\n"); printf("exited, status=%d\n", WEXITSTATUS(status)); } else if (WIFSIGNALED(status)) { printf("--------Something Wrong--------\n"); printf("%s\n", strsignal(WTERMSIG(status))); } else if (WIFSTOPPED(status)) { printf("stopped by signal %d\n", WSTOPSIG(status)); } } while (!WIFEXITED(status) && !WIFSIGNALED(status)); } return 0; }
void ah_crap_handler(int signum) { printf("prog = %s\npid = %d\nsignal = %s\n", _progname, getpid(), strsignal(signum)); printf("stack logged to someplace\n"); nsTraceRefcntImpl::WalkTheStack(stdout); printf("Sleeping for 5 minutes.\n"); printf("Type 'gdb %s %d' to attach your debugger to this thread.\n", _progname, getpid()); sleep(300); printf("Done sleeping...\n"); }
void cwSighandInit(int * lastsig_ptr) { int rc; unsigned i; struct sigaction handler; memset(&handler, 0, sizeof(handler)); handler.sa_sigaction = &cwSighandHandler; handler.sa_flags = SA_SIGINFO | SA_RESTART; for (i=0; i<SIGCT; ++i) { rc = sigaction(cwSighandSig[i], &handler, &cwSighandOldact[i]); if (rc != 0) { cwMsg("sighand_init: sigaction %s(%d) failed %s(%d)", strsignal(cwSighandSig[i]), cwSighandSig[i], strerror(errno), errno); raise(SIGTERM); } } cwSighandLastsigPtr = lastsig_ptr; if (cwSighandLastsigPtr) *cwSighandLastsigPtr = 0; return; }
static void handler(int sig) { /* UNSAFE: This handler uses non-async-signal-safe functions (printf(), strsignal(), printSigMask(); see Section 21.1.2) */ printf("Received signal %d (%s), signal mask is:\n", sig, strsignal(sig)); printSigMask(stdout, NULL); if (!canJump) { printf("'env' buffer not yet set, doing a simple return\n"); return; } #ifdef USE_SIGSETJMP siglongjmp(senv, 1); #else longjmp(env, 1); #endif }
extern "C" void signalHandler(int signal) { #ifdef Q_WS_X11 // Kill window since it's frozen anyway. if (QX11Info::display()) close(ConnectionNumber(QX11Info::display())); #endif pid_t pid = fork(); switch (pid) { case -1: // error break; case 0: // child execl(crashHandlerPathC, crashHandlerPathC, strsignal(signal), (char *) 0); _exit(EXIT_FAILURE); default: // parent prctl(PR_SET_PTRACER, pid, 0, 0, 0); waitpid(pid, 0, 0); _exit(EXIT_FAILURE); break; } }
static RETSIGTYPE fatal_signal_handler(int a) { struct sigaction act; logger(LOG_ERR, "Got fatal signal %d (%s)", a, strsignal(a)); if(do_detach) { logger(LOG_NOTICE, "Trying to re-execute in 5 seconds..."); act.sa_handler = fatal_signal_square; act.sa_mask = emptysigset; act.sa_flags = 0; sigaction(SIGSEGV, &act, NULL); close_network_connections(); sleep(5); remove_pid(pidfilename); execvp(g_argv[0], g_argv); } else { logger(LOG_NOTICE, "Not restarting."); exit(1); } }
static void s_video_helper_kbd_signal_handler (int v) { int i; s_video_helper_kbd_uninit(); s_server_quit(xynth_server->window); debugf(DSER, "Signal %d: %s received %s", v, strsignal(v), (v == SIGINT) ? "(ctrl-alt-backspace or ctrl-c pressed)" : ""); for (i = 0; i < sizeof(s_video_helper_keybd_sig2catch); i++) { if (s_video_helper_keybd_sig2catch[i] == v) { sigaction(v, s_video_helper_keybd.old_signal_handler + i, NULL); raise(v); break; } } if (i >= sizeof(s_video_helper_keybd_sig2catch)) { debugf(DSER, "Illegal call to signal_handler, raising segfault"); raise(SIGSEGV); } }
void crit_err_hdlr(int sig_num, siginfo_t * info, void * ucontext) { void * array[50]; void * caller_address; char ** messages; int size, i; sig_ucontext_t * uc; uc = (sig_ucontext_t *)ucontext; /* Get the address at the time the signal was raised */ #if defined(__i386__) // gcc specific caller_address = (void *) uc->uc_mcontext.eip; // EIP: x86 specific #elif defined(__x86_64__) // gcc specific caller_address = (void *) uc->uc_mcontext.rip; // RIP: x86_64 specific #else #error Unsupported architecture. // TODO: Add support for other arch. #endif fprintf(stderr, "signal %d (%s), address is %p from %p\n", sig_num, strsignal(sig_num), info->si_addr, (void *)caller_address); size = backtrace(array, 50); /* overwrite sigaction with caller's address */ array[1] = caller_address; messages = backtrace_symbols(array, size); /* skip first stack frame (points here) */ for (i = 1; i < size && messages != NULL; ++i) { fprintf(stderr, "[bt]: (%d) %s\n", i, messages[i]); } free(messages); exit(EXIT_FAILURE); }
/* * Hunt down processes that have files open at the given mount point. */ void Process::killProcessesWithOpenFiles(const char *path, int signal) { DIR* dir; struct dirent* de; if (!(dir = opendir("/proc"))) { SLOGE("opendir failed (%s)", strerror(errno)); return; } while ((de = readdir(dir))) { int pid = getPid(de->d_name); char name[PATH_MAX]; if (pid == -1) continue; getProcessName(pid, name, sizeof(name)); char openfile[PATH_MAX]; if (checkFileDescriptorSymLinks(pid, path, openfile, sizeof(openfile))) { SLOGE("Process %s (%d) has open file %s", name, pid, openfile); } else if (checkFileMaps(pid, path, openfile, sizeof(openfile))) { SLOGE("Process %s (%d) has open filemap for %s", name, pid, openfile); } else if (checkSymLink(pid, path, "cwd")) { SLOGE("Process %s (%d) has cwd within %s", name, pid, path); } else if (checkSymLink(pid, path, "root")) { SLOGE("Process %s (%d) has chroot within %s", name, pid, path); } else if (checkSymLink(pid, path, "exe")) { SLOGE("Process %s (%d) has executable path within %s", name, pid, path); } else { continue; } if (signal != 0) { SLOGW("Sending %s to process %d", strsignal(signal), pid); kill(pid, signal); } } closedir(dir); }
int main(int argc, char *argv[]) { (void) argc; (void) argv; sigset_t mask; struct signalfd_siginfo info; sigemptyset(&mask); sigaddset(&mask, SIGHUP); sigaddset(&mask, SIGINT); sigaddset(&mask, SIGQUIT); sigaddset(&mask, SIGTERM); sigprocmask(SIG_BLOCK, &mask, nullptr); kill(getpid(), SIGQUIT); kill(getpid(), SIGINT); kill(getpid(), SIGTERM); kill(getpid(), SIGHUP); auto sfd = fd::signalfd(mask, SFD_NONBLOCK); while (1) { try { sfd.read(info); std::cout << "Signal: " << strsignal(info.ssi_signo) << '\n'; } catch (std::system_error &e) { if (e.code().value() == EAGAIN) break; throw e; } } std::cout << "Ok\n"; return 0; }
static void * sigsuspender (void *arg) { int save_count, status, i; sigset_t run_mask; SET_NAME("sigsuspender"); /* Run with all signals blocked. */ sigfillset (&run_mask); CHECKe(sigprocmask (SIG_SETMASK, &run_mask, NULL)); /* Allow these signals to wake us up during a sigsuspend. */ sigfillset (&suspender_mask); /* Default action */ sigdelset (&suspender_mask, SIGINT); /* terminate */ sigdelset (&suspender_mask, SIGHUP); /* terminate */ sigdelset (&suspender_mask, SIGQUIT); /* create core image */ sigdelset (&suspender_mask, SIGURG); /* ignore */ sigdelset (&suspender_mask, SIGIO); /* ignore */ sigdelset (&suspender_mask, SIGUSR2); /* terminate */ sigdelset (&suspender_mask, SIGSTOP); /* unblockable */ sigdelset (&suspender_mask, SIGKILL); /* unblockable */ while (sigcounts[SIGINT] == 0) { save_count = sigcounts[SIGUSR2]; status = sigsuspend (&suspender_mask); if ((status == 0) || (errno != EINTR)) { DIE(errno, "Unable to suspend for signals, " "return value %d\n", status); } for (i = 0; i < fifo_depth; i++) printf ("Sigsuspend woke up by signal %d (%s)\n", sigfifo[i], strsignal(sigfifo[i])); fifo_depth = 0; } return (arg); }
static void firmware_preparation_termination(struct io_process *process, pid_t pid, int status) { int ret; struct firmware_preparation *firmware_preparation; struct preparation *preparation; struct firmware *firmware; firmware_preparation = ut_container_of(process, struct firmware_preparation, process); io_mon_remove_source(firmwared_get_mon(), io_process_get_src(&firmware_preparation->process)); preparation = &firmware_preparation->preparation; if (status != 0) { if (WIFSIGNALED(status)) { ULOGD("curl hook terminated on signal %s", strsignal(WTERMSIG(status))); } else { if (WTERMSIG(status) != SIGUSR1) { ULOGE("curl hook error, use absolute paths"); ret = -EINVAL; goto err; } } } /* TODO the following may block a long time */ firmware = firmware_new(firmware_preparation->destination_file); preparation->completion(preparation, &firmware->entity); return; err: firmwared_notify(FWD_ANSWER_ERROR, FWD_FORMAT_ANSWER_ERROR, preparation->seqnum, -ret, strerror(-ret)); preparation->completion(preparation, NULL); }
TEST(string, strsignal) { // A regular signal. ASSERT_STREQ("Hangup", strsignal(1)); // A real-time signal. #ifdef __GLIBC__ // glibc reserves real-time signals for internal use, and doesn't count those. ASSERT_STREQ("Real-time signal 14", strsignal(48)); #else ASSERT_STREQ("Real-time signal 16", strsignal(48)); #endif // Errors. ASSERT_STREQ("Unknown signal -1", strsignal(-1)); // Too small. ASSERT_STREQ("Unknown signal 0", strsignal(0)); // Still too small. ASSERT_STREQ("Unknown signal 1234", strsignal(1234)); // Too large. }
// Signal handler that simply dumps the stack and then crashes out. void signal_handler(int sig) { // Reset the signal handlers so that another exception will cause a crash. signal(SIGABRT, SIG_DFL); signal(SIGSEGV, signal_handler); // Log the signal, along with a backtrace. TRC_BACKTRACE("Signal %d caught", sig); // Ensure the log files are complete - the core file created by abort() below // will trigger the log files to be copied to the diags bundle TRC_COMMIT(); // Check if there's a stored jmp_buf on the thread and handle if there is exception_handler->handle_exception(); CL_HOMESTEAD_CRASH.log(strsignal(sig)); closelog(); // Dump a core. abort(); }
/* reset signal handling... */ void reset_sighandler(void) { size_t i; /* set signal handling to default actions */ int signals[] = { SIGQUIT, SIGTERM, SIGHUP, SIGPIPE, SIGXFSZ, SIGUSR1, SIGINT }; for (i = 0; i < sizeof(signals) / sizeof(signals[0]); ++i) { if (signal(signals[i], SIG_DFL) == SIG_ERR) { nm_log(NSLOG_RUNTIME_ERROR, "Failed to reset signal handler for %s: %s", strsignal(signals[i]), strerror(errno)); } } }
/** sighandler - signal handler for catching signal and exiting cleanly */ static void sighandler(int sig) { static int quit = 0; fprintf(stderr, "%s %s (%d)\n", __func__, strsignal(sig), sig); switch (sig) { // quit case SIGINT: case SIGQUIT: if (quit++ == 0) { g_main_loop_quit(loop); return; } break; // ignore case SIGHUP: return; break; } exit(1); }
int subproc_check(int status, const char *desc, int flags) { void (*out)(const char *fmt, ...) DPKG_ATTR_PRINTF(1); int n; if (flags & PROCWARN) out = warning; else out = ohshit; if (WIFEXITED(status)) { n = WEXITSTATUS(status); if (!n) return 0; if (flags & PROCNOERR) return n; out(_("subprocess %s returned error exit status %d"), desc, n); } else if (WIFSIGNALED(status)) { n = WTERMSIG(status); if (!n) return 0; if ((flags & PROCPIPE) && n == SIGPIPE) return 0; if (n == SIGINT) out(_("subprocess %s was interrupted"), desc); else out(_("subprocess %s was killed by signal (%s)%s"), desc, strsignal(n), WCOREDUMP(status) ? _(", core dumped") : ""); } else { out(_("subprocess %s failed with wait status code %d"), desc, status); } return -1; }
int runExecutable() { assert(!gExePath.isEmpty()); assert(gExePath.isValid()); // build arguments std::vector<const char*> args; // args[0] should be the name of the executable args.push_back(gExePath.c_str()); // Skip first argument to -run; it's a D source file. for (size_t i = 1, length = opts::runargs.size(); i < length; i++) { args.push_back(opts::runargs[i].c_str()); } // terminate args list args.push_back(NULL); // try to call linker!!! std::string errstr; int status = llvm::sys::Program::ExecuteAndWait(gExePath, &args[0], NULL, NULL, 0,0, &errstr); if (status < 0) { #if defined(_MSC_VER) error("program received signal %d", -status); #else error("program received signal %d (%s)", -status, strsignal(-status)); #endif return -status; } if (!errstr.empty()) { error("failed to execute program"); if (!errstr.empty()) error("error message: %s", errstr.c_str()); fatal(); } return status; }
static void handle_sigchld(int signal, siginfo_t *siginfo, void *data) { int pid, status; pid = waitpid(-1, &status, WNOHANG); if (pid <= 0) return; pr_err("si_code=%d si_pid=%d si_status=%d\n", siginfo->si_code, siginfo->si_pid, siginfo->si_status); if (WIFEXITED(status)) pr_err("%d exited with %d unexpectedly\n", pid, WEXITSTATUS(status)); else if (WIFSIGNALED(status)) pr_err("%d was killed by %d unexpectedly: %s\n", pid, WTERMSIG(status), strsignal(WTERMSIG(status))); else if (WIFSTOPPED(status)) pr_err("%d was stopped by %d unexpectedly\n", pid, WSTOPSIG(status)); /* FIXME Should we exit? */ /* exit(1); */ }
void *thr_receive(void *arg) { int err, signo; while(1) { err = sigwait(&g_mask, &signo); if (err != 0) { perror("sigwait failed\n"); exit(1); } switch (signo) { case SIGIO: pthread_mutex_lock(&g_lock); printf("In child thread: received signal %s!!\n",strsignal(signo)); g_rcv_flag = 1; #if MY_DEBUG == MY_DEBUG_WR char *filename = "/dev/"__DEVICE_NAME__; int fd = open(filename,O_RDONLY); char buf[10] = {0,}; read(fd,buf,sizeof(buf)); printf("read from device:%s",buf); #elif MY_DEBUG == MY_DEBUG_SR //receive(g_usr_vir_addr, receivebuf, receivelen); #else #endif pthread_mutex_unlock(&g_lock); pthread_cond_signal(&g_wait); return(0); default: printf("In child thread: unexpected signal %d\n",signo); exit(1); } } return((void *)0); }
static void sig_catcher(int sig) { #if !defined(NDEBUG) if (!no_needless_logging) { char buf[80]; unsigned s = snprintf(buf, sizeof buf, "dkimsign[%d]: received signal %s\n", (int)getpid(), strsignal(sig)); if (s >= sizeof buf) { buf[sizeof buf - 1] = '\n'; s = sizeof buf; } write(2, buf, s); } #endif switch(sig) { case SIGALRM: signal_timed_out = 1; break; case SIGHUP: case SIGPIPE: case SIGINT: case SIGQUIT: case SIGTERM: signal_break = 1; break; case SIGCHLD: signal_child = 1; break; default: break; } }
static void catch_sig_event(int sig) { printf("%s signal: %s\n", "event", strsignal(sig)); if (sig_term_received) return; switch (sig) { case SIGHUP: break; case SIGUSR1: sig_usr1_received = 1; break; case SIGUSR2: break; case SIGALRM: sig_alrm_received = 1; break; } }
pid_t fwexec(const char *cmd, ...) { const char *argv[100] = { cmd }; va_list ap; int wstatus, i = 1; pid_t p; va_start(ap, cmd); do { argv[i] = va_arg(ap, char *); } while (argv[i++]); va_end(ap); switch ((p = fork())) { case -1: return -1; case 0: execvp(argv[0], (char *const *)argv); _exit(EXIT_FAILURE); break; default: if (waitpid(p, &wstatus, 0) == -1) { return -1; } else if (WIFEXITED(wstatus)) { if (WEXITSTATUS(wstatus) == 0) { return 0; } else { syslog(LOG_WARNING, "%s exit status: %d", argv[0], WEXITSTATUS(wstatus)); } } else { /* must have died due to signal */ syslog(LOG_WARNING, "%s died: %s", argv[0], strsignal(WTERMSIG(wstatus))); } break; } return -1; }
/* Execute the code in the file at code->path by executing the * configured command line. On success, returns STATUS_OK. On error * returns STATUS_ERR and fills in *error. */ static int execute_code_command_line(struct code_state *code, char **error) { int result = STATUS_ERR; /* return value */ char *full_command_line = NULL; asprintf(&full_command_line, "%s %s", code->command_line, code->path); /* For verbose debugging we dump the full output file. */ if (code->verbose) { char *verbose_command_line = NULL; asprintf(&verbose_command_line, "cat %s", code->path); system(verbose_command_line); free(verbose_command_line); printf("running: '%s'\n", full_command_line); } int status = system(full_command_line); if (status == -1) { asprintf(error, "error running '%s' with system(3): %s", code->command_line, strerror(errno)); goto out; } if (WIFSIGNALED(status) && (WTERMSIG(status) == SIGINT || WTERMSIG(status) == SIGQUIT)) { asprintf(error, "'%s' got signal %d (%s)", code->command_line, WTERMSIG(status), strsignal(WTERMSIG(status))); goto out; } if (WEXITSTATUS(status) != 0) { asprintf(error, "'%s' returned non-zero status %d", code->command_line, WEXITSTATUS(status)); goto out; } result = STATUS_OK; out: free(full_command_line); return result; }
void ProcessManagerBase::signalError(int sig, siginfo_t *si, void *ptr) { void* ErrorAddr; void* Trace[16]; int x; int TraceSize; char** Messages; std::stringstream msg; msg << _("ProcessManager: received sigal: ") << strsignal(sig) << " (" << si->si_addr << ")" << std::endl; #if __WORDSIZE == 64 // os type ErrorAddr = (void*)((ucontext_t*)ptr)->uc_mcontext.gregs[REG_RIP]; #else ErrorAddr = (void*)((ucontext_t*)ptr)->uc_mcontext.gregs[REG_EIP]; #endif TraceSize = backtrace(Trace, 16); Trace[1] = ErrorAddr; Messages = backtrace_symbols(Trace, TraceSize); if (Messages) { const char intend[] = " "; msg << intend << _("== Backtrace ==") << std::endl; for (x = 1; x < TraceSize; x++) msg << intend << Messages[x] << std::endl; msg << intend << _("== End Backtrace =="); LOG(ERROR) << msg.str(); free(Messages); } VLOG(2) << _("Exception occur. Hard stopping."); // TODO: It will be best to legally stop here, or, at least give // inheritances chance to do some work: handle closing, // destructing or smth... exit(2); // need restart status }
static void sigsegvHandler(int sig, siginfo_t* info, void* secret) { if (fatal_error_in_progress) raise(sig); fatal_error_in_progress = 1; unlinkPidFile(); #ifdef DEBUG void* trace[100]; size_t trace_size = backtrace(trace, 100); // overwrite sigaction with caller's address ucontext_t *uc = (ucontext_t*) secret; if (getMcontextEip(uc) != NULL) trace[1] = getMcontextEip(uc); if (!s_stack_filename.empty()) { int stackfd = open(s_stack_filename.c_str(), O_WRONLY|O_CREAT, S_IRUSR|S_IWUSR); backtrace_symbols_fd(trace, trace_size, stackfd); } base::Logger::instance()->setAutoFlush(true); LOG(fatal, "Ooops! Got signal (" << sig << "): " << strsignal(sig)); char** messages = backtrace_symbols(trace, trace_size); for (int i = 1; i < trace_size; ++i) LOG(fatal, messages[i]); #endif struct sigaction act; sigemptyset(&act.sa_mask); act.sa_flags = SA_NODEFER | SA_ONSTACK | SA_RESETHAND; act.sa_handler = SIG_DFL; sigaction(sig, &act, NULL); raise(sig); }
static ALWAYS_INLINE void _push_request_fd(lwan_t *l, int fd) { unsigned thread; #ifdef __x86_64__ assert(sizeof(lwan_connection_t) == 32); /* Since lwan_connection_t is guaranteed to be 32-byte long, two of them * can fill up a cache line. This formula will group two connections * per thread in a way that false-sharing is avoided. This gives wrong * results when fd=0, but this shouldn't happen (as 0 is either the * standard input or the main socket, but even if that changes, * scheduling will still work). */ thread = ((fd - 1) / 2) % l->thread.count; #else static int counter = 0; thread = counter++ % l->thread.count; #endif int epoll_fd = l->thread.threads[thread].epoll_fd; struct epoll_event event = { .events = EPOLLIN | EPOLLRDHUP | EPOLLERR | EPOLLET, .data.ptr = &l->conns[fd] }; l->conns[fd].flags = 0; l->conns[fd].thread = &l->thread.threads[thread]; if (UNLIKELY(epoll_ctl(epoll_fd, EPOLL_CTL_ADD, fd, &event) < 0)) lwan_status_critical_perror("epoll_ctl"); } static void _signal_handler(int signal_number) { lwan_status_info("Signal %d (%s) received", signal_number, strsignal(signal_number)); longjmp(cleanup_jmp_buf, 1); }