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
