#include <stdio.h> #include <string.h> #include <stdlib.h> #include <signal.h> #include <unistd.h> #include <errno.h> #include <sys/epoll.h> #include <fcntl.h> #include "aytype.h" #include "aylist.h" #include <vector> using namespace std; static int32_t pipe_fds[2] = {-1, -1}; static int32_t epollfd = -1; static struct sigaction act; static void _real_signal_to_pipe_(int signal_num, siginfo_t* si, void *context) { int32_t sig = signal_num; int32_t res = 0; if (pipe_fds[1] > 0) { try_again: res = write(pipe_fds[1], &sig, sizeof(int32_t)); if (res == -1 && errno == EAGAIN) { goto try_again; } else if (res != sizeof(int32_t)) { fprintf(stderr, "error when write to pipe\n"); return; } } } static int32_t epoll_init() { epollfd = epoll_create(EPOLL_CLOEXEC); if (epollfd < 0) return -errno; return 0; } static int32_t epoll_add(int32_t fd) { struct epoll_event ev; int32_t res = 0; ev.events = EPOLLIN; ev.data.u64 = 0; if (epoll_ctl(epollfd, EPOLL_CTL_ADD, fd, &ev) == -1) res = -errno; return res; } static int32_t epoll_del(int32_t fd) { int32_t res = 0; if (epoll_ctl(epollfd, EPOLL_CTL_DEL, fd, NULL) == -1) res = -errno; return res; } static int32_t sys_fd_nonblock_cloexec_set(int32_t fd) { int32_t res = 0; int32_t oldflags = fcntl(fd, F_GETFD, 0); if (oldflags < 0) oldflags = 0; oldflags |= FD_CLOEXEC; res = fcntl(fd, F_SETFD, oldflags); if (res == -1) { res = -errno; fprintf(stderr, "could not set close-on-exit on fd:%d\n", fd); return res; } res = fcntl(fd, F_SETFL, O_NONBLOCK); if (res == -1) { res = -errno; return res; } return res; } static int32_t my_poll_start() { const int MAX_EVENTS = 12; int32_t event_count; int32_t res; int32_t the_signal; struct epoll_event events[MAX_EVENTS]; vector<int> signal_queue; vector<int>::iterator signal_queue_ite; while (1) { retry_poll: event_count = epoll_wait(epollfd, events, MAX_EVENTS, /*timeout*/10); if (errno == EINTR && event_count == -1) { goto retry_poll; } else if (event_count == -1) { return -errno; } /* we have only one fds to listen */ for (int i = 0; i < event_count; i++) { if (events[i].events & EPOLLIN) { res = read(pipe_fds[0], &the_signal, sizeof(int32_t)); if (res != sizeof(int32_t)) { fprintf(stderr, "failed to read pipe\n"); return -1; } else { signal_queue.push_back(the_signal); printf("\nsignal_queue\n"); for (signal_queue_ite = signal_queue.begin(); signal_queue_ite != signal_queue.end(); signal_queue_ite++) { printf("|- %d\n", *signal_queue_ite); } printf("\n"); } } } } return 0; } static int my_poll_init() { int32_t res = 0; res = pipe(pipe_fds); if (res == -1) { res = -errno; return res; } sys_fd_nonblock_cloexec_set(pipe_fds[0]); sys_fd_nonblock_cloexec_set(pipe_fds[1]); if ((res = epoll_init()) < 0) goto error_exit; if ((res = epoll_add(pipe_fds[0])) < 0) goto error_exit; // so wired act.sa_sigaction = _real_signal_to_pipe_; act.sa_flags = SA_NOMASK; return 0; error_exit: if (pipe_fds[0] >= 0) close(pipe_fds[0]); if (pipe_fds[1] >= 0) close(pipe_fds[1]); return res; } static void my_poll_add_signal(int signum) { sigaction(signum, &act, NULL); } int main() { my_poll_init(); my_poll_add_signal(SIGINT); my_poll_add_signal(SIGQUIT); my_poll_start(); return 0; }
转载于:https://www.cnblogs.com/Anney/archive/2013/01/06/2848344.html