Email List: Xaustin-group-lX
[All Lists]

Re: C99 questions about freopen(NULL, ...)

To: yyyyyyyyyyyyyy@xxxxxxxxxxxxx
Subject: Re: C99 questions about freopen(NULL, ...)
From: Geoff Clare <yyy@xxxxxxxxxxxxx>
Date: Tue, 2 Sep 2003 19:23:25 +0100
References: <20030830140823.GA21777@squonk> <20030902041818.GI72322@finch-staff-1.thus.net>
Clive D.W. Feather <yyyyy@xxxxxxxxx> wrote, on 02 Sep 2003:
>
> > 1. Was freopen(NULL, ...) added to the C Standard in order to provide
> > applications with a way of completely re-initialising a stream without
> > needing to know the file name?  Or is the whole point just the mode
> > change, with other effects considered secondary?
> 
> The mode change.
> 
> > I'm thinking that
> > maybe the idea is that an application which opens a file read-write to
> > write some data that it will then read back could change the mode to
> > read-only after it has written the data.  Is that the kind of use that
> > was envisaged, or something else?
> 
> Actually, where this started was with the question:
> 
>     How do I write cat(1), or cpio(1), or ..., in Standard C?
> 
> More precisely, if a program is required to read standard input or write
> standard output in binary mode, how does the programmer do this, since thos
> streams will initially have opened in text mode.

Yes, of course!  I hadn't thought about changing between text and binary
modes on non-UNIX systems.  (Concentrating too much on UNIX specifics.)

Unfortunately I think the current requirements in C99 don't quite
provide the intended capability.  Sure you can change stdin and stdout
to binary mode, but I can't see any way to implement cat properly using
freopen(NULL, ...), given that the "as if" requirement means that
changing to mode "rb" rewinds the stream and changing to mode "wb"
truncates the file.

It would work fine in the (admittedly common) case where the file
pointer for stdin is initially at the beginning of the file, and
the file open on stdout is empty.  I can't see how to make it work
for the other cases.

You can't use ftell()/fseek() on stdin before and after the change to
"rb" because the value returned by ftell() for text and binary streams
can be different.  (I assume fgetpos()/fsetpos() would have the same
problem, although that's not clear from their descriptions.)
Even if you could somehow restore the initial position for stdin, the
situation for stdout is much worse.  The only way to avoid truncating
the file would be to change to "ab" instead of "wb", but then if the
file position wasn't at EOF the data will be written in the wrong place.

Why on earth did the C99 folks put the "as if" clause in there in the
first place?  It seems to have caused nothing but problems.  Surely it
would have been much more useful to specify that freopen(NULL, ...)
changes the mode *without* the side effects that an freopen() with the
filename would have had, not with them.

-- 
Geoff Clare <yyyyyyy@xxxxxxxxxxxxx>
The Open Group, Apex Plaza, Forbury Road, Reading, RG1 1AX, England

<Prev in Thread] Current Thread [Next in Thread>