我执行库运行命令。 图书馆是C,在Linux上。
目前,它做了POPEN()调用运行命令,并得到输出。 问题是,该命令将继承所有当前打开的文件处理程序。
如果我做了一个叉/ EXEC我可以在孩子关闭处理程序作了明确规定。 但是,这意味着重新实现POPEN()。
我可以设置近距离上的exec对所有的处理程序,而无需通过他们循环逐一?
我可以设置近距离上的exec为默认的过程?
谢谢!
我执行库运行命令。 图书馆是C,在Linux上。
目前,它做了POPEN()调用运行命令,并得到输出。 问题是,该命令将继承所有当前打开的文件处理程序。
如果我做了一个叉/ EXEC我可以在孩子关闭处理程序作了明确规定。 但是,这意味着重新实现POPEN()。
我可以设置近距离上的exec对所有的处理程序,而无需通过他们循环逐一?
我可以设置近距离上的exec为默认的过程?
谢谢!
没有,没有。
你只需要小心,并设置近距离上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);
需要注意的是POSIX 指定该
该POPEN()函数应确保从以前的popen()调用,父进程保持打开的任何数据流在新的子进程被关闭。
所以,如果你担心的是泄漏,不要。
有点老问题,但如何使用getpid()
儿童后fork()
然后寻找到/proc/PID/fd/
目录并关闭所有描述符,你会发现其中(除0,1,2,你从得到一个opendir()
然后execve()