Discussion:
fopen mode string flags for buffering control.
(too old to reply)
Kaz Kylheku
2016-03-18 20:50:11 UTC
Permalink
Raw Message
stdio streams allow buffering control, but it's closely associated
with the act of opening a stream. It is only defined to work if
a call to a function like setvbuf takes place before any I/O
operation.

There might as well be mode letters to control buffering, so
no API has to be used at all.

fopen("name", "r+bu"); // read/write binary, unbuffered

fopen("name", "r+bf2"); // fully buffered, 4096 bytes
// i.e. setvbuf(stream, 0, _IOFBF, 4096);

fopen("name", "r+l"); // line buffered
// i.e. setvbuf(stream, 0, _IOLBF, 0);

fopen("name", "r+l0"); // line buffered, 1024 byte buffer
// i.e. setvbuf(stream, 0, _IOLBF, 1024);


The letters f and l can be followed by an optional decimal digit D from 0
to 9 giving the binary exponential order of the buffer size,
such that the size is 1024 * pow(2, d) bytes.

0 = 1024, 1 = 2048, ..., 9 = 524288.

The nice thing about this is that any languages built in C benefit.
That is to say, if you have some language that has file/descriptor
opening functions that expose C fopen mode strings which are passed
down to fopen, freopen or the POSIX fdopen and popen, then it instantly
benefits: now that language has buffering control, without any
additional new API.
Keith Thompson
2016-03-18 21:24:55 UTC
Permalink
Raw Message
Post by Kaz Kylheku
stdio streams allow buffering control, but it's closely associated
with the act of opening a stream. It is only defined to work if
a call to a function like setvbuf takes place before any I/O
operation.
There might as well be mode letters to control buffering, so
no API has to be used at all.
fopen("name", "r+bu"); // read/write binary, unbuffered
fopen("name", "r+bf2"); // fully buffered, 4096 bytes
// i.e. setvbuf(stream, 0, _IOFBF, 4096);
fopen("name", "r+l"); // line buffered
// i.e. setvbuf(stream, 0, _IOLBF, 0);
fopen("name", "r+l0"); // line buffered, 1024 byte buffer
// i.e. setvbuf(stream, 0, _IOLBF, 1024);
The letters f and l can be followed by an optional decimal digit D from 0
to 9 giving the binary exponential order of the buffer size,
such that the size is 1024 * pow(2, d) bytes.
0 = 1024, 1 = 2048, ..., 9 = 524288.
The nice thing about this is that any languages built in C benefit.
That is to say, if you have some language that has file/descriptor
opening functions that expose C fopen mode strings which are passed
down to fopen, freopen or the POSIX fdopen and popen, then it instantly
benefits: now that language has buffering control, without any
additional new API.
My initial reaction is that it's too specific. The sytax allows one of
10 different buffer sizes, from 1024 to 524288. Perhaps that's useful
in practice, but why not allow 1048576? Or 1536?

If we're going to extend the syntax of the mode string, I suggest
defining a more flexible and human-readable syntax. (I don't have any
concrete suggestions for what it should look like.)

Existing practice: in Ada, the Open functions take a "Form" parameter
that's a string, defaulting to the empty string. The meaning of the
argument is, if I recall correctly, completely implementation-defined.
That's probably *too* flexible.
--
Keith Thompson (The_Other_Keith) kst-***@mib.org <http://www.ghoti.net/~kst>
Working, but not speaking, for JetHead Development, Inc.
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
Dag-Erling Smørgrav
2016-03-21 09:23:39 UTC
Permalink
Raw Message
Post by Keith Thompson
There might as well be mode letters to control buffering, so no API
has to be used at all. [...]
My initial reaction is that it's too specific. The sytax allows one
of 10 different buffer sizes, from 1024 to 524288. Perhaps that's
useful in practice, but why not allow 1048576? Or 1536?
(all section, paragraph and footnote numbers below refer to 9899:2011)

I would suggest f{N} or l{N}, where N is the desired buffer size in a
form recognized by strtoul() with the base argument set to 0. Leaving
out {N} is equivalent to specifying {0}. Replace {} with () or [] if
you like and / or if there is precedent for a similar syntax in other
functions either in C or in POSIX. I can't think of any off the cuff -
the printf() family places the precision and length before the
specifier, which would not work very well here.

