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 ===========================================================================