forked from stsaz/kernel-queue-the-complete-guide
-
-
Notifications
You must be signed in to change notification settings - Fork 0
/
kqueue-signal.c
55 lines (45 loc) · 1.13 KB
/
kqueue-signal.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
/* Kernel Queue The Complete Guide: kqueue-signal.c: UNIX signal handler
Usage:
$ ./kqueue-signal
$ killall -SIGUSR1 kqueue-signal
*/
#include <assert.h>
#include <signal.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/event.h>
int kq;
struct context {
void (*handler)(int sig);
};
void unix_signal_handler(int sig)
{
printf("Received UNIX signal via kqueue: %d\n", sig);
}
void main()
{
kq = kqueue();
assert(kq != -1);
struct context obj = {};
obj.handler = unix_signal_handler;
// block default signal handler
int sig = SIGUSR1;
sigset_t mask;
sigemptyset(&mask);
sigaddset(&mask, sig);
sigprocmask(SIG_BLOCK, &mask, NULL);
// register UNIX signal handler
struct kevent events[1];
EV_SET(&events[0], sig, EVFILT_SIGNAL, EV_ADD | EV_ENABLE, 0, 0, &obj);
assert(0 == kevent(kq, events, 1, NULL, 0, NULL));
struct timespec *timeout = NULL; // wait indefinitely
int n = kevent(kq, NULL, 0, events, 1, timeout);
assert(n > 0);
struct context *o = events[0].udata;
if (events[0].filter == EVFILT_SIGNAL) {
int sig = events[0].ident;
obj.handler(sig); // handle UNIX signal
}
close(kq);
}