Paragraph 3 of section 7.21.5.3 needs to be extended (or a new paragraph
inserted between the current paragraphs 3 and 4) to describe the u, f{N}
and l{N} suffixes, with reference to section 7.21.5.6 which describes
setvbuf().

Paragraph 8 needs to be modified, for instance by the insertion of
"unless otherwise specified in the mode string" after "When opened".

Paragraph 9 needs to be modified, for instance by the insertion of "or
the requested buffering mode and size could not be honored" after "if
the open operation fails".

Section 7.21.5.6 does not specify what happens if the buf argument is a
null pointer and the size argument is 0; in fact, it even suggests that
setvbuf() is free to ignore the size argument when the buf argument is a
null pointer.

(Note that per footnote 271, implementations are already free to
implement something like this as an extension)

DES
--
Dag-Erling Smørgrav - ***@des.no
Kaz Kylheku
2016-03-21 17:01:56 UTC
Permalink
Raw Message
Post by Dag-Erling Smørgrav
Post by Keith Thompson
There might as well be mode letters to control buffering, so no API
has to be used at all. [...]
My initial reaction is that it's too specific. The sytax allows one
of 10 different buffer sizes, from 1024 to 524288. Perhaps that's
useful in practice, but why not allow 1048576? Or 1536?
(all section, paragraph and footnote numbers below refer to 9899:2011)
I would suggest f{N} or l{N}, where N is the desired buffer size in a
form recognized by strtoul() with the base argument set to 0.
In my opinion, that is over-designed. It is not necessary to be able to
specify any buffer size down to the byte, in any base. If the difference
between 1500 and 1501 bytes is so critical, the program should just use
the setvbuf API.

I have modified my proposal since then, privately. I dropped the letter
'f' because full buffering is the default.

I have implemented a version of this in the stream library of a
non-C programming language:

http://www.nongnu.org/txr/txr-manpage.html#N-02B8FBBD

In this implementation, I also relaxed the mode strings you can omit
the "r". A mode string can be empty, in which case it specifies a
default mode. (In C that would always be "r"; in my language I have
some socket functions whose default is "r+b"). If only "+" is specified,
then it means "r+". So you can do (open-file "foo" "b3") and the "b3"
means "rb3": read binray with a 2**3 = 8 kilobyte buffer.

By the way, I thing I overlooked previously: in C, there is a
considerable convenience to the buffer size aspect of these extension.

If you use the setvbuf function, you currently must allocate a buffer
yourself, and take care of freeing it when done using the stream.

With this proposal, the buffer is managed by the stream; it goes away
automatically when you fclose.
Post by Dag-Erling Smørgrav
out {N} is equivalent to specifying {0}. Replace {} with () or [] if
you like and / or if there is precedent for a similar syntax in other
I don't like; it makes strings too verbose. It paves the path to an
ugly, unnecessary language developing within fopen mode strings.

A single undelimited digit is easy to recognize and convert to a size:
1024 << (digit - '0').

It coordinates well with the existing design in which single characters
are used to specify properties.

If you want exactly 15000 byte buffer, you just can't use this; too bad.
Learn to like 16384 and enjoy the terse convenience of specifying that
with just an order 4, or else use the API.
Jakob Bohm
2016-03-21 17:17:08 UTC
Permalink
Raw Message
Post by Kaz Kylheku
Post by Dag-Erling Smørgrav
Post by Keith Thompson
There might as well be mode letters to control buffering, so no API
has to be used at all. [...]
My initial reaction is that it's too specific. The sytax allows one
of 10 different buffer sizes, from 1024 to 524288. Perhaps that's
useful in practice, but why not allow 1048576? Or 1536?
(all section, paragraph and footnote numbers below refer to 9899:2011)
I would suggest f{N} or l{N}, where N is the desired buffer size in a
form recognized by strtoul() with the base argument set to 0.
In my opinion, that is over-designed. It is not necessary to be able to
specify any buffer size down to the byte, in any base. If the difference
between 1500 and 1501 bytes is so critical, the program should just use
the setvbuf API.
I have modified my proposal since then, privately. I dropped the letter
'f' because full buffering is the default.
I have implemented a version of this in the stream library of a
http://www.nongnu.org/txr/txr-manpage.html#N-02B8FBBD
In this implementation, I also relaxed the mode strings you can omit
the "r". A mode string can be empty, in which case it specifies a
default mode. (In C that would always be "r"; in my language I have
some socket functions whose default is "r+b"). If only "+" is specified,
then it means "r+". So you can do (open-file "foo" "b3") and the "b3"
means "rb3": read binray with a 2**3 = 8 kilobyte buffer.
Please note that on platforms where the native line end encoding is not
a single occurrence of the '\n' character (ASCII 10), the fopen flag
characters "b" and "t" are already used to indicate if the file handle
should transparently translate between single '\n' in the C interface
and the native encoding (such as '\r' or '\r\n') in the system calls or
not. One of those 2 letters is even part of the C standard already
(having no effect on systems where there is no such translation),
however the ability to explicitly specify either mode is a practical
necessity because the default is often affected by dynamic settings.

