468,103 Members | 1,172 Online
Bytes | Developer Community
New Post

Home Posts Topics Members FAQ

Post your question to a community of 468,103 developers. It's quick & easy.

Unix I/O and C library I/O, why there are two sets of I/O functions?

In the C programming language, I/O operation functions are declared in
stdio.h, for example, fopen(), fclose(), fwrite(), fread(), fseek() ...

But another set of I/O functions are also defined in Unix, for example,
open(), close(), read(), write(), lseek() ...

Which set of functions is more suitable for I/O task, C library version
or Unix version?

Thank you

lovecreatesbeauty

Feb 4 '06 #1
36 3362
You're talking about the difference between library calls and system
calls. The ones in stdio (e.g. printf, fopen) are C library functions.
The others (e.g. read, write) are lower level than that, and are known
as system calls (meaning functions provided by the kernel to all other
libraries). The C library functions actually call the system calls to
do their job. But one stdio call may result in several system calls.
(Try using the command line strace utility to see which system calls a
stdio function actually boils down to)

The stdio calls, believe it or not, provide easier interfaces to the
system calls. If you do want to use the system calls directly, you have
to fiddle around with the exact number of bytes in and out each time,
which is a pain.

If you want to use system calls, go ahead. When you are writing a
program, they're pretty much the same thing, although at a kernel
level, there are differences.

Whatever you do, don't mix stdio and system calls. Ther results can be
a little strange to say the least.

Feb 4 '06 #2
lovecreatesbeauty wrote:
In the C programming language, I/O operation functions are declared in
stdio.h, for example, fopen(), fclose(), fwrite(), fread(), fseek()
...

But another set of I/O functions are also defined in Unix, for
example, open(), close(), read(), write(), lseek() ...

Which set of functions is more suitable for I/O task, C library
version or Unix version?


If you are only ever going to use your program on Unix, whichever better
fits your needs. However, if you go the Unix I/O way, you're most
likely in for a nasty experience if ever you're required to port to
some other OS. Pick your poison...

Cheers

Vladimir
--
Tact is the ability to tell a man he has an open mind when he has a
hole in his head.

Feb 4 '06 #3
Vladimir S. Oka a écrit :
if you go the Unix I/O way, you're most
likely in for a nasty experience if ever you're required to port to
some other OS. Pick your poison...


an OS that isn't POSIX isn't a good one anyway.
Feb 4 '06 #4

lovecreatesbeauty wrote:
In the C programming language, I/O operation functions are declared in
stdio.h, for example, fopen(), fclose(), fwrite(), fread(), fseek() ...

But another set of I/O functions are also defined in Unix, for example,
open(), close(), read(), write(), lseek() ...

Which set of functions is more suitable for I/O task, C library version
or Unix version?


You must realise that the low level functions (open(), close(), read(),
write(), ...) use unbuffered I/O and may therefore slow down your
program read/write operations.

I recommend only to use the standard I/O functions for portability,
speed and ease of use. You can configure the buffering used by the
standard I/O functions by calling setvbuf().

Lucien Kennedy-Lamb

Feb 4 '06 #5

"lovecreatesbeauty" <lo***************@gmail.com> wrote in message
news:11**********************@g43g2000cwa.googlegr oups.com...
In the C programming language, I/O operation functions are declared in
stdio.h, for example, fopen(), fclose(), fwrite(), fread(), fseek() ...

But another set of I/O functions are also defined in Unix, for example,
open(), close(), read(), write(), lseek() ...

Which set of functions is more suitable for I/O task, C library version
or Unix version?

One of the original motivations for the stdio library was to provide a layer
of buffering so that character-based calls like getc(), fgets() and printf()
could be implemented without the overhead of doing system I/O one byte at a
time (if the o.s. and the device support such a thing at all).

Bear in mind also that fread() returns the amount of data requested, if
possible, whereas read() gives you no such guarantee. A lot of the time,
you have to write more code to use the low-level calls.

--
RSH
Feb 4 '06 #6
lovecreatesbeauty wrote:
In the C programming language, I/O operation functions are declared in
stdio.h, for example, fopen(), fclose(), fwrite(), fread(), fseek() ...

But another set of I/O functions are also defined in Unix, for example,
open(), close(), read(), write(), lseek() ...

Which set of functions is more suitable for I/O task, C library version
or Unix version?


To the question in your subject line: C's I/O and Unix'
I/O are different because C can operate on systems that are
not Unix.

To the question in your message: Neither set of functions
is always "more suitable." Which is more suitable: a hammer
or a saw? A hand-operated drill, a battery-powered drill, a
portable drill powered by house current, or a fixed-position
drill press? It all depends on the task at hand and on where
you want to be able to do it.

Various responders have offered information that's either
incorrect, incomplete, or misleading. Rather than post a
whole flurry of rebuttals, I'll package them all here:

richselby says fopen() and friends are library functions
while open() and the like are system calls. That's a detail
of the implementation, true on many systems but certainly
not on all. On some systems, both fopen() and open() are
library functions.

loufoque opines that only POSIX-compliant systems are any
good. It's pointless to dispute his (?) opinion, but the
implication that open() and friends on POSIX systems share
all the characteristics found in Unix implementations.

Lucien Kennedy-Lamb explains that fopen() and friends are
higher-level functions that rest upon lower-level system calls
like open(). This is really just richselby's mistake all over
again: It's often true, but not universally true.

Summary: fopen() and friends are part of the C Standard
library, found in all hosted C implementations, even those
that do not run under Unix or under POSIX. open() and the
like are specified by POSIX, but only in terms of what they
do, not how they do it. They may or may not be "system calls,"
and they may or may not be "lower level" calls.

--
Eric Sosman
es*****@acm-dot-org.invalid

Feb 4 '06 #7
Lucien Kennedy-Lamb a écrit :
You must realise that the low level functions (open(), close(), read(),
write(), ...) use unbuffered I/O and may therefore slow down your
program read/write operations.


That's not true.
Feb 4 '06 #8
"lovecreatesbeauty" <lo***************@gmail.com> writes:
In the C programming language, I/O operation functions are declared in
stdio.h, for example, fopen(), fclose(), fwrite(), fread(), fseek() ...

But another set of I/O functions are also defined in Unix, for example,
open(), close(), read(), write(), lseek() ...

Which set of functions is more suitable for I/O task, C library version
or Unix version?


If you want maximum portability, you should obviously use only the
functions defined by the C standard.

The Unix-specific (or POSIX-specific) functions may provide some
features that the standard C functions don't. <OT>For example,
open()'s flags parameter gives you more control over how the file is
opened than fopen()'s mode parameter.</OT> If you really need that
extra functionality, you'll need to use the POSIX functions -- but
there's a good chance you don't really need it.

It's quite possible that you'll never need to port your program to a
system that doesn't support POSIX (though you can't really be sure of
that). Even in that case, I recommend using the C standard functions
rather than the POSIX-specific functions. They're easier to use, and
they typically provide buffering that can make your program more
efficient.

Somebody elsethread said something about function calls vs. system
calls. That's a system-specific distinction that you shouldn't have
to worry about even if you're writing system-specific code. The C
language has no concept of "system calls"; they're all just functions.
<OT>I don't think POSIX refers to system calls either, but I could be
mistaken; the POSIX interface can be implemented on top of lower-level
calls, just as the <stdio.h> interface can be.</OT> In Unix, a
system call might be implemented differently than a call to a library
function, but as far as your program is concerned it's just another
function call.

If you have more questions in this area, comp.unix.programmer would
probably be a better place to ask.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Feb 4 '06 #9
Eric Sosman wrote:

Summary: fopen() and friends are part of the C Standard
library, found in all hosted C implementations, even those
that do not run under Unix or under POSIX. open() and the
like are specified by POSIX, but only in terms of what they
do, not how they do it. They may or may not be "system calls,"
and they may or may not be "lower level" calls.

Well put.

--
Ian Collins.
Feb 4 '06 #10
loufoque <lo******@remove.gmail.com> writes:
Lucien Kennedy-Lamb a écrit :
You must realise that the low level functions (open(), close(), read(),
write(), ...) use unbuffered I/O and may therefore slow down your
program read/write operations.


That's not true.


True or not (I honestly don't know), it's a question for
comp.unix.programmer.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Feb 4 '06 #11
"richselby" <ri*******@hotmail.com> writes:
You're talking about the difference between library calls and system
calls. The ones in stdio (e.g. printf, fopen) are C library functions.
The others (e.g. read, write) are lower level than that, and are known
as system calls (meaning functions provided by the kernel to all other
libraries). The C library functions actually call the system calls to
do their job. But one stdio call may result in several system calls.
(Try using the command line strace utility to see which system calls a
stdio function actually boils down to)
You are making several incorrect assumptions here.

open(), read(), write(), close() etc. are part of the POSIX standard.
POSIX does not differentiate between library functions and system
calls; I do not believe it even uses the term "system call".

Although POSIX has been merged into the Single Unix Specification, is
not synonymous with what we commonly regard as Unix. In fact, most
operating systems which are grouped under the term Unix in common
parlance are not Unix; they are derivatives or clones. Only a very
few Unix-like operating systems are actually certified as Unix.

POSIX can be (and has been) implemented on e.g. Microsoft Windows. In
fact, there are several partial or complete implementations of POSIX
for Windows; at least one of them (Interix / SFU) is implemented as a
separate kernel personality, but others (like Cygwin) are implemented
on top of the Windows API, and most of what you think of as system
calls are in fact library functions which invoke Windows system
library or kernel calls behind the scenes. In an environment like
this, it is not unlikely that both open() and fopen() are layered
directly on top of the underlying system API, instead of one being
implemented in terms of the other.
The stdio calls, believe it or not, provide easier interfaces to the
system calls. If you do want to use the system calls directly, you have
to fiddle around with the exact number of bytes in and out each time,
which is a pain.


There is no conceptual difference between fwrite() and write(),
although fwrite() is usually buffered and write() usually is not (and
if it is, there is no standardized API to manipulate the buffer). The
only stream-based functions which have no equivalent that operate on
file descriptors are the printf() / scanf() family (because they
cannot be implemented efficiently without a buffer).

DES
--
Dag-Erling Smørgrav - de*@des.no
Feb 4 '06 #12
lovecreatesbeauty wrote:
In the C programming language, I/O operation functions are declared in
stdio.h, for example, fopen(), fclose(), fwrite(), fread(), fseek() ...

But another set of I/O functions are also defined in Unix, for example,
open(), close(), read(), write(), lseek() ...

Which set of functions is more suitable for I/O task, C library version
or Unix version?

One issue that hasn't been addressed so far (maybe because it's off
topic?) is that the posix functions operate with a file descriptor,
which can refer to things other than files.

For more information, go to comp.unix.programmer.

--
Ian Collins.
Feb 4 '06 #13

"lovecreatesbeauty" <lo***************@gmail.com> wrote in message
news:11**********************@g43g2000cwa.googlegr oups.com...
In the C programming language, I/O operation functions are declared in
stdio.h, for example, fopen(), fclose(), fwrite(), fread(), fseek() ...

But another set of I/O functions are also defined in Unix, for example,
open(), close(), read(), write(), lseek() ...

Which set of functions is more suitable for I/O task, C library version
or Unix version?


You need to find answers to other questions:

1) Do you need ANSI/ISO C compliance or portability?
2) Do you want IO buffering?
3) Which is more important speed or ease of programming?

Most language compilers (except PL/1, FORTH) were written after the
operating system was implemented and are dependent on a small set of
operating system specific functions. P.J. Plauger layers 'fopen(),
fclose(), fwrite(), fread(), fseek()' on top of 'open(), close(), read(),
write(), lseek()' in his classic book (pg 447) "The Standard C Library."
The ANSI/ISO C functions of GLIBC are also layered on top of POSIX operating
system functions. In fact, just about anywhere you find a C compiler (VAX
VMS, Stratus VOS, Windows, MS-DOS, Linux), the ANSI/ISO C functions will
layered onto the OS's low level functions.
Rod Pemberton
Feb 5 '06 #14
On 2006-02-04, Eric Sosman <es*****@acm-dot-org.invalid> wrote:
lovecreatesbeauty wrote:
In the C programming language, I/O operation functions are declared in
stdio.h, for example, fopen(), fclose(), fwrite(), fread(), fseek() ...

But another set of I/O functions are also defined in Unix, for example,
open(), close(), read(), write(), lseek() ...

