[comp.unix.questions] tail -f

jbr0871@fedeva.UUCP (Blaine Robertson) (12/07/88)

Can someone please tell me how 'tail -f' works?.  Obviously, it does not
do a busy loop while doing a stat on the file.  I know that it has got
to be blocked, waiting for the length to change, but how does it get
notified of a change?  Thanks in advance for any responses.

-- 
Blaine Robertson
Federal Express, Memphis, TN
[..!mirror!premise, ..gatech!emcard]!fedeva!jbr0871

gwyn@smoke.BRL.MIL (Doug Gwyn ) (12/07/88)

In article <412@fedeva.UUCP> jbr0871@fedeva.UUCP (Blaine Robertson) writes:
>Can someone please tell me how 'tail -f' works?.  Obviously, it does not
>do a busy loop while doing a stat on the file.

All it does is to sleep for a short time (around one second), then
copy out everything past the last high water mark via read/write.
There is no statting, no asynchronous notification, no nonblocking
I/O, etc.  It IS a "busy loop" (except for the short sleep).

jds@mimsy.UUCP (James da Silva) (12/08/88)

In article <412@fedeva.UUCP> jbr0871@fedeva.UUCP (Blaine Robertson) writes:
>Can someone please tell me how 'tail -f' works?.  Obviously, it does not
>do a busy loop while doing a stat on the file.  I know that it has got
>to be blocked, waiting for the length to change, but how does it get
>notified of a change?  Thanks in advance for any responses.

Actually, tail doesn't get notified of a change.  It simply sleeps for a
second, then tries a read().  Probably something like this:

	while(1) {
		sleep(1);
		while(size=read(file,buffer,BSIZE))
			write(1,buffer,size);
	}

Nothing fancy, I'm afraid.

Jaime
...........................................................................
: domain: jds@mimsy.umd.edu				     James da Silva
: path:   uunet!mimsy!jds

rick@kimbal.UUCP (Rick Kimball) (12/08/88)

From article <412@fedeva.UUCP>, by jbr0871@fedeva.UUCP (Blaine Robertson):
> Can someone please tell me how 'tail -f' works?.  Obviously, it does not
> do a busy loop while doing a stat on the file.  I know that it has got
> to be blocked, waiting for the length to change, but how does it get
> notified of a change?  Thanks in advance for any responses.


My guess is that it sleeps for a second and then tries to
read more data.





-- 
____________________________________________________________________________
Rick Kimball | Mac Source BBS, Altamonte Springs, FL     DATA (407) 862-6214
             |                                          VOICE (407) 788-6875
UUCP: rick@kimbal ..!gatech!fabscal!kimbal!rick ..!ucf-cs!sdgsun!kimbal!rick

guy@auspex.UUCP (Guy Harris) (12/09/88)

>Can someone please tell me how 'tail -f' works?.  Obviously, it does not
>do a busy loop while doing a stat on the file.  I know that it has got
>to be blocked, waiting for the length to change, but how does it get
>notified of a change?  Thanks in advance for any responses.

Oh, dear, he used the "O" word.  One should be careful using that
word....

In fact, it *does* do a busy loop while doing "read"s (not "stat"s) of
the file; it just sleeps 1 second between attempts to "read", so it
doesn't burn quite so much CPU doing it.  If there were some way for it
to block waiting for the length to change, it would; however, there
isn't any such way. 

decot@hpisod2.HP.COM (Dave Decot) (12/10/88)

> >Can someone please tell me how 'tail -f' works?.  Obviously, it does not
> >do a busy loop while doing a stat on the file.  I know that it has got
> >to be blocked, waiting for the length to change, but how does it get
> >notified of a change?  Thanks in advance for any responses.
> 
> Oh, dear, he used the "O" word.  One should be careful using that
> word....
> 
> In fact, it *does* do a busy loop while doing "read"s (not "stat"s) of
> the file; it just sleeps 1 second between attempts to "read", so it
> doesn't burn quite so much CPU doing it.  If there were some way for it
> to block waiting for the length to change, it would; however, there
> isn't any such way. 

I suppose it could use select(2)...

Dave

guy@auspex.UUCP (Guy Harris) (12/11/88)

>I suppose it could use select(2)...

You suppose incorrectly.  I know of no UNIX system where "select" will
permit you to wait for a regular file (as in S_IFREG) file to be
modified....

mirk@warwick.UUCP (Mike Taylor) (12/12/88)

>>>Can someone please tell me how 'tail -f' works? ...
>>In fact, it *does* do a busy loop while doing "read"s (not "stat"s) of
>>the file; it just sleeps 1 second between attempts to "read" ...
>I suppose it could use select(2)...

Not necessarily - select(2) is a Berkeleyism, I believe, so code written
using it is not portable to older Unices - Vanilla V7, for instance.
I must agree that it would be a far more elegant solution, though.
I am surprised that it hasn't been re-written for Berkeley systems.
______________________________________________________________________________
Mike Taylor - {Christ,M{athemat,us}ic}ian ...  Email to: mirk@uk.ac.warwick.cs
*** Unkle Mirk sez: "Gm F#7 Bb Cm->Gm->Eb->Gm F; Gm F#7 Bb C Eb C Bb Dm D" ***
------------------------------------------------------------------------------

guy@auspex.UUCP (Guy Harris) (12/13/88)

 >Not necessarily - select(2) is a Berkeleyism, I believe, so code written
 >using it is not portable to older Unices - Vanilla V7, for instance.
 >I must agree that it would be a far more elegant solution, though.
 >I am surprised that it hasn't been re-written for Berkeley systems.

I'm not at all surprised, since even on a Berkeley system you can't use
"select()" to wait for somebody to write something to a regular file.

moss@BRL.MIL (VLD/VMB) (12/13/88)

>>I suppose it could use select(2)...
>
>You suppose incorrectly.  I know of no UNIX system where "select" will
>permit you to wait for a regular file (as in S_IFREG) file to be
>modified....
Right, he was probably referring to a non-blocking read which won't help
since blocking is really what you want.  Anyway, I haven't looked at the
source for 'tail', but I wrote an asynchronous log file monitoring
subroutine to allow the contents of an interactive program's log file to
be displayed in a scrolling window.  A subroutine gets called from an
alarm signal handler which loops on fgets() until one fails, then does a
clearerr() (only necessary on some systems like 4.2 BSD) to clear the EOF
condition.  Then, the signal handler resets the alarm for N seconds.  Of
course you can use sleep() instead of the alarm() call/handler if you
want.

-moss

dce@mips.COM (David Elliott) (12/14/88)

No, you can't use select, but tail can be made a little smarter.

In Tektronix's UTek, tail -f has a "back-off" for the timing of the
loop.  After 10 failed reads, the sleep time is increased by some
amount (with some upper limit, of course).  Tim Knox, who was at Intel
last I saw, might remember the details, as he was the person that
wrote the code.

In any event, it made a tail -f that was running for no reason not
take up so much time.

-- 
David Elliott		dce@mips.com  or  {ames,prls,pyramid,decwrl}!mips!dce
"Did you see his eyes?  Did you see his crazy eyes?" -- Iggy (who else?)

guy@auspex.UUCP (Guy Harris) (12/15/88)

>Right, he was probably referring to a non-blocking read which won't help
>since blocking is really what you want.

*Ahem* a non-blocking "read" on a regular file is no different from a
blocking "read" on the same file under most versions of UNIX.  Folks,
there really, truly, honestly *is* no special magic feature of e.g. 
4.xBSD that obviates the need for the "sleep and try again" stuff....