On 4/17/22 18:10, Chet Ramey wrote:
> On 4/16/22 2:58 PM, Rob Landley via austin-group-l at The Open Group wrote:
>> Q) "How do I switch from FILE * to fd via fileno() without losing data."
>> 
>> A) "Don't use FILE *"
>> 
>> That's not the question I asked?
> 
> The answer is correct, but incomplete. The missing piece is that if you
> want to use FILE *, the operation you want, and the information you need to
> implement it, are not part of the public API.

Which is a fixable problem.

> Other than using a strategy like Geoff suggested early on, or trying
> something like setvbuf to turn off buffering on the FILE * completely, the
> buffer associated with a FILE * and the indexes into it that say how much
> data you've consumed from the underlying source are opaque.

https://github.com/coreutils/gnulib/blob/master/lib/freadahead.c

https://sources.debian.org/src/m4/1.4.18-2/lib/freadahead.c

> If you want to
> manipulate that information, or expose it to a caller, you can't use FILE *
> (or, if you want a direct answer, "you can't").

The if/else staircase in m4 and gnulib and so on says I can. I was just
wondering if there was a _clean_ way to do it. (The gnu lot exposed it as part
of glib's exports, but glib's license isn't compatible with my projects and
pulling in a library like that just for one accessor function to read an integer
out of a struct is a bit silly anyway.)

The C99 guys point out they haven't got file descriptors and thus this would
logically belong in posix, for the same reason fileno() does. "But FILE *
doesn't have a way to fetch the file descriptor" was answered by adding
fileno(). That is ALSO grabbing an integer out of the guts of FILE *.

> I found it easier to write my own buffered input package to satisfy the
> POSIX read ahead requirements than try to coerce stdio into doing it.

Reimplementing FILE * from scratch and not using the ANSI one is a common way to
address this limitation, yes. So is the if/else staircase of libc specific
hacks. Or in the case of musl (and now bionic, according to the end of
http://lists.landley.net/pipermail/toybox-landley.net/2022-April/012824.html)
adding __freadahead(fp) to return the number of bytes in the buffer.

Z/OS has it too:

https://www.ibm.com/docs/en/zos/2.3.0?topic=lf-freadahead-retrieve-number-bytes-remaining-in-input-buffer

Of course the lack of standardization means that Dragonfly BSD called theirs
"__sreadahead()" instead...

https://github.com/DragonFlyBSD/DragonFlyBSD/blob/master/lib/libc/stdio/sreadahead.c

But can you really say it's opaque when so many independent reimplementations of
how to access it already exist?

This exists. It would be nice if it got standardized.

Rob

Reply via email to