Some platforms (not sure which) may also have used other letters to
indicate other important options, such as automatic file locking, or
system level file types (on systems where a file is not simply a file,
such as some IBM systems).

Thus when proposing new standard fopen() mode letters, a survey of
already used letters is needed to avoid conflicts.




Enjoy

Jakob
--
Jakob Bohm, CIO, Partner, WiseMo A/S. https://www.wisemo.com
Transformervej 29, 2860 Søborg, Denmark. Direct +45 31 13 16 10
This public discussion message is non-binding and may contain errors.
WiseMo - Remote Service Management for PCs, Phones and Embedded
Kaz Kylheku
2016-03-21 17:49:31 UTC
Permalink
Raw Message
Post by Jakob Bohm
Post by Kaz Kylheku
Post by Dag-Erling Smørgrav
Post by Keith Thompson
There might as well be mode letters to control buffering, so no API
has to be used at all. [...]
My initial reaction is that it's too specific. The sytax allows one
of 10 different buffer sizes, from 1024 to 524288. Perhaps that's
useful in practice, but why not allow 1048576? Or 1536?
(all section, paragraph and footnote numbers below refer to 9899:2011)
I would suggest f{N} or l{N}, where N is the desired buffer size in a
form recognized by strtoul() with the base argument set to 0.
In my opinion, that is over-designed. It is not necessary to be able to
specify any buffer size down to the byte, in any base. If the difference
between 1500 and 1501 bytes is so critical, the program should just use
the setvbuf API.
I have modified my proposal since then, privately. I dropped the letter
'f' because full buffering is the default.
I have implemented a version of this in the stream library of a
http://www.nongnu.org/txr/txr-manpage.html#N-02B8FBBD
In this implementation, I also relaxed the mode strings you can omit
the "r". A mode string can be empty, in which case it specifies a
default mode. (In C that would always be "r"; in my language I have
some socket functions whose default is "r+b"). If only "+" is specified,
then it means "r+". So you can do (open-file "foo" "b3") and the "b3"
means "rb3": read binray with a 2**3 = 8 kilobyte buffer.
Please note that on platforms where the native line end encoding is not
a single occurrence of the '\n' character (ASCII 10), the fopen flag
characters "b" and "t" are already used to indicate if the file handle
should transparently translate between single '\n' in the C interface
and the native encoding (such as '\r' or '\r\n') in the system calls or
not.
Yes, that's the "b" I'm using above.
Post by Jakob Bohm
Thus when proposing new standard fopen() mode letters, a survey of
already used letters is needed to avoid conflicts.
Absolutely.
Dag-Erling Smørgrav
2016-03-22 08:43:15 UTC
Permalink
Raw Message
Post by Kaz Kylheku
Post by Dag-Erling Smørgrav
I would suggest f{N} or l{N}, where N is the desired buffer size in
a form recognized by strtoul() with the base argument set to 0.
In my opinion, that is over-designed. It is not necessary to be able
to specify any buffer size down to the byte, in any base.
On the contrary, it is a much simpler design, since it translates
directly into calls to existing library functions, which makes it easy
to describe and implement.
Post by Kaz Kylheku
I have modified my proposal since then, privately. I dropped the letter
'f' because full buffering is the default.
Full buffering is not the default in all cases, see section 7.21.5.3
paragraph 8. And even if it were, there is value in being explicit.
Post by Kaz Kylheku
If you use the setvbuf function, you currently must allocate a buffer
yourself, and take care of freeing it when done using the stream.
No, the buf argument can be a null pointer, in which case the size
argument is taken as a size hint for a buffer allocated by the
implementation itself.

And with all due respect, cf. <***@news.xs4all.nl> by
Richard Bos on Sunday.

DES
--
Dag-Erling Smørgrav - ***@des.no
Kaz Kylheku
2016-03-22 16:48:28 UTC
Permalink
Raw Message
Post by Dag-Erling Smørgrav
Post by Kaz Kylheku
Post by Dag-Erling Smørgrav
I would suggest f{N} or l{N}, where N is the desired buffer size in
a form recognized by strtoul() with the base argument set to 0.
In my opinion, that is over-designed. It is not necessary to be able
to specify any buffer size down to the byte, in any base.
On the contrary, it is a much simpler design, since it translates
directly into calls to existing library functions, which makes it easy
to describe and implement.
What?

if (isdigit(ch))
size = 1024 << (ch - '0');

Done.

"The King's Toaster": http://www.ee.ryerson.ca/~elf/hack/ktoast.html
Post by Dag-Erling Smørgrav
Post by Kaz Kylheku
I have modified my proposal since then, privately. I dropped the letter
'f' because full buffering is the default.
Full buffering is not the default in all cases, see section 7.21.5.3
paragraph 8. And even if it were, there is value in being explicit.
Sorry, I bungled my wording. I mean full buffering can just be the
default if a size is specified, and line buffering isn't, without
the letter 'f'. Fewer letters, smaller clash surface with existing
extensions.

(Would there be use in the behavior whereby if just a size is specified,
then it merges with the buffering strategy selected according to
device? That is, you get line buffering with the chosen buffer size
on an interactive device.)
Post by Dag-Erling Smørgrav
Post by Kaz Kylheku
If you use the setvbuf function, you currently must allocate a buffer
yourself, and take care of freeing it when done using the stream.
No, the buf argument can be a null pointer, in which case the size
argument is taken as a size hint for a buffer allocated by the
implementation itself.
Alas, that hint actually gets ignored!

For instance, on GNU/Linux systems based on glibc, I am still seeing
4096 byte reads after setvbuf(stream, 0, _IOFBF, 65536). If a buffer
pointer is passed in, then the library complies and issues 65536 byte
reads.

(Maybe this requirement should just be strengthened so it's not merely
a hint, but a requirement to allocate a buffer of that size as if
by malloc.)
Jakob Bohm
2016-03-22 16:59:58 UTC
Permalink
Raw Message
Post by Kaz Kylheku
Post by Dag-Erling Smørgrav
Post by Kaz Kylheku
Post by Dag-Erling Smørgrav
I would suggest f{N} or l{N}, where N is the desired buffer size in
a form recognized by strtoul() with the base argument set to 0.
In my opinion, that is over-designed. It is not necessary to be able
to specify any buffer size down to the byte, in any base.
On the contrary, it is a much simpler design, since it translates
directly into calls to existing library functions, which makes it easy
to describe and implement.
What?
if (isdigit(ch))
size = 1024 << (ch - '0');
Done.
"The King's Toaster": http://www.ee.ryerson.ca/~elf/hack/ktoast.html
Post by Dag-Erling Smørgrav
Post by Kaz Kylheku
I have modified my proposal since then, privately. I dropped the letter
'f' because full buffering is the default.
Full buffering is not the default in all cases, see section 7.21.5.3
paragraph 8. And even if it were, there is value in being explicit.
Sorry, I bungled my wording. I mean full buffering can just be the
default if a size is specified, and line buffering isn't, without
the letter 'f'. Fewer letters, smaller clash surface with existing
extensions.
(Would there be use in the behavior whereby if just a size is specified,
then it merges with the buffering strategy selected according to
device? That is, you get line buffering with the chosen buffer size
on an interactive device.)
Post by Dag-Erling Smørgrav
Post by Kaz Kylheku
If you use the setvbuf function, you currently must allocate a buffer
yourself, and take care of freeing it when done using the stream.
No, the buf argument can be a null pointer, in which case the size
argument is taken as a size hint for a buffer allocated by the
implementation itself.
Alas, that hint actually gets ignored!
For instance, on GNU/Linux systems based on glibc, I am still seeing
4096 byte reads after setvbuf(stream, 0, _IOFBF, 65536). If a buffer
pointer is passed in, then the library complies and issues 65536 byte
reads.
(Maybe this requirement should just be strengthened so it's not merely
a hint, but a requirement to allocate a buffer of that size as if
by malloc.)
Except where impractical for implementation reasons. For example on
platforms with small address spaces.

But I would definitely consider that a bug in glibc (not a standards
violation, just a bug).

Enjoy

Jakob
--
Jakob Bohm, CIO, Partner, WiseMo A/S. https://www.wisemo.com
Transformervej 29, 2860 Søborg, Denmark. Direct +45 31 13 16 10
This public discussion message is non-binding and may contain errors.
WiseMo - Remote Service Management for PCs, Phones and Embedded
Dag-Erling Smørgrav
2016-03-23 09:40:12 UTC
Permalink
Raw Message
Post by Kaz Kylheku
Post by Dag-Erling Smørgrav
On the contrary, it is a much simpler design, since it translates
directly into calls to existing library functions, which makes it easy
to describe and implement.
What?
if (isdigit(ch))
size = 1024 << (ch - '0');
Done.
Yeah, if you don't care if it works or not. There's a bug in the first
line. And you are completely ignoring "easy to describe".
Post by Kaz Kylheku
"The King's Toaster": http://www.ee.ryerson.ca/~elf/hack/ktoast.html
Cute story. Now find one that illustrates the futility of discussing a
standard with someone who clearly hasn't read it.
Post by Kaz Kylheku
Post by Dag-Erling Smørgrav
Full buffering is not the default in all cases [...]
Sorry, I bungled my wording. [...]
You realize that you just proved that your proposed solution is more
complicated to explain and understand than mine?
Post by Kaz Kylheku
Post by Dag-Erling Smørgrav
No, the buf argument can be a null pointer, in which case the size
argument is taken as a size hint for a buffer allocated by the
implementation itself.
Alas, that hint actually gets ignored! For instance, on GNU/Linux
systems based on glibc, [...]
We are discussing the C standard, not the GNU C library. If you want to
talk implementations, I invite you to consider the following diffs:

https://svnweb.freebsd.org/csrg/lib/libc/stdio/setvbuf.c?r1=55893&r2=56990
https://svnweb.freebsd.org/csrg/lib/libc/stdio/setvbuf.c?r1=56990&r2=59778

This code survives nearly unmodified in {Free,Net,Open}BSD.
Post by Kaz Kylheku
(Maybe this requirement should just be strengthened so it's not merely
a hint, but a requirement to allocate a buffer of that size as if
by malloc.)
That would piss a lot of people off. But feel free to submit a bug
report to glibc asking them to honor the size argument if the buf
argument is a null pointer.

DES
--
Dag-Erling Smørgrav - ***@des.no
Kaz Kylheku
2016-03-23 12:24:54 UTC
Permalink
Raw Message
Post by Dag-Erling Smørgrav
Post by Kaz Kylheku
Post by Dag-Erling Smørgrav
On the contrary, it is a much simpler design, since it translates
directly into calls to existing library functions, which makes it easy
to describe and implement.
What?
if (isdigit(ch))
size = 1024 << (ch - '0');
Done.
Yeah, if you don't care if it works or not. There's a bug in the first
line.
How do you know what ch is without a declaration? Maybe it's an
unsigned char representing a value in the range 0 to UCHAR_MAX?
Or maybe it's char, but had been tested positive already?
The above could be a snippet of an error-free C program.

(In an actual implementation, I have it in a switch statement with case
'0': case '1': ... case '9': no library function is required at all.)
Post by Dag-Erling Smørgrav
And you are completely ignoring "easy to describe".
Far from it:

"The buffer size is 2ᴺ kilobytes, where N is specified as a decimal digit."

Of course it occured to me right from the beginning that an arbitrary
buffer size could be specified if we require an integer token to be
lexically scanned; I rejected the low-brow idea and searched for a
compact representation in one character which harmonizes with the
existing terse design of the mode string. It had to have a convention
that is easy to remember and a reasonable dynamic range.
Post by Dag-Erling Smørgrav
Post by Kaz Kylheku
Post by Dag-Erling Smørgrav
Full buffering is not the default in all cases [...]
Sorry, I bungled my wording. [...]
You realize that you just proved that your proposed solution is more
complicated to explain and understand than mine?
Both are mine. I came up with the 'f' in the original proposal, and
later revised it to drop 'f'. (I did so in an implementation first, in
fact). It's about equally brief to specify either way.

