popen() implementation,fd leaks,and vfork()



popen()的glibc实现中,它指定

popen()函数应确保来自先前popen()调用的所有在父进程中保持打开的流在新的子进程中关闭。

为什么?如果目的是避免fd泄漏,为什么不直接关闭所有打开的fd呢?

popen()的glibc实现使用fork()。虽然在fork()exec()之间有dup2()close()调用,但是否有可能用vfork()代替fork()以提高性能?

popen()的Linux实现是基于fork()而不是vfork()吗?为什么(或为什么不)?

我将编写一个双向版本的popen(),它返回两个FILE*:一个用于读,一个用于写。我如何正确地实现它?它应该是线程安全的,没有fd泄漏。

vfork(2)已经过时了(从POSIX2008中删除),而fork(2)非常高效,因为它使用了写时复制技术。

popen(3)不能关闭所有打开的文件,因为它不知道它们,也不知道哪些是相关的。设想一个程序获取一个socket,并将其文件描述符作为参数传递给popen -ed命令(或简单地称为popen("time cat /etc/issue >&9; date","r") ....)。参见fcntl(2) with FD_CLOEXEC, open(2) with O_CLOEXEC, execve(2)

文件描述符是程序范围和进程范围的资源,正确管理它们是您的责任。您应该知道在execve之前子进程中应该关闭哪些fd。如果您知道execve -d是什么程序以及它需要什么fds,那么您可以在execve之前close所有其他fds(或者大多数fds,可能使用for (int i=STDERR_FILENO+1; i<64; i++) (void) close(i);)。

如果你正在编写一个可重用的库,文档关于文件描述符(以及任何其他全局进程范围的资源)的策略,并且可能在它自己获取的任何文件描述符上使用FD_CLOEXEC(不是作为显式参数或数据),例如用于内部使用。

它看起来像你在重新发明p2open(那么你可能需要了解你的FILE在你的C标准库的实现细节,否则使用fdopen(3)小心谨慎);您可能会找到它的一些实现。注意,使用该方法的进程可能需要一些事件循环(例如上面的poll(2)…)来避免潜在的死锁(父进程和子进程在读取时都阻塞)。

您是否考虑使用一些现有的事件循环基础设施(例如libevent, libev, GTK中的glib等....)?

顺便说一句,Linux有几个自由软件实现了它的C标准库。GNU libc是非常常见的,但也有musl-libc和其他几个libc。学习libc的源代码

相关内容

  • 没有找到相关文章