c - 如何默认设置close-on-exec

标签 c linux exec fork

我正在实现一个库来运行命令。该库是 C,在 Linux 上。

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

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

我可以在所有处理程序上设置 close-on-exec 而无需逐一循环吗?

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

谢谢!

最佳答案

没有也没有。

您只需要小心并在您关心的所有文件描述符上设置 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);
}

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

#include <unistd.h>
fd = open("...", ... | O_CLOEXEC);

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

#include <fcntl.h>
newfd = fcntl(oldfd, F_DUPFD_CLOEXEC);

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

#define _GNU_SOURCE
#include <unistd.h>
pipe2(pipefds, O_CLOEXEC);
dup3(oldfd, newfd, O_CLOEXEC);

请注意 POSIX specifies那个

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.

因此,如果您担心 泄漏,请不要担心。

关于c - 如何默认设置close-on-exec,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1643304/

相关文章:

c - 出售苹果股票(一进一出)

php - 使用来自 PHP 网页的输入参数运行 .exe

c - Valgrind 报告使用 fexecve 调用发生了不可能的事情

php - 由 PHP exec() 函数调用在后台执行的两个 linux 命令

c - 为什么我不能在不使用 fflush() 的情况下在 C 中将 printf() 输出到标准输出?

c - MSP430 - 在结构中混合端口寄存器

c++ - 将寄存器设计成可由 C 和 C++ 访问的外围设备的最佳实践?

linux - 您可以在 Go 中运行程序的独立实例吗?

linux - 使用 Git 保留文件权限

php - Composer 安装 : the json extension is missing