I'm implementing a library to run commands. The library is C, on Linux.
It currently does a popen() call to run a command and get output. The problem is that the command inherits all currently open file handlers.
If I did a fork/exec I could close the handlers in child explicitly. But that means re-implementing popen().
Can I set close-on-exec on all handlers without looping through them one by one?
Can I set close-on-exec as default for the process?
Thanks!
Kinda old question, but how about use
getpid()
in child afterfork()
, then look into/proc/PID/fd/
directory and just close all descriptors you find there (except 0, 1, 2 and the one you get fromopendir()
) and thenexecve()
?No and no.
You simply need to be careful and set close-on-exec on all file descriptors you care about.
Setting it is easy, though:
If you are running Linux kernel ≥2.6.23 and glibc ≥2.7,
open
(along with other similar syscalls) accepts a new flagO_CLOEXEC
:If you are running Linux kernel ≥2.6.24 and glibc ≥2.7,
fcntl
accepts a new argumentF_DUPFD_CLOEXEC
:If you are running Linux kernel ≥2.6.27 and glibc ≥2.9, there are new syscalls
pipe2
,dup3
, etc., and many more syscalls gain new*_CLOEXEC
flags:Note that POSIX specifies that
so if you're worried about that leak, don't be.