如何默认设置close-on-exec

n-a*_*der 18 c linux fork exec

我正在实现一个库来运行命令.Linux上的库是C语言.

它目前执行popen()调用来运行命令并获取输出.问题是该命令继承了所有当前打开的文件处理程序.

如果我做了一个fork/exec,我可以明确地关闭孩子的处理程序.但这意味着重新实现popen().

我可以在所有处理程序上设置close-on-exec而不必逐个循环它们吗?

我可以将close-on-exec设置为进程的默认值吗?

谢谢!

eph*_*ent 28

不,不.

您只需要小心并在您关心的所有文件描述符上设置close-on-exec.

但是设置很简单:

#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);
}
Run Code Online (Sandbox Code Playgroud)

如果您运行的Linux内核≥2.6.23和glibc≥2.7,open(以及其他类似的系统调用)接受一个新标志O_CLOEXEC:

#include <unistd.h>
fd = open("...", ... | O_CLOEXEC);
Run Code Online (Sandbox Code Playgroud)

如果您运行的Linux内核≥2.6.24且glibc≥2.7,则fcntl接受新参数F_DUPFD_CLOEXEC:

#include <fcntl.h>
newfd = fcntl(oldfd, F_DUPFD_CLOEXEC);
Run Code Online (Sandbox Code Playgroud)

如果您运行的是Linux内核≥2.6.27和glibc≥2.9,有新的系统调用pipe2,dup3等等,还有更多的系统调用获得新的*_CLOEXEC标志:

#define _GNU_SOURCE
#include <unistd.h>
pipe2(pipefds, O_CLOEXEC);
dup3(oldfd, newfd, O_CLOEXEC);
Run Code Online (Sandbox Code Playgroud)

请注意,POSIX 指定

POPEN()函数应确保从以前的任何流POPEN()调用,父进程保持开放的新的子进程被关闭.

所以,如果你担心这个泄漏,不要.