Path: utzoo!utgpu!news-server.csri.toronto.edu!cs.utexas.edu!sdd.hp.com!wuarchive!rex!uflorida!mlb.semi.harris.com!trantor.harris-atd.com!x102c!wdavis From: wdavis@x102c.harris-atd.com (davis william 26373) Newsgroups: comp.windows.x Subject: Re: How do I get XtAppAddInput to work correctly Message-ID: <5211@trantor.harris-atd.com> Date: 8 Jan 91 15:16:35 GMT References: <9101051037.AA02347@lightning.McRCIM.McGill.EDU> Sender: news@trantor.harris-atd.com Reply-To: wdavis@x102c.ess.harris.com (davis william 26373) Organization: Harris Corporation GSS, Melbourne, Florida Lines: 110 I quoted from Part 3 of Frequently Asked Questions: >>>> I am using XtAppAddInput to read from a file, but the function is >>>> called even when there isn't input pending. >>> XtAppAddInput is actually working as it is supposed to. When used >>> on files, it is called whenever the file is READY to be read, not >>> when there is new data to be read. In article <1991Jan4.221250.5174@athena.mit.edu>, bjaspan@athena.mit.edu (Barr3y Jaspan) writes: >> wdavis is incorrect; XtAddInput calls the procedure when there is >> DATA TO READ. Which is exactly what I expected from the documentation. When this didn't work, I posted my query. >> All XtAddInput does, for functions registered with >> XtInputReadMask, is call select and then calls those procedures whose >> filedescriptor is set in the fdset returned from select. Actually, I was asking about XtAppAddInput as my documentation on Xt Intrinsics claims that XtAddInput is obsolete and has been replaced by XtAppAddInput. The only difference in the documentation is that the obsolete one always uses the default application context and the one I was using requires you to specify it. I got the context from the ApplicationShell widget surrounding a list that was being kept updated from the bottom of a file. I assume the internals are similar for both routines. In article <9101051037.AA02347@lightning.McRCIM.McGill.EDU> mouse@lightning.mcrcim.mcgill.EDU writes: >This is not "when there is DATA TO READ". Even ignoring the question >of select()'s semantics when applied to files, it sometimes returns >when no data are available, such as a socket connection which has >reached EOF (ie, all write ends shut down). Having Xt Intrinsics claim to provide a function when it just uses underlying select semantics is misleading. If XtAppAddInput wants to claim it provides a particular function, then it should provide that function. If it just intends to be a wrapper for select then that is what it should claim. At least then it becomes a simple matter to test out select semantics and know what to expect for a particular release of Unix. >> I have only used XtAddInput for filedescriptors connected to >> pipes/sockets/etc, never for a file. > >Then why are you making pronouncements about what it - or rather, the >presumably related XtAppAddInput - does when applied to files? > >> Perhaps your problem is the result of peculiar select() semantics. >> When EOF is reached on a filedescriptor, select() will return that >> *there is data waiting to be read on it* even though there isn't. >> Any subsequent read() from that descriptor will return 0 bytes, which >> indicates that it has been closed > >If it had been closed, the read would return -1 with errno set to EBADF >(unless of course something else had been opened up since, and gotten >the same descriptor). 0 means the descriptor is still open, but at >EOF. > >The semantics select() is supposed to provide are not entirely clear. >All the descriptions available to me simply say "ready for reading". I >have seen this stated as "a read() will not block", which is what I >observe from sockets. I, too, have not tried using select() on files, >but if it truly does provide "read() will not block" indications, then >select()ing a file for reading will always indicate readability. >(Unless, presumably, the file is on a dead NFS server :-) > > der Mouse Well, based on this discussion, I wrote a simple program to test select semantics on files and pipes. For the version of Unix I am using (your mileage may vary), select will block when used on an open pipe with no data (as expected). It also blocks after a read of an end of file indication (end of files can be put into a stream and followed by more data without bothering select). Multiple end of file indications without intervening data cause the pipe to be closed. I did my pipe testing with a simple "cat" command and did not investigate how the Ctrl-D typed to cat actually translated to an EOF down the pipe. When select was applied to a file, the select returned "ready for reading" (from select(2) documentation here) when there was data to read or the current file position was at end of file. I did not try positioning the file position to weird places as this would not have helped my application (I need to track things as they are written to a file). So, the conclusion is that XtAppAddInput on files is only useful to read in a file one time. And it is clearly the hard way to go about it. I only see that as useful if the file read needs to proceed in parallel with user events (a big file or something that needs to allow a user cancel event during the read). Lacking any better suggestions (one suggestion here involved generating special X events to indicate it was time to look at the file), I decided to fork a process on a pipe. I forked a copy of "tail +0f filename" and use XtAppAddInput on the read side of the pipe. It seems to be working fine. Long term, it would be desirable to have X provide a lower overhead method of doing this, but I don't know a good way at the moment when select does not want to provide the functionality. What it sounds like is needed for this type of application (basically a fancy tail command under X) is to have a way to specify to Unix that select should not consider a file at end of file as readable. In this way, a program could read to the end of file, change (via fcntl) the select semantics and not be bothered until something became appended. Then , if desired, the select semantics could be toggled if it was important not to get tied up with a read of all available input in one call to the input function.