Which set of functions is more suitable for I/O task, C library version
or Unix version?


To the question in your subject line: C's I/O and Unix'
I/O are different because C can operate on systems that are
not Unix.


Though I suspect that the Unix I/O functions can be faked to some degree
in standard C.

say,

#define OPEN_MAX 20

static FILE *_files[OPEN_MAX] = { stdin, stdout, stderr };

int fileno(FILE *x) {
for(int i=0;i<OPEN_MAX;i++) if(_files[i] == x) return i;
return -1;
}

#define O_RDONLY 0 #define O_WRONLY 1 #define O_RDWR 2 ...
static char **flags = {
"rb", "wb", "wb+", NULL, ...
}

int open(char *fn, int flag, ...) {
return fileno(fopen(fn,flags[flag]));
}

and so forth.

Something analogous to O_EXCL and O_CREAT might have been nice to have
in standard C [O_CREAT: create the file if it doesn't exist - if flag is
not set, fail if the file does not exist. O_EXCL: fail if the file
exists] I don't see any reason why such a thing couldn't exist - anyone
have any ida why it doesn't?
Feb 5 '06 #15
On 2006-02-04, Keith Thompson <ks***@mib.org> wrote:
loufoque <lo******@remove.gmail.com> writes:
Lucien Kennedy-Lamb a écrit :
You must realise that the low level functions (open(),
close(), read(), write(), ...) use unbuffered I/O and
may therefore slow down your program read/write
operations.


That's not true.


True or not (I honestly don't know), it's a question for
comp.unix.programmer.


There may be kernel buffers involved, but there's no
buffering at the user level [which means that it requires a
trip to the system and back (two context switches) per call]
Feb 5 '06 #16
On 2006-02-04, Dag-Erling Smørgrav <de*@des.no> wrote:
open(), read(), write(), close() etc. are part of the POSIX standard.
POSIX does not differentiate between library functions and system
calls; I do not believe it even uses the term "system call".
True. what are "system calls" is a matter of tradition, rather than
standardized fact. And there are variations between systems [on
traditional unix systems, all four you listed are system calls, or, more
precisely, very thin wrappers. around system calls.]
POSIX can be (and has been) implemented on e.g. Microsoft Windows. In
fact, there are several partial or complete implementations of POSIX
for Windows; at least one of them (Interix / SFU) is implemented as a
separate kernel personality, but others (like Cygwin) are implemented
on top of the Windows API, and most of what you think of as system
calls are in fact library functions which invoke Windows system
library or kernel calls behind the scenes. In an environment like
this, it is not unlikely that both open() and fopen() are layered
directly on top of the underlying system API, instead of one being
implemented in terms of the other.
Except that each FILE * is required to have a file number for fileno(),
so i suspect fopen is _still_ layered on top of open() in that case.
[doesn't windows come with an _open() call that more or less fakes posix
open()?]

Though I suppose that open() could be layered on top of fopen() and
fileno(), as I illustrated in another message.
There is no conceptual difference between fwrite() and write(),
although fwrite() is usually buffered and write() usually is not (and
if it is, there is no standardized API to manipulate the buffer). The
only stream-based functions which have no equivalent that operate on
file descriptors are the printf() / scanf() family (because they
cannot be implemented efficiently without a buffer).


Not that it hasn't stopped gnu from trying. [such a function, though,
could provide its own buffer, which it then write()s.]
Feb 5 '06 #17
Ian Collins <ia******@hotmail.com> writes:
lovecreatesbeauty wrote:
In the C programming language, I/O operation functions are declared in
stdio.h, for example, fopen(), fclose(), fwrite(), fread(), fseek() ...
But another set of I/O functions are also defined in Unix, for
example,
open(), close(), read(), write(), lseek() ...
Which set of functions is more suitable for I/O task, C library
version
or Unix version?
One issue that hasn't been addressed so far (maybe because it's off
topic?) is that the posix functions operate with a file descriptor,
which can refer to things other than files.


A FILE* can also refer to things other than "files" (depending on what
you mean by "file"). <OT>See fileno() and fdopen().</OT>
For more information, go to comp.unix.programmer.


