I need to close stdout and stderr for one of my C program. How is it possible without exiting the program in execution?
相关问题
- Multiple sockets for clients to connect to
- What is the best way to do a search in a large fil
- glDrawElements only draws half a quad
- Index of single bit in long integer (in C) [duplic
- Equivalent of std::pair in C
If you want to prevent your application from writing to the console, then:
Outputs:
Note: any attempt to use a FILE pointer after the file is closed is erroneous. I'm doing it in this case just to illustrate what closing these file descriptors might do to your application.
What have you tried? Doesn't
fclose
work?You can just:
For anybody wondering why you might want to do this, this is a fairly common task for a daemon/service process on Unix.
However you should be aware that closing a file descriptor may have unintended consequences:
fopen
that file descriptor (on Linux, at least) will replace fd 1, i.e. stdout. Any code that subsequently uses this will write to this file, which may not be what you intended.FILE*
pointers. Specifically:stdout
orstderr
(which areFILE*
pointers (see their definition) then writing to these whilstFILE*
is closed is undefined behaviour. This will likely crash your program in unexpected ways, not always at the point of the bug either. See undefined behaviour.The quick, one-line solution is to
freopen()
To say/dev/null
,/dev/console
under Linux/OSX ornul
on Windows. Alternatively, you can use your platform-specific implementation to re-open the file descriptors/handles as required.Actually you can also use the
close
function:Warning: I am not experienced in C at all, but recently read a slide that answers this question directly by Jim Meyering, a RedHat employee and GNUlib maintainer: https://www.gnu.org/ghm/2011/paris/slides/jim-meyering-goodbye-world.pdf. I merely summarize.
TL;DR
Get closeout.c and its dependencies from GNUlib into your source and call
as your first line in main.
Summary
First, some heads up warning, quoting POSIX:
Closing stream without handling its errors is not robust, and it is the same for stdout and stderr. Here is a list of errors you need to handle:
fclose(stdout)
ferror(stdout)
a.k.a. previous error__fpending(stdout)
a.k.a. stuff not flushedHandling these errors, as GNUlib implements in close-stream.c, is quoted below.
Notice:
__fpending
is special to glibc and may not be portable. OTOH, it is on the way to be standardized asfpending
.P.S.:
That is not a good reason to close stdout and stderr if you are writing a daemon according to http://cloud9.hedgee.com./scribbles/daemon#logging. You should let a daemon manager (such as daemon tools, runit, s6, nosh, OpenRC and systemd) handle the redirection.
However, you still should close any stream that the program has ever written to in the end to check for errors. Quote from close-stream.c: