freopen()

J

John Devereux

Hi,

I am a bit confused about the behaviour of freopen() and the standard
i/o streams.

I am trying to redirect a stream (stderr) to a particular "file". But,
if the call fails I want it to stay as it was, or at least be able to
redirect it somewhere else (e.g. stdout).

For example I would like to do,

..
stderr = freopen("/dev/errors","w", stderr); /* may fail */
if(!stderr) freopen("/dev/screen", "w", stderr);
 
R

Richard Tobin

John Devereux said:
I am trying to redirect a stream (stderr) to a particular "file". But,
if the call fails I want it to stay as it was, or at least be able to
redirect it somewhere else (e.g. stdout).

According to the standard, "The freopen function first attempts to
close any file that is associated with the specified stream". So if
opening the new file fails, it's too late to revert to the old one.

(You may be able to do this using something operating-system specific
instead, such as dup2() in unix.)

I see nothing that implies that you can't attempt to freopen() the
same stream again. (This may explain the "... any file ..." wording.)
stderr = freopen("/dev/errors","w", stderr); /* may fail */

Don't do this. You can't assign to stderr. freopen() changes the file
associated with the stream rather than creating a new stream. Just
do

if(!freopen("/dev/errors","w", stderr))
...

-- Richard
 
J

John Devereux

According to the standard, "The freopen function first attempts to
close any file that is associated with the specified stream". So if
opening the new file fails, it's too late to revert to the old one.

(You may be able to do this using something operating-system specific
instead, such as dup2() in unix.)

I see nothing that implies that you can't attempt to freopen() the
same stream again. (This may explain the "... any file ..."
wording.)


Don't do this. You can't assign to stderr. freopen() changes the file
associated with the stream rather than creating a new stream. Just
do

if(!freopen("/dev/errors","w", stderr))
...

Just to clarify, do you mean I can freopen() stderr with another
stream, even after the failure?

if(!freopen("/dev/errors","w", stderr))
{
stderr = freopen("/dev/screen","w", stderr);
}


I gather freopen() returns a null pointer if unsuccessful, does that
then mean (stderr==0) ? I read that sometimes stderr is implemented as
a macro e.g.

#define stderr (&iob[2])

But if so how can the call

stderr = freopen(..)

be legal?


Thanks,
 
J

John Devereux

But if so how can the call

stderr = freopen(..)

be legal?

Sorry, I now see it's not legal. I was confused because my
implementation did not complain.
 

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,755
Messages
2,569,536
Members
45,009
Latest member
GidgetGamb

Latest Threads

Top