Indeed.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Feb 5 '06 #18
Dag-Erling Smørgrav wrote:
.... snip ...
There is no conceptual difference between fwrite() and write(),
although fwrite() is usually buffered and write() usually is not
(and if it is, there is no standardized API to manipulate the
buffer). The only stream-based functions which have no equivalent
that operate on file descriptors are the printf() / scanf() family
(because they cannot be implemented efficiently without a buffer).


There is a large difference. The fwrite etc. call family is
guaranteed to be available by the standard. The write etc. family
need not be available, and in fact is often not, or may have
entirely different undocumented semantics and characteristics.
Thus they are off-topic here, where we deal with the portable C
language only.

--
"The power of the Executive to cast a man into prison without
formulating any charge known to the law, and particularly to
deny him the judgement of his peers, is in the highest degree
odious and is the foundation of all totalitarian government
whether Nazi or Communist." -- W. Churchill, Nov 21, 1943
Feb 5 '06 #19
In article <ds**********@nwrdmz02.dmz.ncs.ea.ibs-infra.bt.com>,
"Vladimir S. Oka" <no****@btopenworld.com> wrote:
lovecreatesbeauty wrote:
In the C programming language, I/O operation functions are declared in
stdio.h, for example, fopen(), fclose(), fwrite(), fread(), fseek()
...

But another set of I/O functions are also defined in Unix, for
example, open(), close(), read(), write(), lseek() ...

Which set of functions is more suitable for I/O task, C library
version or Unix version?


If you are only ever going to use your program on Unix, whichever better
fits your needs. However, if you go the Unix I/O way, you're most
likely in for a nasty experience if ever you're required to port to
some other OS. Pick your poison...


Another advantage of Standard C is that anybody who knows the C language
can read and modify the code, so you are not restricted to those who
understand Unix as well.

So unless you can see a significant advantage in using Unix calls (and
the original poster was asking a question about that, so he _doesn't_
see any significant advantage), C functions are just more widely
portable than Unix functions, or MacOS functions, or Windows functions.
Feb 5 '06 #20
In article <11***************@drone2-svc-skyt.qsi.net.nz>,
Ian Collins <ia******@hotmail.com> wrote:
lovecreatesbeauty wrote:
In the C programming language, I/O operation functions are declared in
stdio.h, for example, fopen(), fclose(), fwrite(), fread(), fseek() ...

But another set of I/O functions are also defined in Unix, for example,
open(), close(), read(), write(), lseek() ...

Which set of functions is more suitable for I/O task, C library version
or Unix version?

One issue that hasn't been addressed so far (maybe because it's off
topic?) is that the posix functions operate with a file descriptor,
which can refer to things other than files.


Years ago, on a certain version of Microsoft Word, running on a certain
operating system, you could save a document and type in ".sound" as the
filename, and the document contents would be sent directly to the sound
driver...

With nasty consequences to the ears of the user.

I never dared trying to save a document to the harddisk driver...
Feb 5 '06 #21
Keith Thompson wrote:
One issue that hasn't been addressed so far (maybe because it's off
topic?) is that the posix functions operate with a file descriptor,
which can refer to things other than files.

A FILE* can also refer to things other than "files" (depending on what
you mean by "file"). <OT>See fileno() and fdopen().</OT>

Thanks for reminding me, it's been a very long time since I used those.

Has OT come to signify On Topic here now :)

--
Ian Collins.
Feb 5 '06 #22

loufoque wrote:
Vladimir S. Oka a écrit :
if you go the Unix I/O way, you're most
likely in for a nasty experience if ever you're required to port to
some other OS. Pick your poison...


an OS that isn't POSIX isn't a good one anyway.


in the Real World we don't always get to choose a so-called
"good" OS.

And that all "good" OS's are POSIX compliant is merely your opinion
--
Nick Keighley

Feb 5 '06 #23
Ian Collins <ia******@hotmail.com> writes:
Keith Thompson wrote:
One issue that hasn't been addressed so far (maybe because it's off
topic?) is that the posix functions operate with a file descriptor,
which can refer to things other than files.

A FILE* can also refer to things other than "files" (depending on
what
you mean by "file"). <OT>See fileno() and fdopen().</OT>

Thanks for reminding me, it's been a very long time since I used those.

Has OT come to signify On Topic here now :)


