bjaspan@athena.mit.edu (Barr3y Jaspan) (01/20/91)
There seems to be a great deal of confusion about how to use XtAddInput to read data from a source (regardless of what kind of source it is). Enclosed below is a newer version of the example I've posted several times before that works for pipes (specifically, stdin) and files. You can think of it as a horribly inefficient and limited form of the 'cat' program. :-) The confusing point seems to be that the registered input procedure gets called continuously after a certain point. As I explained in my previous message, this occurs when end-of-file is reached but the file is not closed and the input procedure is not removed with XtRemoveInput. Notice that in the example below, the file is actually closed and the procedure unregistered when EOF occurs. Uncommenting those two lines causes the previously described (losing) behavior. Next week's lesson will cover why XtAddInput for output sinks (using XtInputWriteMask) does not do what you expected. :-) (Disclaimer: This program was tested on an IBM RT running a 4.3BSD-based system. Your mileage may vary, particularly if your system does not have the open(), read(), and close() syscalls.) -- Barr3y Jaspan, bjaspan@mit.edu Watchmaker Computing ---- snip snip ---- #include <stdio.h> #include <X11/Intrinsic.h> #include <X11/StringDefs.h> #include <X11/Xaw/Label.h> void input(); main(argc, argv) int argc; char **argv; { Widget top; int fd; top = XtInitialize("Hello", "World", NULL, 0, &argc, argv); if (argc == 2) { fprintf(stderr, "Reading input from file \"%s\".\n", argv[1]); fd = open(argv[1], "r", 0); if (fd == -1) { perror("opening file"); exit(1); } } else { fprintf(stderr, "Reading input from stdin.\n"); fd = 0; } (void) XtCreateManagedWidget("label", labelWidgetClass, top, NULL, 0); XtAddInput(fd, XtInputReadMask, input, NULL); XtRealizeWidget(top); XtMainLoop(); } void input(client_data, source, input_id) caddr_t client_data; int *source; XtInputId *input_id; { char buf[BUFSIZ]; int c; c = read(*source, buf, BUFSIZ); fprintf(stderr, "%d bytes read on fd %d.\n", c, *source); if (c == 0) { fprintf(stderr, "closing file.\n"); close(*source); XtRemoveInput(*input_id); } else if (c == -1) { perror("reading from file"); exit(1); } else { buf[c] = 0; printf("\"%s\"\n", buf); bzero(buf, c); } }