Hacker News new | ask | show | jobs
by spatz 4093 days ago
The problem is that less +F polls every second while tail -f uses inotify, which is both more efficient and responds faster to change.
2 comments

There was a time when tail didn't know inotify. It was so, so much better when it learned that trick.

There was also a time when there was a utility called inotail, bridging that gap until tail proper was improved. I very much preferred it over regular tail.

I always thought it was such a shame that you couldn't use plain poll() for this. poll()-ing on a read fd at EOF for a regular file should work like poll()-ing a network socket.
The problem is in what concepts are being considered "the same" when mapping two mostly-dissimilar things (a socket or pipe, vs a file).

poll(), select() et al don't define "readable" as meaning "a byte of data is available". They define it as "read() will not block".

When you read to the end of a file, read() returns "". This is the same as when you try to read from a closed socket. Conceptually, they are linking the concepts of "EOF" and "closed", not the concepts of "EOF" and "waiting for data". And indeed, if you call poll() on a socket that has been closed on the remote end, you will find it is "readable".

Ultimately, regular files just were never intended to be used as pipes. The abstractions just weren't chosen to work in that way.

> poll(), select() et al don't define "readable" as meaning "a byte of data is available". They define it as "read() will not block".

If that were true, poll() wouldn't return read-ready on a file-based fd until the data was actually sitting in buffers. After all, that's the only way to guarantee it won't block. That would actually be a useful semantic.

But what actually happens is that poll() on a file-based fd is basically a no-op that always returns true immediately, AFAIK. Someone could pull the disk drive cable before you actually call read(), in which case read() will indeed block, forever.

The existing semantic is useless. What argument is there in favor of a useless semantic?

This semantic wouldn't solve the "tail -f" problem, but at least it would be useful: http://cr.yp.to/unix/asyncdisk.html

You can use kqueue/kevent to poll on a file. That's what tail(1) and other system utilities are using.