I see the smiley, but apparently I'm too dense to get the joke 8-)},
so I'll take the question seriously.

No, OT still stands for Off Topic. fileno() and fdopen() are not
standard C functions.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Feb 5 '06 #24
Keith Thompson wrote:

A FILE* can also refer to things other than "files" (depending on
what
you mean by "file"). <OT>See fileno() and fdopen().</OT>

Thanks for reminding me, it's been a very long time since I used those.

Has OT come to signify On Topic here now :)

I see the smiley, but apparently I'm too dense to get the joke 8-)},
so I'll take the question seriously.

No, OT still stands for Off Topic. fileno() and fdopen() are not
standard C functions.

OK, my bad. I (and my system's man pages) though they were standard,
but yes I see they aren't.

--
Ian Collins.
Feb 5 '06 #25
Nick Keighley a écrit :
And that all "good" OS's are POSIX compliant is merely your opinion


POSIX = Portable Operating System Interface.
Any decent OS should implement that interface, unless it refuses
portability.
Feb 6 '06 #26
loufoque wrote:
Nick Keighley a écrit :
And that all "good" OS's are POSIX compliant is merely your opinion

POSIX = Portable Operating System Interface.
Any decent OS should implement that interface, unless it refuses
portability.


Which many do....

--
Ian Collins.
Feb 6 '06 #27
loufoque wrote:
Nick Keighley a écrit :

And that all "good" OS's are POSIX compliant is merely your opinion


POSIX = Portable Operating System Interface.
Any decent OS should implement that interface, unless it refuses
portability.


this is plainly off-topic so I won't continue after this. But just
because
something is labelled something doesn't mean it is necessarily the best

solution. I have no particular axe to grind over POSIX. Indeed if I had
a
choice of a POSIX interface or something else I would give it serious
consideration. But you seem to be saying *nothing* can *ever* be
better than POSIX. This seems to refuse to consider any inovation..
Surely POSIX isn't *perfect*?

Are all embedded RTOSs POSIX compliant?
--
Nick Keighley

Feb 6 '06 #28
# Which set of functions is more suitable for I/O task, C library version
# or Unix version?

Depends on what the task is. Each interface has its good points and
bad points; choose the interface that best matches your needs.
--
SM Ryan http://www.rawbw.com/~wyrmwif/
Don't say anything. Especially you.
Feb 6 '06 #29
# Bear in mind also that fread() returns the amount of data requested, if
# possible, whereas read() gives you no such guarantee. A lot of the time,
# you have to write more code to use the low-level calls.

Other way around. In Unix, read() gives the number of bytes read
or an error indication. fread returns the number of complete items,
but in case of a partial item of more than one byte, you don't
know how many bytes were read.

--
SM Ryan http://www.rawbw.com/~wyrmwif/
Mention something out of a Charleton Heston movie, and suddenly
everybody's a theology scholar.
Feb 6 '06 #30
loufoque wrote:
Nick Keighley a écrit :
And that all "good" OS's are POSIX compliant is merely your opinion


POSIX = Portable Operating System Interface.
Any decent OS should implement that interface, unless it refuses
portability.


Plenty of good embedded compilers implement good ANSI C and compile
code for the traget systems on non POSIX OSes (or no OS at all, such
small micros often can't even support an OS). The majority of CPUs
shipped in products cannot support a so called "decent" OS. A lot of
people forget about them because they are unseen. But more and more
these things are programmed in C rather than assembly because each
project you work on often requires a different CPU with very different
and sometimes alien instruction sets. So "standard" C is far more
portable than POSIX will ever be.

Feb 6 '06 #31
"SM Ryan" <wy*****@tango-sierra-oscar-foxtrot-tango.fake.org> wrote in
message news:11*************@corp.supernews.com...
# Bear in mind also that fread() returns the amount of data requested, if
# possible, whereas read() gives you no such guarantee. A lot of the
time,
# you have to write more code to use the low-level calls.

Other way around. In Unix, read() gives the number of bytes read
or an error indication. fread returns the number of complete items,
but in case of a partial item of more than one byte, you don't
know how many bytes were read.


Both statements are true. fread keeps trying to read until it hits EOF
or a read error; and if you are reading multibyte items you have no
way of knowing about partial items at the end. read will give you a
short count, the only promise being that you'll get at least one byte
if there are any bytes at all to be read.

BTW, X3J11 debated whether to include both read/write/seek and fread/
fwrite/fseek in the C Standard. We finally decided there should be
just one set, and that the fread/fwrite/fseek set made more sense
across operating systems.

P.J. Plauger
Dinkumware, Ltd.
http://www.dinkumware.com
Feb 6 '06 #32
On 2006-02-06, SM Ryan <wy*****@tango-sierra-oscar-foxtrot-tango.fake.org> wrote:
# Bear in mind also that fread() returns the amount of data requested, if
# possible, whereas read() gives you no such guarantee. A lot of the time,
# you have to write more code to use the low-level calls.

Other way around. In Unix, read() gives the number of bytes read
or an error indication. fread returns the number of complete items,
but in case of a partial item of more than one byte, you don't
know how many bytes were read.


There _isn't_ a partial item, as far as fread() is concerned - the bytes
that would be a "partial item" are still in the buffer, and can be
subsequently read with getchar().

[what isn't clear to me is what happens if you attempt to read items
larger than BUFSIZ, or generally whatever size your buffer happens to
be]
Feb 6 '06 #33
In article <43***********************@news.free.fr>,
loufoque <lo******@remove.gmail.com> wrote:
Nick Keighley a écrit :
And that all "good" OS's are POSIX compliant is merely your opinion


POSIX = Portable Operating System Interface.
Any decent OS should implement that interface, unless it refuses
portability.


Microsoft will rename Windows as "portable Windows interface".
Feb 6 '06 #34
Jordan Abel wrote:
On 2006-02-06, SM Ryan <wy*****@tango-sierra-oscar-foxtrot-tango.fake.org> wrote:
# Bear in mind also that fread() returns the amount of data requested, if
# possible, whereas read() gives you no such guarantee. A lot of the time,
# you have to write more code to use the low-level calls.

Other way around. In Unix, read() gives the number of bytes read
or an error indication. fread returns the number of complete items,
but in case of a partial item of more than one byte, you don't
know how many bytes were read.

There _isn't_ a partial item, as far as fread() is concerned - the bytes
that would be a "partial item" are still in the buffer, and can be
subsequently read with getchar().


Are you sure of that? Can you cite chapter and verse?

It seems to me this would be an onerous requirement,
considering that support for fseek()/fsetpos() is not
guaranteed for all streams. Lacking seekability, making
the characters of the partial item accessible to getchar()
would seem to require a buffer of sizeof(item) -- which
could, of course, be as large as (size_t)-1. I suppose one
could get away with a 32KB (C90) or 64KB (C99) buffer, at
the cost of restricting object sizes to the bare minima the
Standards require, but ...

Anyhow, I don't see "getc() can retrieve the bytes of
a trailing partial item" requirement anywhere in C99. Can
you explain where you find it?

--
Eric Sosman
es*****@acm-dot-org.invalid
Feb 7 '06 #35
On 2006-02-07, Eric Sosman <es*****@acm-dot-org.invalid> wrote:
Jordan Abel wrote:
On 2006-02-06, SM Ryan <wy*****@tango-sierra-oscar-foxtrot-tango.fake.org> wrote:
# Bear in mind also that fread() returns the amount of data requested, if
# possible, whereas read() gives you no such guarantee. A lot of the time,
# you have to write more code to use the low-level calls.

Other way around. In Unix, read() gives the number of bytes read
or an error indication. fread returns the number of complete items,
but in case of a partial item of more than one byte, you don't
know how many bytes were read.

There _isn't_ a partial item, as far as fread() is concerned - the bytes
that would be a "partial item" are still in the buffer, and can be
subsequently read with getchar().


Are you sure of that? Can you cite chapter and verse?

It seems to me this would be an onerous requirement,
considering that support for fseek()/fsetpos() is not
guaranteed for all streams.


Nor is it necessary. fread does not need to be implemented in pure
standard C. To suppose that it's "getc in a loop" is naive.
Lacking seekability, making the characters of the partial item
accessible to getchar() would seem to require a buffer of
sizeof(item) -- which could, of course, be as large as (size_t)-1.
I suppose one could get away with a 32KB (C90) or 64KB (C99)
buffer, at the cost of restricting object sizes to the bare minima
the Standards require, but ...
Or allocate a buffer on the stack within fread. It's unlikely to
actually be too large, given that the user also has to have
allocated a whole array of items in the given size.
Anyhow, I don't see "getc() can retrieve the bytes of a
trailing partial item" requirement anywhere in C99. Can you
explain where you find it?


Well, with a closer reading of the standard i'll concede that it's
not the case when using a stream that isn't seekable, but

The file position indicator for the stream (if defined) is advanced
by the number of characters successfully read. /* i'm assuming that
characters which are part of a partial item are not "successfully
read". */
Feb 7 '06 #36
Jordan Abel wrote:
On 2006-02-07, Eric Sosman <es*****@acm-dot-org.invalid> wrote:
Jordan Abel wrote:

On 2006-02-06, SM Ryan <wy*****@tango-sierra-oscar-foxtrot-tango.fake.org> wrote:
# Bear in mind also that fread() returns the amount of data requested, if
# possible, whereas read() gives you no such guarantee. A lot of the time,
# you have to write more code to use the low-level calls.

Other way around. In Unix, read() gives the number of bytes read
or an error indication. fread returns the number of complete items,
but in case of a partial item of more than one byte, you don't
know how many bytes were read.
There _isn't_ a partial item, as far as fread() is concerned - the bytes
that would be a "partial item" are still in the buffer, and can be
subsequently read with getchar().


Are you sure of that? Can you cite chapter and verse?

It seems to me this would be an onerous requirement,
considering that support for fseek()/fsetpos() is not
guaranteed for all streams.

Nor is it necessary. fread does not need to be implemented in pure
standard C. To suppose that it's "getc in a loop" is naive.


My naiveté may be the stuff of legend, but even I am
not *that* naive. Nonetheless, I find it hard to imagine
accepting data from a transient and un-replayable source
while retaining the ability to say "Woops! I went too far
and must make all this data available via a subsequent
getc()" without buffering the data *somewhere*. My point
is about the difficulty of providing such a buffer, of
potentially large size, and for potentially every input or
update stream.
Lacking seekability, making the characters of the partial item
accessible to getchar() would seem to require a buffer of
sizeof(item) -- which could, of course, be as large as (size_t)-1.
I suppose one could get away with a 32KB (C90) or 64KB (C99)
buffer, at the cost of restricting object sizes to the bare minima
the Standards require, but ...

Or allocate a buffer on the stack within fread. It's unlikely to
actually be too large, given that the user also has to have
allocated a whole array of items in the given size.


"On the stack within fread" won't suffice. If the
"overrun" characters are to be accessible to a subsequent
getc(), their buffer must persist until getc() empties it.
If the buffer were to vanish when fread() returned, how
would getc() find it? (Again, I'm not supposing that these
functions need be implemented in C; the persistence of the
buffer, not its location, is the troublesome point.)
Anyhow, I don't see "getc() can retrieve the bytes of a
trailing partial item" requirement anywhere in C99. Can you
explain where you find it?

Well, with a closer reading of the standard i'll concede that it's
not the case when using a stream that isn't seekable, but

The file position indicator for the stream (if defined) is advanced
by the number of characters successfully read. /* i'm assuming that
characters which are part of a partial item are not "successfully
read". */


The Standard is not clear about what constitutes "success"
here. Another reading is that fread() can "successfully" read
less than an item's worth of bytes, and this is the interpretation
P.J. Plauger uses in "The Standard C Library." PJP is officially
non-normative, of course, but he is widely considered to be
authoritatively non-normative ;-) That is, his interpretation
is likely to be a pretty good hint about the Committee's intent,
even if the Standard's expression of that intent has the ability
to confuse the rest of us.

--
Eric Sosman
es*****@acm-dot-org.invalid
Feb 7 '06 #37

This discussion thread is closed

Replies have been disabled for this discussion.

Similar topics

43 posts views Thread by Steven T. Hatton | last post: by
5 posts views Thread by markus | last post: by
reply views Thread by Holly | last post: by
1 post views Thread by Solo | last post: by
By using this site, you agree to our Privacy Policy and Terms of Use.