I wrote a small ppoll test but I am confused about the signal handling. The man page says:
The relationship between poll() and ppoll() is analogous to the relationship between select(2) and pselect(2): like pselect(2), ppoll() allows an application to safely wait until either a file descriptor becomes ready or until a signal is caught.
In my case fd changes are handled immediately while signals are handled after the timeout. I used ctr-c in the process context and kill from another shell but always the same behavior.
What am I doing wrong? Did I miss something?
#include <iostream> #include <poll.h> #include <signal.h> #include <unistd.h> void handleSignal(int signal) { switch(signal) { case SIGINT: std::cerr << "sigint" << std::endl; break; case SIGTERM: std::cerr << "sigterm" << std::endl; break; default: std::cerr << "sig=" << signal << std::endl; break; } } int main(int argc, char* argv[]) { int result; FILE *fd = fopen("/tmp/tmpFile", "r"); result = fileno(fd); if(-1 == result) { std::cerr << "could not open temp file" << std::endl; return EXIT_FAILURE; } pollfd fds[2]; fds[0] = { 0, POLLIN, 0 }; fds[1] = {result, POLLIN, 0 }; sigset_t mySigset, oldSigset; sigemptyset(&mySigset); sigaddset(&mySigset, SIGINT); sigaddset(&mySigset, SIGTERM); struct sigaction mySigHandler; mySigHandler.sa_handler = &handleSignal; mySigHandler.sa_flags = 0; sigemptyset(&mySigHandler.sa_mask); sigaction(SIGINT, &mySigHandler, NULL); sigaction(SIGTERM, &mySigHandler, NULL); char buffer[1024]; timespec time; while(true) { time = {20, 0}; result = ppoll(&fds[0], 2, &time, &mySigset); if(0 == result) { // timeout std::cout << "ppoll timeout" << std::endl; } else if(0 > result) { // error std::cerr << "ppoll error" << std::endl; } else { // at least one fd changed std::cout << "active fds: " << result << std::endl; for(int i = 0; i < 2; i++) { if(fds[i].revents & POLLIN) { result = read(fds[i].fd, buffer, 1024); if (-1 == result) { std::cerr << "error while reading fd " << fds[i].fd << std::endl; } else if(0 < result) { buffer[result] = ''; std::cout << "read fd " << fds[i].fd << ": " << buffer << std::endl; } } } } } return EXIT_SUCCESS; }
Advertisement
Answer
When you called ppoll
, you told it to block SIGINT
and SIGTERM
by passing them in the signal mask.