Close XLib application from another process
c, linux, signals, x11, xlib
Solution
I found a way to do this based on this SO question and this one.
Basically you can use the `ConnectionNumber()` macro to get the fd that `XNextEvent()` is reading from. This lets me call `select()` myself to wait for data on the Xlib fd and some other fd. Now it is `select()` that is blocking, and not `XNextEvent()`. I can easily unblock `select()` from my signal handler by writing to the second fd.
Pseudo-code for the event loop:
/* Get X11 fd */
x11_fd = ConnectionNumber(display);
while(1) {
/* Create a File Description Set containing x11_fd and other_fd */
FD_ZERO(&in_fds);
FD_SET(x11_fd, &in_fds);
FD_SET(other_fd, &in_fds);
/* Wait for X Event or exit signal */
ret = select(nfds, &in_fds, ...);
if (FD_ISSET(other_fd, &in_fds) {
/* Do any cleanup and exit */
} else {
while (XEventsQueued(display, QueuedAlready) > 0) {
/* Process X events */
}
}
}
Problem
I have a Xlib-based program with an event loop that uses `XNextEvent` to receive and process relevant events. I would like to be able to gracefully close this program from another process (actually from a shell script). I need to do some cleanup when closing, so I considered to setup a signal handler (for example for SIGUSR1) and when this signal is received, do the appropriate cleanup. My question is, how can I interrupt the (blocking) `XNextEvent` call from the signal handler? Any other suggestions?