Date:        Sat, 22 Nov 2025 11:08:16 +0100
    From:        Andreas Schwab <[email protected]>
    Message-ID:  <[email protected]>

  | On Nov 21 2025, Chet Ramey wrote:
  |
  | > Yes, this defeats the bash check. I tend to agree with kre that this is
  | > a Linux kernel bug, but here we are.
  |
  | I don't think so.  This can happen with any file (even "normal" regular
  | ones) if another process is modifying it just between the stat and the
  | read calls.

It is a kernel bug if it doesn't correctly report the actual amount of
data available to be read in the stat() interface ("always returns 4K"
indeed!)

Certainly there is a race condition between getting that size, and actually
doing the read, but that's up to the application to decide what is right.

If not getting the expected data (indicating that it is changing out from
under the application) is to be an error, then so be it - for some applications
that can be something that should never happen.

Others might want to repeat the whole operation, just to ensure that they
get consistent data, not something that is half from one version of the
file, and half from a newly modified one - in this case if the kernel's
stat() size and how much it actually delivers when the file is read is
never the same, eventually the application must error out (looks like some
other application is attempting to break it by detecting when the file is
being read, and changing it - or perhaps just constantly changing it).

And yet others might just detect it as a short read (which should only ever
happen on pipes, devices, network connections, fifo's etc - never a "normal"
file system file) and attempt to read the data not available when the first
read was done, until either all the data is obtained, or EOF.

There is really no one "required" behaviour of applications here, and if
the kernel believes there should be, and acts stupidly (for some absurd
efficiency hope I assume) then it should expect to be labelled as broken.

  | A short read is never an error, as you can see from the fact that errno
  | wasn't set.

That's kind of a meaningless thing to say - errno is only ever set when
read() returns -1, which is not a "short read".   Whether short reads are
errors of a different kind (ie: not kernel detected problems, like EIO etc)
depends upon the application.

An obvious example is reading UDP packets - for those, one read == 1 received
packet, always.   If the read returns less data that it should have (that is,
the sender sent less than the protocol demands) that is an error, but not
one the kernel can detect, so it will be a short read, with errno unaltered.

kre


Reply via email to