/* * to create and obtain a new NONBLOCKING socket file descriptor * * (!) this will block SIGRTMIN for this thread only * * returns -1 on error */ int rtsig_install_receiver(int listen_on_rtsig, int nonblock_on) { //make thread "immune" to realtime signals sigset_t immune_set; sigemptyset(&immune_set); sigaddset(&immune_set, (SIGRTMIN+listen_on_rtsig)); pthread_sigmask(SIG_BLOCK, &immune_set, NULL); #if(USS_LIBRARY_DEBUG == 1) //printf("SIGRTMIN=%i\n", (int)SIGRTMIN); //printf("immune to %i\n", (int)SIGRTMIN+listen_on_rtsig); #endif //prepare parameters int fd; sigset_t mask; sigemptyset(&mask); sigaddset(&mask, SIGRTMIN+listen_on_rtsig); if(nonblock_on != 0) { //create new NONBLOCKING fd for realtime signal SIGRTMIN fd = signalfd(-1, &mask, SFD_NONBLOCK); if(fd == -1) {derr("problem with signal file descriptor"); return USS_ERROR_GENERAL;} } else { //create new NONBLOCKING fd for realtime signal SIGRTMIN fd = signalfd(-1, &mask, 0); if(fd == -1) {derr("problem with signal file descriptor"); return USS_ERROR_GENERAL;} } return fd; }
int main (void) { #if defined(HAVE_SIGNALFD) && defined(HAVE_EVENTFD) \ && defined(HAVE_EVENTFD_READ) && defined(HAVE_PPOLL) { sigset_t mask; int fd, fd2; eventfd_t ev; struct timespec ts = { .tv_sec = 1, .tv_nsec = 0 }; struct pollfd pfd[2]; sigemptyset (&mask); sigaddset (&mask, SIGUSR1); fd = signalfd (-1, &mask, 0); sigaddset (&mask, SIGUSR2); fd = signalfd (fd, &mask, 0); fd2 = eventfd (5, 0); eventfd_read (fd2, &ev); pfd[0].fd = fd; pfd[0].events = POLLIN|POLLOUT; pfd[1].fd = fd2; pfd[1].events = POLLIN|POLLOUT; ppoll (pfd, 2, &ts, &mask); } #endif #if defined(HAVE_UTIMENSAT) unlink("/tmp/valgrind-utimensat-test"); close (creat ("/tmp/valgrind-utimensat-test", S_IRUSR | S_IWUSR)); { struct timespec ts2[2] = { [0].tv_sec = 10000000, [1].tv_sec = 20000000 }; utimensat (AT_FDCWD, "/tmp/valgrind-utimensat-test", ts2, 0); } unlink("/tmp/valgrind-utimensat-test"); #endif #if defined(HAVE_EPOLL_CREATE) && defined(HAVE_EPOLL_PWAIT) { int fd3; struct epoll_event evs[10]; sigset_t mask; sigemptyset (&mask); sigaddset (&mask, SIGUSR1); sigaddset (&mask, SIGUSR2); fd3 = epoll_create (10); epoll_pwait (fd3, evs, 10, 0, &mask); } #endif return 0; }
static int setup_signal_fd(sigset_t *oldmask) { sigset_t mask; int fd; /* Block everything except serious error signals. */ if (sigfillset(&mask) || sigdelset(&mask, SIGILL) || sigdelset(&mask, SIGSEGV) || sigdelset(&mask, SIGBUS) || sigdelset(&mask, SIGWINCH) || sigprocmask(SIG_BLOCK, &mask, oldmask)) { SYSERROR("Failed to set signal mask."); return -1; } fd = signalfd(-1, &mask, 0); if (fd < 0) { SYSERROR("Failed to create signal file descriptor."); return -1; } if (fcntl(fd, F_SETFD, FD_CLOEXEC)) { SYSERROR("Failed to set FD_CLOEXEC on the signal file descriptor: %d.", fd); close(fd); return -1; } DEBUG("Set SIGCHLD handler with file descriptor: %d.", fd); return fd; }
static int signalfd_open(struct file_desc *d, int *new_fd) { struct signalfd_info *info; int tmp; sigset_t mask; info = container_of(d, struct signalfd_info, d); pr_info("Restoring signalfd %#x\n", info->sfe->id); sigset_fill(&mask, info->sfe->sigmask); tmp = signalfd(-1, &mask, 0); if (tmp < 0) { pr_perror("Can't create signalfd %#08x", info->sfe->id); return -1; } if (rst_file_params(tmp, info->sfe->fown, info->sfe->flags)) { pr_perror("Can't restore params on signalfd %#08x", info->sfe->id); goto err_close; } *new_fd = tmp; return 0; err_close: close(tmp); return -1; }
int main(int argc, char *argv[]) { sigset_t mask; int sfd; struct signalfd_siginfo fdsi; ssize_t s; sigemptyset(&mask); sigaddset(&mask, SIGINT); sigaddset(&mask, SIGQUIT); if (sigprocmask(SIG_BLOCK, &mask, NULL) == -1) handle_error("sigprocmask"); sfd = signalfd(-1, &mask, 0); if (sfd == -1) handle_error("signalfd"); for (;;) { s = read(sfd, &fdsi, sizeof(struct signalfd_siginfo)); if (s != sizeof(struct signalfd_siginfo)) handle_error("read"); if (fdsi.ssi_signo == SIGINT) { printf("Got SIGINT\n"); } else if (fdsi.ssi_signo == SIGQUIT) { printf("Got SIGQUIT\n"); exit(EXIT_SUCCESS); } else { printf("Read unexpected signal\n"); } } }
int swSignalfd_setup(swReactor *reactor) { if (signal_fd == 0) { signal_fd = signalfd(-1, &signalfd_mask, SFD_NONBLOCK | SFD_CLOEXEC); if (signal_fd < 0) { swWarn("signalfd() failed. Error: %s[%d]", strerror(errno), errno); return SW_ERR; } SwooleG.signal_fd = signal_fd; if (sigprocmask(SIG_BLOCK, &signalfd_mask, NULL) == -1) { swWarn("sigprocmask() failed. Error: %s[%d]", strerror(errno), errno); return SW_ERR; } reactor->setHandle(reactor, SW_FD_SIGNAL, swSignalfd_onSignal); reactor->add(reactor, signal_fd, SW_FD_SIGNAL); return SW_OK; } else { swWarn("signalfd has been created"); return SW_ERR; } }
int main(int argc, char *argv[]) { sigset_t mask; int sfd, epollfd; struct epoll_event ev; sigemptyset(&mask); sigaddset(&mask, SIGINT); sigaddset(&mask, SIGTERM); sigaddset(&mask, SIGQUIT); sigaddset(&mask, SIGCHLD); /* Block signals so that they aren't handled according to their default dispositions */ if (sigprocmask(SIG_BLOCK, &mask, NULL) == -1) handle_error("sigprocmask"); sfd = signalfd(-1, &mask, SFD_CLOEXEC | SFD_NONBLOCK); if (sfd == -1) handle_error("signalfd"); // forking after epoll created leades to world of pain do_forks(MAX_CHILDREN, sfd); run_epoll(sfd, 1); return EXIT_SUCCESS; }
GSource * _g_posix_signal_source_new (gint signum) { sigset_t sigset; gint fd; GSource *_source; _GPosixSignalSource *source; _source = NULL; sigemptyset (&sigset); sigaddset (&sigset, signum); if (sigprocmask (SIG_BLOCK, &sigset, NULL) == -1) g_assert_not_reached (); fd = signalfd (-1, &sigset, SFD_NONBLOCK | SFD_CLOEXEC); _source = g_source_new (&_g_posix_signal_source_funcs, sizeof (_GPosixSignalSource)); source = (_GPosixSignalSource *) _source; source->pollfd.fd = fd; source->pollfd.events = G_IO_IN; g_source_add_poll (_source, &source->pollfd); source->signum = signum; return _source; }
static int create_signal_io(void) { sigset_t mask; GIOChannel *signal_io; int signal_fd, signal_source; sigemptyset(&mask); sigaddset(&mask, SIGTERM); sigaddset(&mask, SIGINT); if (sigprocmask(SIG_BLOCK, &mask, NULL) < 0) { g_error("Can't set signal mask"); return 1; } signal_fd = signalfd(-1, &mask, 0); if (signal_fd < 0) { g_error("Can't create signal filedescriptor"); return 1; } signal_io = g_io_channel_unix_new(signal_fd); g_io_channel_set_close_on_unref(signal_io, TRUE); signal_source = g_io_add_watch(signal_io, G_IO_IN | G_IO_HUP | G_IO_ERR | G_IO_NVAL, signal_cb, GINT_TO_POINTER(signal_fd)); g_io_channel_unref(signal_io); return signal_source; }
static int local_init(const char *option) { sigset_t mask; int ret; static struct timer t = { .callback = check_pids, .data = &t, }; if (option) shmfile = option; shm_queue_init(); sigemptyset(&mask); sigaddset(&mask, SIGUSR1); sigprocmask(SIG_BLOCK, &mask, NULL); sigfd = signalfd(-1, &mask, SFD_NONBLOCK); if (sigfd < 0) { eprintf("failed to create a signal fd: %m\n"); return -1; } add_timer(&t, 1); ret = register_event(sigfd, local_handler, NULL); if (ret) { eprintf("failed to register local event handler (%d)\n", ret); return -1; } return 0; }
static int setup_signals(struct weston_launch *wl) { int ret; sigset_t mask; struct sigaction sa; memset(&sa, 0, sizeof sa); sa.sa_handler = SIG_DFL; sa.sa_flags = SA_NOCLDSTOP | SA_RESTART; ret = sigaction(SIGCHLD, &sa, NULL); assert(ret == 0); sa.sa_handler = SIG_IGN; sa.sa_flags = 0; sigaction(SIGHUP, &sa, NULL); ret = sigemptyset(&mask); assert(ret == 0); sigaddset(&mask, SIGCHLD); sigaddset(&mask, SIGINT); sigaddset(&mask, SIGTERM); sigaddset(&mask, SIGUSR1); sigaddset(&mask, SIGUSR2); ret = sigprocmask(SIG_BLOCK, &mask, NULL); assert(ret == 0); wl->signalfd = signalfd(-1, &mask, SFD_NONBLOCK | SFD_CLOEXEC); if (wl->signalfd < 0) return -errno; return 0; }
static int init_signal(void) { sigset_t mask; int ret; sigemptyset(&mask); sigaddset(&mask, SIGTERM); sigprocmask(SIG_BLOCK, &mask, NULL); sigfd = signalfd(-1, &mask, SFD_NONBLOCK); if (sigfd < 0) { sd_err("failed to create a signal fd: %m"); return -1; } ret = register_event(sigfd, signal_handler, NULL); if (ret) { sd_err("failed to register signal handler (%d)", ret); return -1; } sd_debug("register signal_handler for %d", sigfd); return 0; }
static void signal_task_run(void *arg) { int fd; sigset_t mask; wire_fd_state_t fd_state; sigemptyset(&mask); sigaddset(&mask, SIGINT); sigaddset(&mask, SIGQUIT); sigaddset(&mask, SIGTERM); sigaddset(&mask, SIGHUP); /* Block signals so that they aren't handled according to their default dispositions */ if (sigprocmask(SIG_BLOCK, &mask, NULL) == -1) { perror("sigprocmask failed"); return; } fd = signalfd(-1, &mask, 0); if (fd == -1) { perror("signalfd failed"); return; } wire_fd_mode_init(&fd_state, fd); while (1) { struct signalfd_siginfo fdsi; ssize_t s; wire_fd_mode_read(&fd_state); wire_fd_wait(&fd_state); s = read(fd, &fdsi, sizeof(struct signalfd_siginfo)); if (s != sizeof(struct signalfd_siginfo)) { wire_log(WLOG_ERR, "failed to read from signalfd %d: ret=%d errno=%d: %m\n", fd, (int)s, errno); wio_close(fd); break; } if (fdsi.ssi_signo == SIGINT || fdsi.ssi_signo == SIGTERM || fdsi.ssi_signo == SIGQUIT) { wire_log(WLOG_NOTICE, "Got signal %d", fdsi.ssi_signo); handle_shutdown_signal(); break; } else if (fdsi.ssi_signo == SIGHUP) { wire_log(WLOG_INFO, "Got sighup, saving state"); disk_manager_save_state(); } else { wire_log(WLOG_WARNING, "Read unexpected signal %d", fdsi.ssi_signo); } } sigprocmask(SIG_UNBLOCK, &mask, NULL); wire_fd_mode_none(&fd_state); wio_close(fd); wire_log(WLOG_INFO, "signal thread exiting"); }
WL_EXPORT struct wl_event_source * wl_event_loop_add_signal(struct wl_event_loop *loop, int signal_number, wl_event_loop_signal_func_t func, void *data) { struct wl_event_source_signal *source; sigset_t mask; source = malloc(sizeof *source); if (source == NULL) return NULL; source->base.interface = &signal_source_interface; source->signal_number = signal_number; sigemptyset(&mask); sigaddset(&mask, signal_number); source->base.fd = signalfd(-1, &mask, SFD_CLOEXEC); sigprocmask(SIG_BLOCK, &mask, NULL); source->func = func; return add_source(loop, &source->base, WL_EVENT_READABLE, data); }
int32_t IOLoop::addSignalHandler(int signum, HandlerCallback&& handler) { sigset_t mask; sigemptyset(&mask); sigaddset(&mask, signum); // block watched signals: otherwise the default handler is called if(sigprocmask(SIG_BLOCK, &mask, 0)) { TORNADO_LOG_ERROR("sigprocmask faild err=%s", STR_ERRNO); return -1; } int32_t sfd = signalfd(-1, &mask, SFD_NONBLOCK | SFD_CLOEXEC); if(sfd < 0) { TORNADO_LOG_ERROR("signalfd faild err=%s", STR_ERRNO); return sfd; } if( addHandler(sfd, std::move(handler), IOLoop::READ) ) { TORNADO_LOG_ERROR("addHandler faild sfd=%d", sfd); removeHandler(sfd); ::close(sfd); return -1; } return sfd; }
static int setup_signal_fd(sigset_t *oldmask) { sigset_t mask; int fd; /* Block everything except serious error signals */ if (sigfillset(&mask) || sigdelset(&mask, SIGILL) || sigdelset(&mask, SIGSEGV) || sigdelset(&mask, SIGBUS) || sigdelset(&mask, SIGWINCH) || sigprocmask(SIG_BLOCK, &mask, oldmask)) { SYSERROR("failed to set signal mask"); return -1; } fd = signalfd(-1, &mask, 0); if (fd < 0) { SYSERROR("failed to create the signal fd"); return -1; } if (fcntl(fd, F_SETFD, FD_CLOEXEC)) { SYSERROR("failed to set sigfd to close-on-exec"); close(fd); return -1; } DEBUG("sigchild handler set"); return fd; }
static int signal_fd_init(int epoll_fd) { struct epoll_event ev; sigset_t mask; int ret; int fd; sigemptyset(&mask); sigaddset(&mask, SIGINT); sigaddset(&mask, SIGTERM); ret = sigprocmask(SIG_BLOCK, &mask, NULL); if (ret == -1) { perror("sigprocmask"); return -1; } fd = signalfd(-1, &mask, SFD_CLOEXEC); if (fd == -1) { perror("signalfd"); return -1; } signal_cb.fd = fd; ev.events = EPOLLIN; ev.data.ptr = &signal_cb; return epoll_ctl(epoll_fd, EPOLL_CTL_ADD, fd, &ev); }
// Ping X in @pingInterval miliseconds. XServerPinger::XServerPinger(int pingInterval) { Display *dpy; sigset_t sigs; // Open a separate connection to X. dpy = XOpenDisplay(NULL); xcb = XGetXCBConnection(dpy); connect(new QSocketNotifier(ConnectionNumber(dpy), QSocketNotifier::Read), SIGNAL(activated(int)), SLOT(xInput(int))); // XGetInputFocus() is our ping request. request = xcb_get_input_focus(xcb); xcb_flush(xcb); timer = new QTimer(); connect(timer, SIGNAL(timeout()), SLOT(tick())); timer->start(pingInterval); // die() if we get SIGINT or SIGTERM. sigemptyset(&sigs); sigaddset(&sigs, SIGINT); sigaddset(&sigs, SIGTERM); connect(new QSocketNotifier(signalfd(-1, &sigs, 0), QSocketNotifier::Read), SIGNAL(activated(int)), SLOT(die(int))); sigprocmask(SIG_BLOCK, &sigs, NULL); }
static int setup_signal_handler(void) { sigset_t mask; int ret; sigemptyset(&mask); sigaddset(&mask, SIGINT); sigaddset(&mask, SIGPIPE); sigaddset(&mask, SIGHUP); sigaddset(&mask, SIGTERM); ret = sigprocmask(SIG_BLOCK, &mask, NULL); if (ret) { perror("Failed to setup signal mask"); return -errno; } ret = signalfd(-1, &mask, 0); if (ret < 0) { perror("Failed to create signalfd"); return -errno; } return ret; }
void rb_epoll_init_event(void) { sigset_t ss; rb_fde_t *F; int sfd; rb_epoll_supports_event(); if(!can_do_timerfd) { sigemptyset(&ss); sigaddset(&ss, RTSIGNAL); sigprocmask(SIG_BLOCK, &ss, 0); sigemptyset(&ss); sigaddset(&ss, RTSIGNAL); sfd = signalfd(-1, &ss, 0); if(sfd == -1) { can_do_event = -1; return; } F = rb_open(sfd, RB_FD_UNKNOWN, "signalfd"); rb_set_nb(F); signalfd_handler(F, NULL); } }
static void catch_fatal_signals() { struct sigaction sa = { .sa_sigaction = &handle_fatal_signal, .sa_flags = SA_SIGINFO | SA_RESETHAND | SA_NODEFER, }; sigemptyset(&sa.sa_mask); for (int i = 0; i < sizeof(fatal_signals) / sizeof(*fatal_signals); i++) EXPECT_ERRNO(sigaction(fatal_signals[i], &sa, NULL) != -1); } static int create_signal_fd() { sigset_t mask; int sfd; /* Setup a signal fd for SIGINT, SIGCHLD and SIGUSR1 */ sigemptyset(&mask); sigaddset(&mask, SIGINT); sigaddset(&mask, SIGCHLD); sigaddset(&mask, SIGUSR1); EXPECT(sigprocmask(SIG_BLOCK, &mask, NULL) != -1); sfd = signalfd(-1, &mask, 0); EXPECT(sfd != -1); return sfd; }
static int signal_init(void) { sigset_t mask; sigfillset(&mask); sigprocmask(SIG_BLOCK, &mask, NULL); return signalfd(-1, &mask, 0); }
int signal_fd( ) { sigset_t mask; sigemptyset( &mask ); sigaddset( &mask, SIGINT ); sigaddset( &mask, SIGQUIT ); sigprocmask( SIG_BLOCK, &mask, 0 ); return signalfd( -1, &mask, 0 ); }
void add( ItB begin, ItE end ) { for ( ; begin != end; ++begin ) { int r = sigaddset( &_sigset, *begin ); ASSERT( r == 0 ); } _sigfd.fd = signalfd( _sigfd.fd, &_sigset, SFD_CLOEXEC ); ASSERT( !!_sigfd ); // make sure signal are not delivered normally sigprocmask( SIG_BLOCK, &_sigset, nullptr ); }
int selfpipe_init (void) { if (selfpipe_fd >= 0) return (errno = EBUSY, -1) ; sigemptyset(&selfpipe_caught) ; #ifdef SKALIBS_HASSIGNALFD selfpipe_fd = signalfd(-1, &selfpipe_caught, SFD_NONBLOCK | SFD_CLOEXEC) ; #else if (pipenbcoe(selfpipe) < 0) return -1 ; #endif return selfpipe_fd ; }
void Signal::Manager::forked() { if(sigprocmask(SIG_BLOCK, &mask, nullptr) < 0) { throw; } fd = signalfd(fd, &mask, SFD_NONBLOCK | SFD_CLOEXEC); modify(EPOLLIN); start(); }
void loop_init() { main_thread_id = pthread_self(); sigset_t sigset; sigemptyset(&sigset); sigaddset(&sigset, SIGHUP); sigaddset(&sigset, SIGTERM); sigaddset(&sigset, SIGINT); sigaddset(&sigset, SIGQUIT); sigprocmask(SIG_BLOCK, &sigset, NULL); sigFd = signalfd(-1, &sigset, 0); loop_add_fd(sigFd, loop_sig_handler, POLLIN | POLLERR | POLLHUP); }
Signal::Manager::Manager() { setStackSize((size_t)(4 * getpagesize())); ::sigemptyset(&mask); if(sigprocmask(SIG_BLOCK, &mask, nullptr) < 0) { throw; } fd = signalfd(-1, &mask, SFD_NONBLOCK | SFD_CLOEXEC); Poller::get()->addListener(this); }
int rb_epoll_supports_event(void) { /* try to detect at runtime if everything we need actually works */ timer_t timer; struct sigevent ev; struct stat st; int fd; sigset_t set; if(can_do_event == 1) return 1; if(can_do_event == -1) return 0; /* Check for openvz..it has a broken timerfd.. */ if(stat("/proc/user_beancounters", &st) == 0) { can_do_event = -1; return 0; } #ifdef USE_TIMERFD_CREATE if((fd = timerfd_create(CLOCK_REALTIME, 0)) >= 0) { close(fd); can_do_event = 1; can_do_timerfd = 1; return 1; } #endif ev.sigev_signo = SIGVTALRM; ev.sigev_notify = SIGEV_SIGNAL; if(timer_create(CLOCK_REALTIME, &ev, &timer) != 0) { can_do_event = -1; return 0; } timer_delete(timer); sigemptyset(&set); fd = signalfd(-1, &set, 0); if(fd < 0) { can_do_event = -1; return 0; } close(fd); can_do_event = 1; return 1; }
int parent_main(pid_t child_pid) { int epfd; int sigfd; int status; sigset_t sigs; if (sigfillset(&sigs) == -1) { ERRMSG("sigfillset() failed"); goto kill_child; } if (sigprocmask(SIG_SETMASK, &sigs, NULL) == -1) { ERRMSG("sigprocmask() failed"); goto kill_child; } if ((sigfd = signalfd(-1, &sigs, SFD_NONBLOCK)) == -1) { ERRMSG("signalfd() failed"); goto kill_child; } if ((epfd = epoll_create(1)) == -1) { ERRMSG("epoll_create() failed"); goto kill_child; } if (epoll_add(epfd, sigfd, EPOLLIN) == -1) { ERRMSG("epoll_add() failed"); goto kill_child; } if (epoll_add(epfd, STDIN_FILENO, 0) == -1) { ERRMSG("epoll_add() failed"); goto kill_child; } for (;;) { int i; enum HANDLE_RESULT handle_ret; struct epoll_event e[3]; int nfd = epoll_wait(epfd, e, sizeof(e) / sizeof(struct epoll_event), 100); if (nfd == -1) { ERRMSG("epoll_wait() failed"); goto kill_child; } if (nfd == 0) { int ret = waitpid(child_pid, &status, WNOHANG); if (ret == -1) { ERRMSG("waitpid() failed"); goto kill_child; } if (ret != 0) { goto child_exited; } continue; } for (i = 0; i < nfd; i++) { int fd = e[i].data.fd; if (fd == sigfd) { handle_ret = handle_signal(fd, child_pid); } else { handle_ret = handle_in_eof(fd, child_pid); } switch(handle_ret) { case KILL_CHILD: goto kill_child; case WAIT_CHILD_EXIT: goto wait_child_exit; } } } kill_child: if (kill(child_pid, SIGKILL) == -1) { ERR_EXIT("kill() failed"); } wait_child_exit: if (waitpid(child_pid, &status, 0) == -1) { ERR_EXIT("waitpid() failed"); } child_exited: if (WIFEXITED(status)) { return WEXITSTATUS(status); } if (WIFSIGNALED(status)) { return WTERMSIG(status) + 128; } return 1; }