我正在实现一个库来运行命令.Linux上的库是C语言.
它目前执行popen()调用来运行命令并获取输出.问题是该命令继承了所有当前打开的文件处理程序.
如果我做了一个fork/exec,我可以明确地关闭孩子的处理程序.但这意味着重新实现popen().
我可以在所有处理程序上设置close-on-exec而不必逐个循环它们吗?
我可以将close-on-exec设置为进程的默认值吗?
谢谢!
不,不.
您只需要小心并在您关心的所有文件描述符上设置close-on-exec.
但是设置很简单:
#includefcntl(fd, F_SETFD, fcntl(fd, F_GETFD) | FD_CLOEXEC); #include /* 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
:
#includefd = open("...", ... | O_CLOEXEC);
如果您运行的Linux内核≥2.6.24且glibc≥2.7,则fcntl
接受新参数F_DUPFD_CLOEXEC
:
#includenewfd = fcntl(oldfd, F_DUPFD_CLOEXEC);
如果您运行的是Linux内核≥2.6.27和glibc≥2.9,有新的系统调用pipe2
,dup3
等等,还有更多的系统调用获得新的*_CLOEXEC
标志:
#define _GNU_SOURCE #includepipe2(pipefds, O_CLOEXEC); dup3(oldfd, newfd, O_CLOEXEC);
请注意,POSIX 指定了
该POPEN()函数应确保从以前的任何流POPEN()调用,父进程保持开放的新的子进程被关闭.
所以,如果你担心这个泄漏,不要.