我正在实现一个库来运行命令。该库是 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,则有新的系统调用 pipe2
、dup3
等,还有更多系统调用获得新的 *_CLOEXEC
标志:
#define _GNU_SOURCE
#include <unistd.h>
pipe2(pipefds, O_CLOEXEC);
dup3(oldfd, newfd, O_CLOEXEC);
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/