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

  • Thread starter lovecreatesbeauty
  • Start date
C

Christian Bau

Ian Collins said:
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...
 
I

Ian Collins

Keith said:
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 :)
 
N

Nick Keighley

loufoque said:
Vladimir S. Oka a écrit :


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
 
K

Keith Thompson

Ian Collins said:
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 :cool:},
so I'll take the question seriously.

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

Ian Collins

Keith said:
I see the smiley, but apparently I'm too dense to get the joke :cool:},
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.
 
L

loufoque

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.
 
I

Ian Collins

loufoque said:
Nick Keighley a écrit :



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

Which many do....
 
N

Nick Keighley

loufoque said:
Nick Keighley a écrit :

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?
 
S

SM Ryan

# 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.
 
S

SM Ryan

# 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.
 
S

slebetman

loufoque said:
Nick Keighley a écrit :


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.
 
P

P.J. Plauger

# 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
 
J

Jordan Abel

# 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]
 
C

Christian Bau

loufoque said:
Nick Keighley a écrit :


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

Microsoft will rename Windows as "portable Windows interface".
 
E

Eric Sosman

Jordan said:
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?
 
J

Jordan Abel

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". */
 
E

Eric Sosman

Jordan said:
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.
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.)
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.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,772
Messages
2,569,593
Members
45,104
Latest member
LesliVqm09
Top