#include <stdio.h>
#include <string.h>
+#include <signal.h>
+#include <poll.h>
+#include <errno.h>
#include "twm.h"
#include <X11/Xatom.h>
#include "add_window.h"
#include <sys/types.h> /* RAISEDELAY */
#include <unistd.h>
#endif
+#include <unistd.h>
+#include <assert.h>
+#include <sys/fcntl.h>
extern void IconDown();
/* djhjr - 4/26/99 */
\f
+/***********************************************************************
+ *
+ * Procedures:
+ * HandleSignal use instead of signal
+ *
+ ***********************************************************************
+ */
+
+#define HANDLE_SIG_MAX 256 /* increase means changing type written to pipe */
+
+static SigProc signaltable[HANDLE_SIG_MAX];
+static int sigselfpipe[2] = { -1, -1 };
+
+static void
+SelfPipeHandler(sig)
+ int sig;
+{
+ unsigned char sigchar = sig;
+ int esave;
+
+ esave = errno;
+ write(sigselfpipe[1], &sigchar, 1);
+ errno = esave;
+}
+
+void
+HandleSignal(sig, func)
+ int sig;
+ SigProc func;
+{
+ struct sigaction sa;
+ int r, i;
+
+ if (sigselfpipe[0] == -1) {
+ r = pipe(sigselfpipe);
+ if (r) { perror("pipe for signals"); exit(-1); }
+ for (i = 0; i < 2; i++) {
+ r = fcntl(sigselfpipe[i], F_GETFL);
+ if (r<0) { perror("fcntl get for pipe"); exit(-1); }
+ r |= O_NONBLOCK;
+ r = fcntl(sigselfpipe[i], F_SETFL, r);
+ if (r<0) { perror("fcntl get for pipe"); exit(-1); }
+ }
+ }
+
+ assert(sig < HANDLE_SIG_MAX);
+
+ r = sigaction(sig, NULL, &sa);
+ if (r) { perror("sigaction get"); exit(-1); }
+
+ if (sa.sa_handler != SIG_DFL)
+ return;
+
+ signaltable[sig] = func;
+ memset(&sa, 0, sizeof(sa));
+ sa.sa_handler = SelfPipeHandler;
+ sigemptyset(&sa.sa_mask);
+ sa.sa_flags = SA_RESTART;
+ r = sigaction(sig, &sa, NULL);
+ if (r) { perror("sigaction set"); exit(-1); }
+}
+
/***********************************************************************
*
* Procedure:
void
HandleEvents()
{
+ struct pollfd pfds[2];
+ pfds[0].fd = ConnectionNumber(dpy);
+ pfds[0].events = POLLIN|POLLPRI;
+ pfds[1].fd = sigselfpipe[0];
+ pfds[1].events = POLLIN|POLLPRI;
+ sigset_t emptyset;
+ sigemptyset(&emptyset);
+
while (TRUE)
{
if (enter_flag && !QLength(dpy)) {
InstallWindowColormaps(ColormapNotify, (TwmWindow *) NULL);
}
WindowMoved = FALSE;
- XNextEvent(dpy, &Event);
+ while (!XCheckMaskEvent(dpy, -1 /* wot no AllEventMask */, &Event)) {
+ int r;
+ unsigned char signum;
+ r = poll(pfds, 2, -1);
+ if (r<0 && errno!=EINTR) {
+ perror("vtwm: poll failed");
+ exit(-1);
+ }
+ for (;;) {
+ r = read(sigselfpipe[0], &signum, 1);
+ if (r < 0) {
+ if (errno == EINTR) continue;
+ if (errno == EAGAIN) break;
+ if (errno == EWOULDBLOCK) break;
+ perror("vtwm: read signal self-pipe");
+ exit(-1);
+ }
+ if (!r) {
+ fputs("signal self-pipe read EOF!",stderr);
+ exit(-1);
+ }
+ assert(signum < HANDLE_SIG_MAX);
+ assert(signaltable[signum]);
+ signaltable[signum](signum);
+ }
+ }
(void) DispatchEvent ();
}
}
/* djhjr - 6/22/01 */
#ifndef NO_SOUND_SUPPORT
#define sounddonehandler(sig) \
- if (signal (sig, SIG_IGN) != SIG_IGN) (void) signal (sig, PlaySoundDone)
+ HandleSignal (sig, PlaySoundDone)
#else
#define sounddonehandler(sig) \
- if (signal (sig, SIG_IGN) != SIG_IGN) (void) signal (sig, Done)
+ HandleSignal (sig, Done)
#endif
#define donehandler(sig) \
- if (signal (sig, SIG_IGN) != SIG_IGN) (void) signal (sig, Done)
+ HandleSignal (sig, Done)
sounddonehandler (SIGINT);
sounddonehandler (SIGHUP);
#undef donehandler
/* djhjr - 7/31/98 */
- signal (SIGUSR1, QueueRestartVtwm);
+ HandleSignal (SIGUSR1, QueueRestartVtwm);
Home = getenv("HOME");
if (Home == NULL)