Post by Janis PapanagnouThere's one point, though, that unsettles me a bit. The setvbuf()
"The setvbuf() function may only be used after opening a stream
and before any other operations have been performed on it."
As of C99, the freopen function allows the path argument to be null.
You should be able to do this:
FILE *new_stream = freopen(NULL, "r", old_stream);
After this the old_stream object is toast. The new_stream object
is open to the same file/device.
Since no operations have been done on new_stream at this point,
we should be able to change the buffering mode to whatever
we want.
The downside is that we have to replace all copies of the old_stream
pointer with new_stream. (Easly done if we have some context structure
that holds the stream, where only that context structure is shared).
Post by Janis PapanagnouIn my code I've experimented; I made a couple initial outputs on
stdout, made a fflush() to serve my paranoia, and then switched to
unbuffered output. I also switched forth and back from unbuffered
to line-buffered output in a loop. - It *seems* to work at least.
I would say all bets are off. Even if it works, there could be a memory
leak. The requirements allow a FILE stream to lazily allocate the
buffer. E.g. there can be a null pointer there, and when the first
operation notices this, it mallocs a buffer. Thus setvbuf can just
blindly store a pointer, without trying to free anything, such that it
results in a memory leak if it is used after a buffer is allocated.
To test that we can write a loop which repeatedly opens a stream,
performs some I/O, and then changes the buffer and closes,
monitoring the program for leaks.
Post by Janis PapanagnouAny experiences with the restriction documented in the man page,
or opinions and suggestions on the mode-switching I intend to do?
If it's a Linux man page, do not trust that. Linux man pages
are second-hand information cribbed from multiple sources.
Note that Linux systems have more than one C library, yet
those pages from the Linux man page project are the same!
Sometimes it's just copy and paste or paraphrasing from POSIX
or ISO C.
If you're on glibc, the documentation for setvbuf is this:
https://sourceware.org/glibc/manual/html_mono/libc.html#Controlling-Buffering
It doesn't mention anything about this issue, which means it remains
undefined behavior (i.e. glibc isn't providing a documented extension
whereby buffering can be changed after other operations have been done).
glibc is actually implementing POSIX, but regarding setvbuf, POSIX
defers all the requirements to ISO C. It carries forward the
restriction.
--
TXR Programming Language: http://nongnu.org/txr
Cygnal: Cygwin Native Application Library: http://kylheku.com/cygnal
Mastodon: @***@mstdn.ca