Skip to content

Instantly share code, notes, and snippets.

@azat
Last active January 9, 2023 22:33
Show Gist options
  • Save azat/73638b8e3b0fa563a20dadcca9e652a1 to your computer and use it in GitHub Desktop.
Save azat/73638b8e3b0fa563a20dadcca9e652a1 to your computer and use it in GitHub Desktop.
/**
* Check for raising a signal before looping:
* - OSX 10.14 -- *SIGALARM* (with USE__RAISE/USE__PTHREAD_KILL), exit cleanly with USE__KILL
* - OSX 10.11 -- exit cleanly (with USE__RAISE/USE__PTHREAD_KILL/USE__KILL)
*/
#include <sys/event.h>
#include <unistd.h>
#include <assert.h>
#include <signal.h>
#include <stdio.h>
int main (int argc, const char *argv[])
{
int kq = kqueue();
struct kevent sigevent;
EV_SET(&sigevent, SIGINT, EVFILT_SIGNAL, EV_ADD | EV_ENABLE, 0, 0, NULL);
signal(SIGINT, SIG_IGN);
kevent(kq, &sigevent, 1, NULL, 0, NULL);
#if defined(USE__RAISE)
raise(SIGINT);
#elif defined(USE__PTHREAD_KILL)
raise(SIGINT);
#elif defined(USE__KILL)
kill(getpid(), SIGINT);
#else
# error "One of USE__RAISE/USE__PTHREAD_KILL/USE__KILL should be specified"
#endif
alarm(1);
struct kevent change;
assert(kevent(kq, NULL, 0, &change, 1, NULL) != -1);
assert(!change.udata);
puts("Signal received. Clean exit.");
close(kq);
return 0;
}
@azat
Copy link
Author

azat commented May 15, 2019

Apple says:

kevent listens to process-targeted signals, not thread-targeted signals.
“Only signals sent to the process, not to a particular thread, will trigger the filter.”

And:

https://pubs.opengroup.org/onlinepubs/7908799/xsh/raise.html


The raise() function sends the signal sig to the executing thread.
The effect of the raise() function is equivalent to calling:

pthread_kill(pthread_self(), sig);

So, this behaves correctly.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment