Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

read vs fread

29 views
Skip to first unread message

Patrice Kadionik

unread,
Feb 24, 2005, 3:43:37 PM2/24/05
to
Hi all,

I want to make a brief comparison between read() and fread() (under a
Linux OS).

1. Family read and Co: open, close, read, write, ioctl...
2. Family fread and Co: fopen, fclose, fread, fwrite, fcntl...


Family read and Co:
- are not C standard.
- are syscalls.
- are not formatted IO : we have a non formatted byte stream.
- don't use the Linux buffer cache.
- generally used for accessing character devices. fread and Co is possible.


Family fread and Co:
- are C standard.
- are functions of the standard IO libc (glibc).
- use an internal buffer (in their coding)
- are formatted IO (with the "%.." parameter) for some of them.
- use always the Linux buffer cache.
- generally used for accessing bloc devices.

When I'm opening an ordinary file on a HD (bloc device), I'm always
using the buffer cache with open or fopen. In case of fopen, I'm using
in addition an internal buffer when I'm doing a fread or fwrite for
speeding HD access.
When I'm opening an character device, I'm not using the buffer cache.
Open and Co are generally used here but fopen and Co is possible too.

Is is OK?
Some points I've forgotten?

Thank you for your response;
Pat.

Lew Pitcher

unread,
Feb 24, 2005, 3:59:23 PM2/24/05
to
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Patrice Kadionik wrote:
> Hi all,

Hi, Patrice

> I want to make a brief comparison between read() and fread() (under a
> Linux OS).
>
> 1. Family read and Co: open, close, read, write, ioctl...
> 2. Family fread and Co: fopen, fclose, fread, fwrite, fcntl...

Sure, see my comments below

>
> Family read and Co:
> - are not C standard.

Addition
- are Unix, BSD, POSIX and Single Unix Specification standard

> - are syscalls.
Correction,
- are wrappers to syscalls

> - are not formatted IO : we have a non formatted byte stream.

Correction
- are not formatted IO : we have an unformatted block write of one or more
bytes

> - don't use the Linux buffer cache.

Correction
- don't use a C standard I/O buffer
- use Linux VFS buffers and cache

> - generally used for accessing character devices. fread and Co is possible.

Correction
- generally used for accessing data at a low level (device or raw filesystem
format)


>
> Family fread and Co:
> - are C standard.
> - are functions of the standard IO libc (glibc).
> - use an internal buffer (in their coding)
> - are formatted IO (with the "%.." parameter) for some of them.

Correction
- enable formatted I/O on some calls

> - use always the Linux buffer cache.

Correction
- use a C standard I/O buffer ( see 2nd point above)
- use Linux VFS buffers and cache

> - generally used for accessing bloc devices.

Correction
- are generally used for accessing data streams in a device independant
fashion

> When I'm opening an ordinary file on a HD (bloc device), I'm always
> using the buffer cache with open or fopen. In case of fopen, I'm using
> in addition an internal buffer when I'm doing a fread or fwrite for
> speeding HD access.

> When I'm opening an character device, I'm not using the buffer cache.

Nope. You are using a 'buffer cache' (sic). If you continue to use the "line
buffered" or "cbreak buffered" modes, the kernel buffers one line of data before
passing it on to the read() that fread() or gets() invokes.

> Open and Co are generally used here but fopen and Co is possible too.
>
> Is is OK?
> Some points I've forgotten?

In general, on Unixish systems, fread() and company are built on read() and
company. That is to say, the implementation of the C 'standard I/O' library
functions use the POSIX I/O syscalls to access data. So, when you use fread(),
etc, you are /also/ using read(), etc. OTOH, the POSIX I/O functions (read(),
etc.) do not need or use the C standard I/O functions.

HTH
- --
Lew Pitcher
IT Specialist, Enterprise Data Systems,
Enterprise Technology Solutions, TD Bank Financial Group

(Opinions expressed are my own, not my employers')
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.2.4 (MingW32)

iD8DBQFCHkAqagVFX4UWr64RAk8KAKDWjOCVYck7mVrxBNtv8I1dpdY28wCfZMyh
DJ1kB9ohIujkqkc6/cslEEI=
=MyDj
-----END PGP SIGNATURE-----

Nils Weller

unread,
Feb 24, 2005, 4:35:15 PM2/24/05
to

(There's a *lot* wrong with your comparisons, but I only feel like
commenting on one point and leaving the rest to others.)

In article <421e3c7c$0$11959$626a...@news.free.fr>, Patrice Kadionik wrote:
> Hi all,
>
> I want to make a brief comparison between read() and fread() (under a
> Linux OS).
>
> 1. Family read and Co: open, close, read, write, ioctl...
> 2. Family fread and Co: fopen, fclose, fread, fwrite, fcntl...

^^^^^

(This belongs to the ``read and Co'' family as well.)

Your comparison makes precious little sense because the stdio package is
nothing more than an additional layer of abstraction and utility built
atop the low-level system interfaces for file I/O. Instead of
formulating a sentence like ``read() is different from fread() in that
...'', you should formulate it like ``read() is like this, and fread()
adds this and that to read().''

[...]
> Family read and Co:
> - are syscalls.

Actually, if you're writing portable C code, you never perform direct
system calls. The read() you get to see as a C programmer is a library
function (and not only that; it even resides in the same library file as
the stdio package!) that performs the read system call for you and
essentially behaves like the real system call. But there's a subtle
semantic difference between the bare system call and the library read()
call: The library wrapper has a different return value and alters the
visible state of the library. On Linux, the bare system call, on error,
returns a negative value whose absolute value matches the errno.h error
code that caused the error; The library function maps all negative
return values to -1 and additionally sets ``errno'' to the system return
value.

--
My real email address is ``nils<at>gnulinux<dot>nl''

Patrice Kadionik

unread,
Feb 24, 2005, 4:49:44 PM2/24/05
to
Hi Lew,
Thank you for your precious reponse.
This quiet simple question is not so clear for many of us (and me first...).

I Resume according to your remarks:
1. Family read() and Co: open(), close(), read(), write(), ioctl()...
2. Family fread() and Co: fopen(), fclose(), fread(), fwrite()...


Family read() and Co:


- are not C standard.

- are Unix, BSD, POSIX and Single Unix Specification standard compliant.
- are wrappers to syscalls.
- are not formatted I/O : we have a unformatted block of one or more bytes.
- don't use a C standard I/O buffer.
- use Linux VFS buffers and cache.


- generally used for accessing data at a low level (device or raw

filesystem format).


Family fread() and Co:
- are C standard.
- are functions of the standard I/O libc (glibc).
- use an internal buffer (in their coding).
- enable formatted I/O on some calls.
- use a C standard I/O buffer.
- use Linux VFS buffers and cache.


- are generally used for accessing data streams in a device independant

fashion.

In general, on Unixish systems, fread() and Co are built on read() and
Co. The implementation of the C 'standard I/O' library functions use the

POSIX I/O syscalls to access data. So, when you use fread(),

etc, you are using read()
The POSIX I/O functions (read()...) do not need or use the C standard
I/O functions.

Some questions:
- I think 'my' buffer cache corresponds to 'you' cache. What is also the
difference between the Virtual FS buffer and the cache (I've just in
mind the old Bach's figure of a typical *NIX system).
- What is the interest to use Linux VFS buffers and cache when I'm
accessing to a low level character device? intersting for a bloc device
in raw mode.

Thank you;
Pat.

Patrice Kadionik

unread,
Feb 24, 2005, 4:56:37 PM2/24/05
to
Hi Nils,

Nils Weller wrote:

> (There's a *lot* wrong with your comparisons, but I only feel like
> commenting on one point and leaving the rest to others.)
>
> In article <421e3c7c$0$11959$626a...@news.free.fr>, Patrice Kadionik wrote:
>
>>Hi all,
>>
>>I want to make a brief comparison between read() and fread() (under a
>>Linux OS).
>>
>>1. Family read and Co: open, close, read, write, ioctl...
>>2. Family fread and Co: fopen, fclose, fread, fwrite, fcntl...
>
> ^^^^^
>

I've corrected that in my previous post. sorry.


> (This belongs to the ``read and Co'' family as well.)
>
> Your comparison makes precious little sense because the stdio package is
> nothing more than an additional layer of abstraction and utility built
> atop the low-level system interfaces for file I/O. Instead of
> formulating a sentence like ``read() is different from fread() in that
> ...'', you should formulate it like ``read() is like this, and fread()
> adds this and that to read().''

You're right.


>
> [...]
>
>>Family read and Co:
>>- are syscalls.
>
>
> Actually, if you're writing portable C code, you never perform direct
> system calls.

Yes. wrappers to syscalls is more precise.


The read() you get to see as a C programmer is a library
> function (and not only that; it even resides in the same library file as
> the stdio package!) that performs the read system call for you and
> essentially behaves like the real system call. But there's a subtle
> semantic difference between the bare system call and the library read()
> call: The library wrapper has a different return value and alters the
> visible state of the library. On Linux, the bare system call, on error,
> returns a negative value whose absolute value matches the errno.h error
> code that caused the error; The library function maps all negative
> return values to -1 and additionally sets ``errno'' to the system return
> value.
>

Thanks Nils. I'll do a new post with all your remarks.
Cheers;

Pat.

David Schwartz

unread,
Feb 24, 2005, 5:35:09 PM2/24/05
to

"Nils Weller" <m...@privacy.net> wrote in message
news:386vkiF...@individual.net...

> Your comparison makes precious little sense because the stdio package is
> nothing more than an additional layer of abstraction and utility built
> atop the low-level system interfaces for file I/O.

This may be true on your system, but it is not required.

> Instead of
> formulating a sentence like ``read() is different from fread() in that
> ...'', you should formulate it like ``read() is like this, and fread()
> adds this and that to read().''

That would make his documentation specific to platforms where 'fread' is
implemented on top of 'read'. Nothing requires this.

DS


Nils Weller

unread,
Feb 24, 2005, 7:08:37 PM2/24/05
to
(Honestly, I saw a reply like this one coming when I wrote my article;
I expect another reply pointing out that ``portable C'' does not have
read() ;-))

In article <cvlkqq$fct$1...@nntp.webmaster.com>, David Schwartz wrote:
>
> "Nils Weller" <m...@privacy.net> wrote in message
> news:386vkiF...@individual.net...
>
>> Your comparison makes precious little sense because the stdio package is
>> nothing more than an additional layer of abstraction and utility built
>> atop the low-level system interfaces for file I/O.
>
> This may be true on your system, but it is not required.

First of all, the OP explicitly mentioned that he is making the
comparison with Linux in mind:

>> I want to make a brief comparison between read() and fread() (under a
>> Linux OS).

So even if I were talking strictly from the standpoint of an actual
implementation, I would not be that far off because Linux happens to
implement it in just the way I described (unless you're talking about
LSB or something, in which case I think the argument is pretty
pointless.)

Stdio was *designed* to be what I claim it is and it is one of the parts
of the C and Unix standards that reflects not design-by-commitee, but
is standardized ``existent practice''. The natural and obvious physical
hierarchy on those systems that provide both exists in parallel to the
logical layering, and it was specifically intended to be like that.

There may be some compatibility libraries for non-Unix systems that
don't use the obvious implementation (I'm particularly thinking of those
that implemented read()/write()/etc only to ``comply'' with everything
of K&R1), but those are unlikely to come even close to complying with
any POSIX or UNIX. I would be surprised if someone could point me to a
more complete system where the implementation differs (MVS? Cygwin? Most
likely not.)

Even the POSIX and UNIX hint at the implementation I described by
stating on the fopen() page:

The fopen() function shall allocate a file descriptor as open()
does.

>> Instead of
>> formulating a sentence like ``read() is different from fread() in that
>> ...'', you should formulate it like ``read() is like this, and fread()
>> adds this and that to read().''
>
> That would make his documentation specific to platforms where 'fread' is
> implemented on top of 'read'. Nothing requires this.

Again, I'll just say that the formulation makes sense if you don't try
to interpret it in a concrete implementation context (and of course, it
makes no sense on systems that have fread(), etc but not read(), etc but
that should be obvious anyway.)

I suggest that we don't let this thread turn into a pointless discussion
about what standards do and don't guarantee about specific
implementations; I'll quite agree that they guarantee precious little
and that stdio is not *guaranteed* to be actually physically implemented
on top of the (logically) lower-level I/O facilities. Do you have any
complaints about my statement if you do not drag it into a generic
implementation context?

Nils Weller

unread,
Feb 24, 2005, 7:21:15 PM2/24/05
to
In article <3878k5F...@individual.net>, Nils Weller wrote:
> In article <cvlkqq$fct$1...@nntp.webmaster.com>, David Schwartz wrote:
> [...]

> Even the POSIX and UNIX hint at the implementation I described by
> stating on the fopen() page:
>
> The fopen() function shall allocate a file descriptor as open()
> does.

Well, and then there are fileno() and fdopen(). How could I forget about
them!

David Schwartz

unread,
Feb 24, 2005, 8:45:19 PM2/24/05
to

"Nils Weller" <m...@privacy.net> wrote in message
news:3878k5F...@individual.net...

> (Honestly, I saw a reply like this one coming when I wrote my article;
> I expect another reply pointing out that ``portable C'' does not have
> read() ;-))
>
> In article <cvlkqq$fct$1...@nntp.webmaster.com>, David Schwartz wrote:
>>
>> "Nils Weller" <m...@privacy.net> wrote in message
>> news:386vkiF...@individual.net...
>>
>>> Your comparison makes precious little sense because the stdio package is
>>> nothing more than an additional layer of abstraction and utility built
>>> atop the low-level system interfaces for file I/O.
>>
>> This may be true on your system, but it is not required.
>
> First of all, the OP explicitly mentioned that he is making the
> comparison with Linux in mind:

Yet he posted only to 'comp.unix.programmer'. He should not get a
Linux-specific answer unless his question only applies to Linux.

> Even the POSIX and UNIX hint at the implementation I described by
> stating on the fopen() page:
>
> The fopen() function shall allocate a file descriptor as open()
> does.

That does not require it to call the 'open' function.

> I suggest that we don't let this thread turn into a pointless discussion
> about what standards do and don't guarantee about specific
> implementations; I'll quite agree that they guarantee precious little
> and that stdio is not *guaranteed* to be actually physically implemented
> on top of the (logically) lower-level I/O facilities. Do you have any
> complaints about my statement if you do not drag it into a generic
> implementation context?

Yes. APIs should not be described in terms of how they happen to be
implemented on some platforms. They should be described in terms of what
they are or are not specified to do.

DS


David Schwartz

unread,
Feb 24, 2005, 8:49:51 PM2/24/05
to

"Nils Weller" <m...@privacy.net> wrote in message
news:3879brF...@individual.net...

> In article <3878k5F...@individual.net>, Nils Weller wrote:
>> In article <cvlkqq$fct$1...@nntp.webmaster.com>, David Schwartz wrote:
>> [...]
>> Even the POSIX and UNIX hint at the implementation I described by
>> stating on the fopen() page:
>>
>> The fopen() function shall allocate a file descriptor as open()
>> does.
>
> Well, and then there are fileno() and fdopen(). How could I forget about
> them!

This does not require 'fopen' to call 'open', only that it be possible
to extract a file descriptor later. It could, for example, call a totally
different kernel function that opens a descriptor.

On many platforms, this is in fact the case. Calls to 'open' invoke one
library routine that eventually calls some kernel function while calls to
'fopen' invoke another library routine that eventually calls that same
kernel function. The kernel function called is not the user space 'open'
function.

On Linux, the 'open' function called from user-space, for example, has a
pthreads cancellation wrapper (on LinuxThreads platforms, no sure about
NPTL). They do both wind up calling the same kernel function, but that
kernel function is *NOT* the 'open' function he is talking about.

DS


David Schwartz

unread,
Feb 24, 2005, 9:22:47 PM2/24/05
to

"David Schwartz" <dav...@webmaster.com> wrote in message
news:cvm086$l2s$1...@nntp.webmaster.com...

> On Linux, the 'open' function called from user-space, for example, has
> a pthreads cancellation wrapper (on LinuxThreads platforms, no sure about
> NPTL). They do both wind up calling the same kernel function, but that
> kernel function is *NOT* the 'open' function he is talking about.

Actually, it's slightly different from that. On Linux, I'm pretty sure
'fopen' will wind up calling 'open', with the cancellation wrapper and all.
Whether cancellation would be sanely handled is another question. However,
on platforms where 'open64' exists, 'fopen' will typically wind up calling
'open64' instead of 'open'. Platforms where 'fopen' directly invokes the
same kernel function 'open' does, but without 'fopen' actually calling
'open' are not uncommon.

DS


Patrice Kadionik

unread,
Feb 25, 2005, 8:43:45 AM2/25/05
to
Hi all,
David: I've posted the same question in the
comp.os.linux.development.system newsgroup. I've had the same reaction
than here: every one has his own advice on this point. It was the same
reaction when a guy has originally posted this question in a french
private list.
It's sure that the right response is lied to the OS used (it was Linux
for me but we can do the same for *nix).
Is there finally a comparison chart for read vs fread adopted by almost all?
Thanks to all of you;
Pat.

Nils Weller

unread,
Feb 25, 2005, 10:44:37 AM2/25/05
to
> "Nils Weller" <m...@privacy.net> wrote:
>> Nils Weller wrote:
>>> David Schwartz wrote:
>>> [...]
>>> Even the POSIX and UNIX [standards] hint at the implementation I

>>> described by stating on the fopen() page:
>>>
>>> The fopen() function shall allocate a file descriptor as open()
>>> does.
>> Well, and then there are fileno() and fdopen(). How could I forget
>> about them!
> This does not require 'fopen' to call 'open'

Nor did I say that it does. I have already acknowledged that the UNIX
standards do not guarantee that fopen() be implemented atop open(); I
was saying that the relation between the two, even as described by UNIX,
makes a strong suggestion as to how they could be implemented. And this
is barely surprising because the design of stdio, as well as decades of
common practice, have always implied it.

> However, on platforms where 'open64' exists, 'fopen' will typically
> wind up calling 'open64' instead of 'open'.

A distinction without a difference if you ask me. The ``stdio atop of
low-level interfaces'' scheme applies in either case. If this is to
refute the UNIX citation that suggests that fopen() call open() - As I
said, I didn't say that it *mandates* such an implementation. The whole
xxx() vs xxx64() thing is just a common kludge anyway, not something
that makes for timeless good API design.

In article <cvlvvm$kqv$1...@nntp.webmaster.com>, David Schwartz wrote:
>
> "Nils Weller" <m...@privacy.net> wrote in message
>> In article <cvlkqq$fct$1...@nntp.webmaster.com>, David Schwartz wrote:
>>>
>>> "Nils Weller" <m...@privacy.net> wrote in message
>>> news:386vkiF...@individual.net...
>>>
>>>> Your comparison makes precious little sense because the stdio package is
>>>> nothing more than an additional layer of abstraction and utility built
>>>> atop the low-level system interfaces for file I/O.
>>>
>>> This may be true on your system, but it is not required.
>>
>> First of all, the OP explicitly mentioned that he is making the
>> comparison with Linux in mind:
>
> Yet he posted only to 'comp.unix.programmer'. He should not get a
> Linux-specific answer unless his question only applies to Linux.

True, but saying that it ``only applies to Linux'' is way over the top.
And likewise, the ``this may be true on your system'' statement bugs me
as well. A more suitable formulation would probably be closer to ``this
may be true on the half dozen Unix systems you're using, plus the other
half you have used at one time or another, and it also applies to pretty
much every Unix system I have seen myself.'' How many native Unix
systems do you know that do not actually implement stdio atop the low-
level system interfaces for file I/O (by which I mean, of course,
open(), read(), write(), etc, and open64() if you like)?

>> Even the POSIX and UNIX hint at the implementation I described by
>> stating on the fopen() page:
>>
>> The fopen() function shall allocate a file descriptor as open()
>> does.
>
> That does not require it to call the 'open' function.

Nor did I say that it does.

>> I suggest that we don't let this thread turn into a pointless discussion
>> about what standards do and don't guarantee about specific
>> implementations; I'll quite agree that they guarantee precious little
>> and that stdio is not *guaranteed* to be actually physically implemented
>> on top of the (logically) lower-level I/O facilities. Do you have any
>> complaints about my statement if you do not drag it into a generic
>> implementation context?
>
> Yes. APIs should not be described in terms of how they happen to be
> implemented on some platforms. They should be described in terms of what
> they are or are not specified to do.

While this is generally good advice, I don't agree in this particular
case (and I'm not going to comment on the ``on some platforms''
exaggeration again.) It is easier to think of the package as a sort of
a superset from the beginning than to manually collect every single
piece of a difference only to reach the same conclusion. The common
practice implementation view may help with this.

These functions have a long history and knowing that they are
traditionally related in this way may help you understand design
decisions, what stdio on Unix is really intended to be there for, and
when you should use one or the other. I suppose if I had thrown in just
a ``usually'' in my initial description, this sub-thread would have
never happened. But I'm reluctant to use the term in technical
discussions if I don't know of any exception from the rule. So what Unix
systems (native or not - just sufficiently close to complying with POSIX
UNIX to be a realistic target for the average reader of this newsgroup)
do not actually implement stdio on top of the ``low-level system
interfaces for file I/O'' (open(), open64() :-), read(), write(),
close(), etc)?

David Schwartz

unread,
Feb 25, 2005, 2:54:51 PM2/25/05
to

"Nils Weller" <m...@privacy.net> wrote in message
news:388vf4F...@individual.net...

>> Yes. APIs should not be described in terms of how they happen to be
>> implemented on some platforms. They should be described in terms of what
>> they are or are not specified to do.

> While this is generally good advice, I don't agree in this particular
> case (and I'm not going to comment on the ``on some platforms''
> exaggeration again.) It is easier to think of the package as a sort of
> a superset from the beginning than to manually collect every single
> piece of a difference only to reach the same conclusion. The common
> practice implementation view may help with this.

Let's go back to see what I'm replying to:

>>> Your comparison makes precious little sense because the stdio package is
>>> nothing more than an additional layer of abstraction and utility built

>>> atop the low-level system interfaces for file I/O. Instead of


>>> formulating a sentence like ``read() is different from fread() in that
>>> ...'', you should formulate it like ``read() is like this, and fread()
>>> adds this and that to read().''

In other words, it doesn't make sense to think of stdio as its own API.
Not that it's more useful to think of it as an additional layer, but that it
makes no sense on its own.

> These functions have a long history and knowing that they are
> traditionally related in this way may help you understand design
> decisions, what stdio on Unix is really intended to be there for, and
> when you should use one or the other. I suppose if I had thrown in just
> a ``usually'' in my initial description, this sub-thread would have
> never happened. But I'm reluctant to use the term in technical
> discussions if I don't know of any exception from the rule.

This is the secret to designing programs that break. Assume that
something must be true, even though the relevent standards don't guarantee
it, because you don't know of any exceptions *today*.

> So what Unix
> systems (native or not - just sufficiently close to complying with POSIX
> UNIX to be a realistic target for the average reader of this newsgroup)
> do not actually implement stdio on top of the ``low-level system
> interfaces for file I/O'' (open(), open64() :-), read(), write(),
> close(), etc)?

As I said, on many platforms, both 'read' and 'fread' are library
functions that call a common kernel call that is neither 'read' nor 'fread'.
The stdio library is its own API that has its own rules. In fact, one can
argue that a main feature of the stdio library is that it applies to systems
beyond POSIX because it is defined on its own.