E.g. "The presence of the digit implies full buffering unless 'l'
is specified to request line buffering."
Keith Thompson
2016-03-23 15:52:08 UTC
Permalink
Raw Message
Kaz Kylheku <330-706-***@kylheku.com> writes:
[...]
Post by Kaz Kylheku
"The buffer size is 2ᴺ kilobytes, where N is specified as a decimal digit."
Of course it occured to me right from the beginning that an arbitrary
buffer size could be specified if we require an integer token to be
lexically scanned; I rejected the low-brow idea and searched for a
compact representation in one character which harmonizes with the
existing terse design of the mode string. It had to have a convention
that is easy to remember and a reasonable dynamic range.
[...]

I don't think "low-brow" is particularly meaningful.

The problem you're addressing is that setvbuf() must be called (almost)
immediately after fopen(), so there's not much point in separating them.
You want to add information to fopen() in a compatible manner, that lets
the user combine the fopen() and setvbuf() calls. The proposal is meant
to be convenient, but does not cover all cases. In particular, it only
permits a particular set of buffer sizes (encoded in a single decimal
digit), and it can't be used with stdin, stdout, stderr, or other files
for which the user can't modify the fopen() call.

Is that a fair summary, or have I missed something?

My objections to the proposal are:

1. The set of allowed buffer sizes is arbitrary. It might cover most
useful cases -- for now. Future developments might (or might not)
change the set of useful buffer sizes.

2. The syntax, though it's easy it explain, is not intuitive.

3. It's far less flexible than calling setvbuf() after calling fopen().
A user can easily write a function that does both without needing an
update to the standard library.

4. Code that uses the new feature, when used with an implementation that
doesn't support it, will not necessarily be detected at compile time,
and its behavior will be undefined. Compilers might emit warnings,
but that requires knowing whether the runtime library supports the
feature, something that might not always be possible.

I suggest that a call to fopen() immediately followed by a call to
setvbuf(), as permitted by the current standard, is clearer, which
IMHO suggests that the proposed new feature is not very useful.

On the other hand, setting the buffer size and buffering behavior
is logically something that should be associated with opening a file
(though changing the buffering of pre-opened streams can also be
useful). If I were designing an I/O library from scratch, I'd probably
include that functionality in the file open function(s), while making it
as easy as possible to use default settings.

Another approach would be to define a new function that combines fopen()
and setvbuf(). As a starting point;

FILE *fopen_and_setvbuf(
const char *path,
const char *mode,
char *buf,
int buf_mode,
size_t buf_size);

though I don't necessarily suggest that specific declaration. And
again, a programmer can easily define such a function without changing
the standard library.
--
Keith Thompson (The_Other_Keith) kst-***@mib.org <http://www.ghoti.net/~kst>
Working, but not speaking, for JetHead Development, Inc.
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
s***@casperkitty.com
2016-03-22 14:40:47 UTC
Permalink
Raw Message
Post by Kaz Kylheku
stdio streams allow buffering control, but it's closely associated
with the act of opening a stream. It is only defined to work if
a call to a function like setvbuf takes place before any I/O
operation.
Getting into the details of what size buffer is used for a stream seems like
a level of detail which goes beyond what would typically be supported by the
base C Standard. I'm curious why you think the buffer size is of particular
importance, given that the Standard doesn't presently offer any standard
means for platforms to expose commonplace-but-not-universal I/O concepts
like "perform a non-blocking read of all data that's available to date, or
report that none exists", "perform a blocking read of up to N bytes, but
stop blocking as soon as any data is available", or "perform a blocking
read of up to N bytes, but stop blocking when some data is available and
it does not appear that additional data is forthcoming". There are some
systems that can't support such concepts, but that's no reason for the
Standard to ignore the large number of systems that can.
Keith Thompson
2016-03-22 15:25:31 UTC
Permalink
Raw Message
Post by s***@casperkitty.com
Post by Kaz Kylheku
stdio streams allow buffering control, but it's closely associated
with the act of opening a stream. It is only defined to work if
a call to a function like setvbuf takes place before any I/O
operation.
Getting into the details of what size buffer is used for a stream seems like
a level of detail which goes beyond what would typically be supported by the
base C Standard.
setvbuf() already does exactly that. The proposal is to allow the
equivalent of setvbuf() to be done by fopen().

[...]
--
Keith Thompson (The_Other_Keith) kst-***@mib.org <http://www.ghoti.net/~kst>
Working, but not speaking, for JetHead Development, Inc.
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
Loading...