Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
483 views
in Technique[技术] by (71.8m points)

c - how to set close-on-exec by default

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!

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...