Created
July 18, 2013 18:43
-
-
Save ionelmc/6031828 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <stdlib.h> | |
#include <stdio.h> | |
#include <unistd.h> | |
#include <signal.h> | |
#include <pthread.h> | |
#include <sys/signalfd.h> | |
#include <sys/time.h> | |
#include <sys/types.h> | |
#define handle_error(msg) \ | |
do { perror(msg); exit(EXIT_FAILURE); } while (0) | |
void chld_handler(int signum) { | |
pthread_t id = pthread_self(); | |
printf("GOT SIGNAL %d in THREAD %li. This should not happen !\n", signum, (long int) id); | |
} | |
void* my_thread(void *args) { | |
pthread_t id = pthread_self(); | |
sigset_t mask; | |
sigemptyset(&mask); | |
sigaddset(&mask, SIGCHLD); | |
if (pthread_sigmask(SIG_BLOCK, &mask, NULL) == -1) | |
handle_error("sigprocmask in thread"); | |
for (;;) { | |
sleep(1); | |
printf("looping in %li.\n", (long int) id); | |
} | |
} | |
void setup_thread() { | |
pthread_t id; | |
int err = pthread_create(&id, NULL, &my_thread, NULL); | |
if (err) { | |
printf("can't create thread, error: %d\n", err); | |
} else { | |
printf("thread created successfully.\n"); | |
} | |
} | |
int main(int argc, char *argv[]) { | |
struct sigaction action = {.sa_handler = chld_handler, .sa_flags = 0}; | |
sigemptyset (&action.sa_mask); | |
sigaction(SIGCHLD, &action, NULL); | |
int fd; | |
struct signalfd_siginfo si; | |
ssize_t s; | |
sigset_t mask; | |
sigemptyset(&mask); | |
sigaddset(&mask, SIGCHLD); | |
if (pthread_sigmask(SIG_BLOCK, &mask, NULL) == -1) | |
handle_error("sigprocmask"); | |
fd = signalfd(-1, &mask, SFD_NONBLOCK|SFD_CLOEXEC); | |
if (fd == -1) | |
handle_error("signalfd"); | |
setup_thread(); | |
for (;;) { | |
int pid = fork(); | |
printf("Forked %d\n", pid); | |
if (pid) { | |
struct timeval tv = {.tv_sec = 1, .tv_usec = 0}; | |
fd_set readfds; | |
FD_ZERO(&readfds); | |
FD_SET(fd, &readfds); | |
// don't care about writefds and exceptfds: | |
select(fd+1, &readfds, NULL, NULL, &tv); | |
if (FD_ISSET(fd, &readfds)) { | |
s = read(fd, &si, sizeof(struct signalfd_siginfo)); | |
if (s != sizeof(struct signalfd_siginfo)) | |
handle_error("read"); | |
printf("Got signal %d (%d)\n", si.ssi_signo, si.ssi_pid); | |
} | |
} else { | |
sleep(2); | |
exit(0); | |
} | |
} | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
I appreciate you helping my OS assignment. This is only one which I found that implements signalfd() in thread. I love you.