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