From: qualtrak@netcom.com (Qual Trak)
Newsgroups: comp.windows.x
Subject: Xt and Signals Re-Re-Re-Revisited
Summary: Signals under Xt - a technique.
Keywords: Xt signal
Date: 24 Jul 92 15:49:49 GMT
Reply-To: jb@QualTrak.COM
Distribution: usa
Organization: QualTrak Corporation


	After reading the various articles and letters in TXJ and following
some of the articles in this news group, I worked out the following code
to use as a more or less generic signal handling package under Xt (in
this case Motif).  I understand that all bets are off if I try and run
this under SysVR3 or earlier (I'm hoping I don't have to) - But assuming
the presence of BSD style signal handling Does anyone see any
significant gotchas in using this model for signal handling.  I
specifically need this code for forking () off children that write back
to me via a pipe - I can add an input handler to read the pipe but I
can't tell if the child died without catching SIGCHLD - Thus the need
for something like this...

	As a quick overview the user call x_signal (signo, func) just as she
would call signal ().  We're assuming that X initialization has already
taken place.  X_signal () then initializes the signal catching routines
by creating a pipe and installing x_sig_dispatcher () as a reader proc on
that pipe with XtAppAddInput (). X_sig_handler () is then attached to
the signal requested and the func argument is placed in the dispatch
table.  When a signal arrives, x_sig_handler () writes the one byte
signal number out to the pipe and returns.  X_sig_dispatcher is called
out of XtAppMainLoop () as an XtInputEventCallbackProc and he reads the
pipe, figures out which signal to call and if there's a valid handler in
the dispatch table, it's called.

As I said before - I understand all bets are off with SysVR3 and earlier
as well as other Operating Systems I may not know about.  At first blush
this stuff appears to work in a robust manner (SunOS 4.1.2, X11R5, Motif
1.1.4) Does anybody see anything significantly wrong with the concept?
Specifically does this share any of the problems associated with the
Timer Callback and WorkProc solutions in terms of mucking with the
internal state of X.

------------------------------------------------------------------------
#include <errno.h>
#include <signal.h>
#include <stdio.h>
#include <X11/Intrinsic.h>

extern Widget toplevel;

typedef struct _tag_sig_dispatch
{
	void (*handler) ();
} SignalDispatch;

static int SigInit = False;
static int sig_fd [2] = { 0 };

static SignalDispatch sig_d_table [33] = { 0 };




void
x_sig_dispatcher (XtPointer client_data, int *fid, XtInputId *id)
{
	char sigbuf [1];
	int  nread, signo;
	if ((nread = read (*fid, sigbuf, 1)) == -1)
		perror ("x_sig_dispatcher");
	else
	{
		sigbuf [nread] = 0;
		signo = (int) sigbuf [0];
		if (signo > 0                           &&
			signo < XtNumber (sig_d_table)      &&
			sig_d_table [signo].handler != NULL    )
			sig_d_table [signo].handler ();
	}
}




static void
x_sig_handler (sig)
int sig;
{
	char buf [1];
	buf [0] = (char) sig;
	write (sig_fd [1], buf, 1);
}




void *
x_signal (int signo, void (*handler) ())
{
	void ((*rval) ()) = NULL;

	if (signo > 0                      &&
		signo < XtNumber (sig_d_table)    )
	{
		/*
		 * If it's a valid signal number
		 */
		if (SigInit == False)
		{
			if (pipe (sig_fd) < 0)
				return SIG_DFL;
			
			XtAppAddInput (XtWidgetToApplicationContext (toplevel),
						   sig_fd [0],
						   (XtPointer) (XtInputReadMask | XtInputExceptMask),
						   x_sig_dispatcher, NULL);
			SigInit = True;
		}
		sig_d_table [signo].handler = handler;
		rval = signal (signo, (handler != SIG_IGN && handler != SIG_DFL)?
					   x_sig_handler:handler);
	}
	return rval;
}
/*
------------------------------------------------------------------------
John Birchfield - QualTrak Corp (408) 730-2674 Home (408) 736-3852
jb@QualTrak.COM
------------------------------------------------------------------------
*/
Newsgroups: comp.windows.x