DS


Nils Weller

unread,
Feb 26, 2005, 10:32:25 AM2/26/05
to
In article <cvnvql$j3g$1...@nntp.webmaster.com>, David Schwartz wrote:
>
> "Nils Weller" <m...@privacy.net> wrote in message
> news:388vf4F...@individual.net...
>
>>> Yes. APIs should not be described in terms of how they happen to be
>>> implemented on some platforms. They should be described in terms of what
>>> they are or are not specified to do.
>
>> While this is generally good advice, I don't agree in this particular
>> case (and I'm not going to comment on the ``on some platforms''
>> exaggeration again.) It is easier to think of the package as a sort of
>> a superset from the beginning than to manually collect every single
>> piece of a difference only to reach the same conclusion. The common
>> practice implementation view may help with this.
>
> Let's go back to see what I'm replying to:
>
>>>> Your comparison makes precious little sense because the stdio package is
>>>> nothing more than an additional layer of abstraction and utility built
>>>> atop the low-level system interfaces for file I/O. Instead of
>>>> formulating a sentence like ``read() is different from fread() in that
>>>> ...'', you should formulate it like ``read() is like this, and fread()
>>>> adds this and that to read().''
>
> In other words, it doesn't make sense to think of stdio as its own API.
> Not that it's more useful to think of it as an additional layer, but that it
> makes no sense on its own.

This does not accurately rephrase what I said, because it completely
ignores the context: My statement addresses the intent of *comparing*
the (logically and, typically, physically) lower-level interfaces with
stdio. With the context in mind, it does not say anything in general
about ``stdio as its own API''.

>> These functions have a long history and knowing that they are
>> traditionally related in this way may help you understand design
>> decisions, what stdio on Unix is really intended to be there for, and
>> when you should use one or the other. I suppose if I had thrown in just
>> a ``usually'' in my initial description, this sub-thread would have
>> never happened. But I'm reluctant to use the term in technical
>> discussions if I don't know of any exception from the rule.
>
> This is the secret to designing programs that break. Assume that
> something must be true, even though the relevent standards don't guarantee
> it, because you don't know of any exceptions *today*.

Trivially true, but this barely applies to the case we are discussing.
Whether or not stdio is implemented in the traditional way, the
visible semantics of these functions are always the same. In the
unlikely event that you're doing low-level hackery like intercepting
calls to these functions, in which case the difference may matter, your
code is already nonportable and stdio's implementation is the least of
your worries.

The implementation is irrelevant so long as it behaves in the way
described by the relevant standards (whoops, they also call me ``Captain
Obvious''.)

>> So what Unix
>> systems (native or not - just sufficiently close to complying with POSIX
>> UNIX to be a realistic target for the average reader of this newsgroup)
>> do not actually implement stdio on top of the ``low-level system
>> interfaces for file I/O'' (open(), open64() :-), read(), write(),
>> close(), etc)?
>
> As I said, on many platforms, both 'read' and 'fread' are library

^^^^^^^^^^^^^^^^^


> functions that call a common kernel call that is neither 'read' nor 'fread'.

Concrete examples?

> The stdio library is its own API that has its own rules. In fact, one can
> argue that a main feature of the stdio library is that it applies to systems
> beyond POSIX because it is defined on its own.

True, but how is this relevant to comparing open(), read(), etc with
stdio? I think the context has been lost here again.

David Schwartz

unread,
Feb 26, 2005, 4:36:10 PM2/26/05
to

"Nils Weller" <m...@privacy.net> wrote in message
news:38bj49F...@individual.net...

>> As I said, on many platforms, both 'read' and 'fread' are library
> ^^^^^^^^^^^^^^^^^
>> functions that call a common kernel call that is neither 'read' nor
>> 'fread'.
>
> Concrete examples?

On Linux, with LinuxThreads, both 'read' and 'fread' are library
functions that call a common kernel function that is neither 'read' nor
'fread'.

DS


0 new messages