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:
#include <fcntl.h>
fcntl(fd, F_SETFD, fcntl(fd, F_GETFD) | FD_CLOEXEC);
#include <unistd.h>
/* please don't do this */
for (i = getdtablesize(); i --> 3;) {
if ((flags = fcntl(i, F_GETFD)) != -1)
fcntl(fd, F_SETFD, flags | FD_CLOEXEC);
}
If you are running Linux kernel ≥2.6.23 and glibc ≥2.7, open
(along with other similar syscalls) accepts a new flag O_CLOEXEC
:
#include <unistd.h>
fd = open("...", ... | O_CLOEXEC);
If you are running Linux kernel ≥2.6.24 and glibc ≥2.7, fcntl
accepts a new argument F_DUPFD_CLOEXEC
:
#include <fcntl.h>
newfd = fcntl(oldfd, F_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:
#define _GNU_SOURCE
#include <unistd.h>
pipe2(pipefds, O_CLOEXEC);
dup3(oldfd, newfd, O_CLOEXEC);
Note that POSIX specifies that
The popen() function shall ensure that any streams from previous popen() calls that remain open in the parent process are closed in the new child process.
so if you're worried about that leak, don't be.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…