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

redirecting stdout,stderr and stdin to /dev/null

3,137 views
Skip to first unread message

ikeaboy

unread,
Jan 2, 2003, 7:11:49 PM1/2/03
to
Hello.

I wonder if this is the right way to redirect stdout, stderr and
stdin to /dev/null:

freopen("/dev/null", "w", stdout);
freopen("/dev/null", "w", stderr);
freopen("/dev/null", "r", stdin);

Is the mode correct ? Would "w+" be better ?

Also, in lot of open source code is this:

close(0); close(1); close(2);
open("/dev/null",O_RDWR); dup(0); dup(0);

Which approach is better and more portable ?

--
ikeaboy

Shaun

unread,
Jan 2, 2003, 7:29:56 PM1/2/03
to
> I wonder if this is the right way to redirect stdout, stderr and
> stdin to /dev/null:
>
> freopen("/dev/null", "w", stdout);
> freopen("/dev/null", "w", stderr);
> freopen("/dev/null", "r", stdin);

This won't work, all you're doing is redirecting the stdio handles for
stdout/err/in, not closing the actually file descriptors.

> close(0); close(1); close(2);
> open("/dev/null",O_RDWR); dup(0); dup(0);
>
> Which approach is better and more portable ?

Definitely this one, it's portable across pretty much every unix known to
man.

Cheers,
Shaun

ikeaboy

unread,
Jan 2, 2003, 10:48:10 PM1/2/03
to
* Shaun <del...@zero.spam.progsoc.org> [Fri, 03 Jan 2003]:

>> I wonder if this is the right way to redirect stdout, stderr
>> and stdin to /dev/null:

[SNIP]

> This won't work, all you're doing is redirecting the stdio
> handles for stdout/err/in, not closing the actually file
> descriptors.

When I examine such program with lsof I can see:

redir 25055 trip 0r CHR 1,3 66788 /dev/null
redir 25055 trip 1w CHR 1,3 66788 /dev/null
redir 25055 trip 2w CHR 1,3 66788 /dev/null

That would suggest the file descriptors *were* redirected.

The code is simple:

freopen("/dev/null", "w", stdout);
freopen("/dev/null", "w", stderr);
freopen("/dev/null", "r", stdin);

fprintf(stdout, "stdio - stdout\n");
write(STDOUT_FILENO, "aaaa\n", 5);
sleep(120);

Also it outputs absolutely nothing.

>> Which approach is better and more portable ?
>
> Definitely this one, it's portable across pretty much every
> unix known to man.

Yes, but I had also other OSes on my mind. The close() and dup()
functions are unix-specific, but the freopen approach is based on
the C standard.

--
ikeaboy

Shaun

unread,
Jan 2, 2003, 11:27:25 PM1/2/03
to

> > This won't work, all you're doing is redirecting the stdio
> > handles for stdout/err/in, not closing the actually file
> > descriptors.
>
> When I examine such program with lsof I can see:

Neat, I apologise for my baseless assertion.

> > Definitely this one, it's portable across pretty much every
> > unix known to man.
>
> Yes, but I had also other OSes on my mind. The close() and dup()
> functions are unix-specific, but the freopen approach is based on
> the C standard.

Well, which platforms were you thinking of in particular? Only unix like
systems have /dev/null.

Cheers,
Shaun

ty

unread,
Jan 2, 2003, 11:50:19 PM1/2/03
to

"ikeaboy" <trip...@yahoo.com> wrote in message
news:av315p$19m4$1...@ns.felk.cvut.cz...

>
> When I examine such program with lsof I can see:
>
> redir 25055 trip 0r CHR 1,3 66788 /dev/null
> redir 25055 trip 1w CHR 1,3 66788 /dev/null
> redir 25055 trip 2w CHR 1,3 66788 /dev/null
>
> That would suggest the file descriptors *were* redirected.
>

Both solutions (redir to /dev/null, and closing 0, 1 and 2) are valid -
which you use is up to you.
In fact I can't really see where redirecting to /dev/null would be
beneficial - you're wasting resources in the form of 3 descriptors that
you're not using. Much friendlier to busy systems to close the FD's.

hth
ty


Shaun

unread,
Jan 3, 2003, 12:17:46 AM1/3/03
to

> > redir 25055 trip 0r CHR 1,3 66788 /dev/null
> > redir 25055 trip 1w CHR 1,3 66788 /dev/null
> > redir 25055 trip 2w CHR 1,3 66788 /dev/null
> >
> > That would suggest the file descriptors *were* redirected.
>
> Both solutions (redir to /dev/null, and closing 0, 1 and 2) are valid -
> which you use is up to you.
> In fact I can't really see where redirecting to /dev/null would be
> beneficial - you're wasting resources in the form of 3 descriptors that
> you're not using. Much friendlier to busy systems to close the FD's.

Well, it is customary to redirect them to /dev/null. This prevents a
paranoid program from detecting errors reading/writing to them and bombing
out.

Cheers,
Shaun

Andrew Gierth

unread,
Jan 3, 2003, 1:27:35 AM1/3/03
to ikeaboy
>>>>> "ikeaboy" == ikeaboy <trip...@yahoo.com> writes:

ikeaboy> Hello.
ikeaboy> I wonder if this is the right way to redirect stdout, stderr
ikeaboy> and stdin to /dev/null:

ikeaboy> freopen("/dev/null", "w", stdout);
ikeaboy> freopen("/dev/null", "w", stderr);
ikeaboy> freopen("/dev/null", "r", stdin);

ikeaboy> Is the mode correct ? Would "w+" be better ?

ikeaboy> Also, in lot of open source code is this:

ikeaboy> close(0); close(1); close(2);
ikeaboy> open("/dev/null",O_RDWR); dup(0); dup(0);

ikeaboy> Which approach is better and more portable ?

The first approach isn't guaranteed to work, because freopen() isn't
guaranteed to reuse the same underlying file descriptors for the new
stream. You may find it works anyway as a result of pure coincidence.
If the same descriptors _aren't_ reused, then stdio functions used to
write to "stderr" will write to /dev/null, but POSIX writes to
STDERR_FILENO will not (and will possibly go to some completely
unexpected place if you're really unlucky). (Note that some library
functions can write to standard error, and in some cases this means
STDERR_FILENO rather than "stderr".)

The second approach avoids this problem. However, a slightly safer
way of doing it is:

int fd = open("/dev/null",O_RDWR);
/* handle failure of open() somehow */
dup2(fd,0);
dup2(fd,1);
dup2(fd,2);
if (fd > 2)
close(fd);

This has the same effect as the code you posted, but has the advantage
of being thread-safe. (relying on open()/dup() to pick the right
descriptor numbers is only safe if there are no other threads running)

--
Andrew.

comp.unix.programmer FAQ: see <URL: http://www.erlenstar.demon.co.uk/unix/>

Andrew Gierth

unread,
Jan 3, 2003, 1:30:05 AM1/3/03
to
>>>>> "ty" == ty <acm...@yahoo.com.au> writes:

ty> Both solutions (redir to /dev/null, and closing 0, 1 and 2) are
ty> valid - which you use is up to you.

ty> In fact I can't really see where redirecting to /dev/null would
ty> be beneficial - you're wasting resources in the form of 3
ty> descriptors that you're not using. Much friendlier to busy
ty> systems to close the FD's.

extremely bad advice - you should _never_ intentionally leave
descriptors 0, 1 or 2 closed. If you're not going to use them, then by
all means redirect them to /dev/null - but if you leave them closed then
some data file in your program may end up open on descriptor 2, and some
library functions will write to descriptor 2 given sufficient provocation,
thus corrupting your data.

ikeaboy

unread,
Jan 3, 2003, 12:30:05 PM1/3/03
to
* Andrew Gierth <and...@erlenstar.demon.co.uk> [Fri, 03 Jan 2003]:

> The second approach avoids this problem. However, a slightly safer
> way of doing it is:
>
> int fd = open("/dev/null",O_RDWR);
> /* handle failure of open() somehow */
> dup2(fd,0);
> dup2(fd,1);
> dup2(fd,2);
> if (fd > 2)
> close(fd);

> This has the same effect as the code you posted, but has the
> advantage of being thread-safe. (relying on open()/dup() to pick
> the right descriptor numbers is only safe if there are no other
> threads running)

Thank you for the explanation.

But I still wonder what happens to the open stdio streams
connected to these file descriptors. I suppose that any IO
operation performed on them would result in an error.
That was the reason why I thought that the freopen() approach
is cleaner. Should I fclose() them first ?

--
ikeaboy

Barry Margolin

unread,
Jan 3, 2003, 1:23:28 PM1/3/03
to
In article <av4has$c2gr9$1...@ID-174976.news.dfncis.de>,

The stdio streams eventually just read/write to the corresponding Unix
fd's. When you dup the fd's, stdio will continue to use those fd's, which
are now connected to /dev/null, so no errors should result.

--
Barry Margolin, bar...@genuity.net
Genuity, Woburn, MA
*** DON'T SEND TECHNICAL QUESTIONS DIRECTLY TO ME, post them to newsgroups.
Please DON'T copy followups to me -- I'll assume it wasn't posted to the group.

Juergen....@jnickelsen.de

unread,
Jan 4, 2003, 10:52:56 AM1/4/03
to
"Shaun" <del...@zero.spam.progsoc.org> writes:

> Only unix like systems have /dev/null.

True, but others have similar devices with names like "NUL" or "NL:"
(IIRC) or whatever. This could be a compile-time definition, with no
code changes necessary.

--
Ask Bill why function code 6 ends in a dollar sign. No one in the
world knows that but me. -- Gary Kildall

0 new messages