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
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
[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
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
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
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
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/>
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.
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
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.
> 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