[comp.windows.x] XtAddInput question

wendar@wiley.UUCP (Wendar Fu) (05/03/90)

I'm a new x user, and I am having problem using XtAddInput().

I'm trying to write a program that forks a child process, and the
parent process captures all the data that goes to standard output
and standard error from the child process, and process them.
The problem I have is it seems to enter an infinite loop, in which
the handler routine is called repeatedly.  The simplified program follows:

------------------------
char	*btn_text;

main(argc, argv)
unsigned int argc;
char **argv;
{
	int	n, i;
	int	cpid, fd[2];
	Widget	toplevel, button;
	Arg	args[10];

	toplevel = XtInitialize("main", "XMdemos", NULL, NULL, &argc, argv);
	btn_text = XmStringCreateLtoR("Push to Quit", XmSTRING_DEFAULT_CHARSET);
	n = 0;
	XtSetArg(args[n], XmNlabelType, XmSTRING); n++;
	XtSetArg(args[n], XmNlabelString, btn_text); n++;
	button = XtCreateManagedWidget("button", xmPushButtonWidgetClass,
		toplevel, args, n);
	XtAddCallback(button, XmNactivateCallback, activateCB, NULL);

	fd[0] = fd[1] = -1;	/* initialize file descriptors */
	if(pipe(&fd[0]) != 0)
	{
		printf("main: pipe call failure\n");
		exit(-1);
	}

	/* set all file descriptors execept stdin, stdout, stderr, and the */
	/* that will be used by the new process for pipes, to be closed */
	/* when the new process is forked */
	for(i=3; i<getdtablesize(); i++)
	{
		if ((i==fd[0]) || (i==fd[1]))
			fcntl(i, F_SETFD, 0);	/* keep open through fork */
		else
			fcntl(i, F_SETFD, 1);	/* close during fork */
	}

	/* fork the child process */
	switch(cpid = fork())
	{
	case 0:		/* child process */
		/* Close fd[0] and assign stdout(1) and stderr(2) to fd[1]. */
		/* Once this is done, fd[1] can be closed */
		close(fd[0]);
		dup2(fd[1], 1);		/* stdout */
		dup2(fd[1], 2);		/* stderr */
		close(fd[1]);
		execl("child", 0);
		exit(1);
	case -1:	/* fork failed */
		printf("main: forking child process failure\n");
		/* close all opened descriptors created by pipe call */
		for(i=0; i<2; i++)
		{
			if (fd[i] >= 0)
				close(fd[i]);
		}
		exit(-1);
	default:	/* parent process */
		close(fd[1]);
		XtAddInput(fd[0], XtInputReadMask, handler, 0);
		break;
	}

	XtRealizeWidget(toplevel);
	XtMainLoop();
	close(fd[0]);
}

void activateCB(w, client_data, call_data)
Widget	w;
caddr_t	client_data;
caddr_t	call_data;
{
	XtFree(btn_text);
	exit(-1);
}


void handler()
{
	/* read message from file descriptor and manages them */
}

-------------------

The child process does nothing except for print a line to its standard
error every couple of seconds.  The handler routine is stilled called
repeated when:
	(1)	execl() is not called,
	(2)	fd[0] and fd[1] are not closed.

Please respond if you have see any error, or if you have a different
approach to handle this.

Thanks in advance!

--- Wendar ---

daf@cavern.mitre.org (Dennis A. Franciskovich) (01/19/91)

If anyone saved or understood the recent discussion about XtAddInput
with files, could you please contact me?  I didn't pay close attention
at the time, and now I've discovered that I'm having the same "problem".

Apparently there is a difference when waiting on input for a pipe and
when waiting on input from a file.  If I wait for input on a pipe
(similar to the xbc example in Young's book), my callback is executed
only when there is new input on the pipe.  If the input source is
instead a file, the callback is executed constantly.  I recall someone
mentioning that when the source is a file, the callback is executed
when the file *can* be read, not just when there is new input to read.

Replying by email would probably be appropriate, since this was recently
discussed.  My apologies for duplicating a question.  I had wanted to
ask about this at the Xt BOF the other day, but that discussion was a
bit monopolized.  ( 1/2 :-)

Dennis
daf@cavern.mitre.org

marbru@attc.UUCP (Martin Brunecky) (01/21/91)

In article <1991Jan18.200129.21797@linus.mitre.org> daf@cavern.mitre.org (Dennis A. Franciskovich) writes:
>when the file *can* be read, not just when there is new input to read.

   Can someone explain to me what are the semantics and mechanisms of a file
   (not a pipe or a socket) that *can* be read but there is NO *new input* 
   to read ?????

   In my (aparently silly) imagination a readable file always has data
   available - i.e. there is nothing to wait for (except for disk latency
   which is totally unpredictable).
   The only questions may arise in regards to the EOF handling.

   In my *opinion*, the XtAddInput is intended as an alternate source of
   *input events*, not *application data*. I somehow can not imagine
   a *file* being a source of time-sequenced input events (though I can
   imagine a pipe there). Thus, it seems to me understandable that the
   XtAddInput does NOT automatically deal with EOF on a file, as the
   semantics of the "death of the input event source" is likely to be
   application specific.

   

-- 
=*= Opinions presented here are solely of my own and not those of Auto-trol =*=
Martin Brunecky                           {...}sunpeaks!auto-trol!marbru
(303) 252-2499                        (sometimes also:  marbru@auto-trol.COM )
Auto-trol Technology Corp. 12500 North Washington St., Denver, CO 80241-2404 

evans@decvax.DEC.COM (Marc Evans) (01/25/91)

In article <980@attc.UUCP>, marbru@attc.UUCP (Martin Brunecky) writes:
|> In article <1991Jan18.200129.21797@linus.mitre.org> daf@cavern.mitre.org (Dennis A. Franciskovich) writes:
|> >when the file *can* be read, not just when there is new input to read.
|> 
|>    Can someone explain to me what are the semantics and mechanisms of a file
|>    (not a pipe or a socket) that *can* be read but there is NO *new input* 
|>    to read ?????

From what I have been able to gather, people really should be doing a

    #ifdef unix
	XtInputId InId;
	CARD32 mask = XtInputReadMask | XtInputExceptMask;
	FILE *fp = popen("tail -f {filename}","r");
	
	if (fp)
	{ InId = XtAppAddInput(appC,fileno(fp),mask,myfunc,NULL); }
    #endif

In other words, they seem to think that the XtAppAddInput and XtAddInput
functions should be performing the task performed by the u*x tail command.

- Marc
-- 
===========================================================================
Marc Evans - WB1GRH - evans@decvax.DEC.COM  | Synergytics     (603)635-8876
      Unix and X Software Contractor        | 21 Hinds Ln, Pelham, NH 03076
===========================================================================