On 2025-01-24, Paul Edwards <
mutazilah@gmail.com> wrote:
"Keith Thompson" <Keith.S.Thompson+u@gmail.com> wrote in message
news:87plkc6bgm.fsf@nosuchdomain.example.com...
"Paul Edwards" <mutazilah@gmail.com> writes:
[...]
With the benefit of hindsight, is there any reason why fpeek
couldn't have been added to C90, with implementations
being allowed with just a macro that returns some sort of
"unsupported"?
>
If fpeek (or similar) makes sense, can someone suggest an
appropriate interface?
[...]
>
It would help to know what "fpeek" is supposed to do. There no such
function in any edition of the C standard or in any implementation
that I'm aware of.
>
fpeek would tell you whether there are any characters available
to be read, on a bidirectional data stream, opened with r+b or
whatever.
This functionality went into POSIX, which can be regarded
as a larger version of the C language with a lot more operating
system functionality, and lower portability (POSIX programs
require a POSIX C implementation, not just a C implementation).
C came from Unix, and was accompanied by a library of functions
like malloc, printf, open, read, write.
When a standardization effort was launched, two groups were formed:
one of the language and one for the OS.
The language one took the closer-to-the-language things like
printf and malloc and fopen.
The OS group took the system level things like open, read, write.
The fpeek function you're looking for can be writen in POSIX
as a combination of fileno (to obtain the integer file descriptor
from a FILE * stream) and a polling function like poll or select,
executed with a zero timeout.
Moreover, care has to be taken not to perform this test on
a stdio stream which itself has unread bytes in its won buffer;
it only makes sense when all bytes in the stream's buffer
have been removed.
The proper technique to use FILE * streams together with select/poll
based multiplexing is to either use unbuffered I/O, or else
non-blocking I/O.
In the PipeWatch program, I demonstrate the use of both in the
same event loop:
https://www.kylheku.com/cgit/pw/tree/pw.cThe program simultaneously reads interactive TTY input, and
updates a full-screen display, while also processing bulk data from
standard input. In case standard input is a pipe, it is set to
nonblocking mode (look for O_NONBLOCK). For the TTY, rather than
nonblocking mode, we set the standard I/O stream to unbuffered via
setvbuf.
When you put a file descriptor into nonblocking mode, then whenever the
standard I/O stream above it runs out of bytes, and the descriptor
doesn't have any, the I/O stream experiences an error, which it
translates to (for instance) an EOF return from getc(stream). errno
indicates EWOULDBLOCK. At that point you know you can use the poll
function to monitor the descriptor for the availability data. You have
remember to clearerr(stream) to remove the error state from the stdio
stream before retrying the input operation when the descriptor
indicates that it has data.
-- TXR Programming Language: http://nongnu.org/txrCygnal: Cygwin Native Application Library: http://kylheku.com/cygnalMastodon: @Kazinator@mstdn.ca