vfork(2)已过时(从 POSIX2008 中删除),并且fork(2)非常有效,因为它使用了写时复制技术。
popen(3)不能关闭所有打开的文件,因为它不知道它们,也不知道哪些是相关的。想象一个程序,它获取 asocket
并将其文件描述符作为参数传递给popen
-ed 命令(或简单地说popen("time cat /etc/issue >&9; date","r")
......)。另请参见fcntl(2)与FD_CLOEXEC
、open(2)与O_CLOEXEC
、execve(2)
文件描述符是程序范围和进程范围的稀缺资源,正确管理它们是您的责任。您应该知道在您的子进程之前应该关闭哪些 fd-s execve
。execve
如果您知道-d是什么程序以及它需要什么close
fds ,那么您可以for (int i=STDERR_FILENO+1; i<64; i++) (void) close(i);
在execve
.
如果您正在编写可重用库,请记录其有关文件描述符(以及任何其他全局进程范围资源)的策略,并可能用于FD_CLOEXEC
它自己获取的任何文件描述符(不是作为显式参数或数据),例如供内部使用。
看起来您正在重新发明p2open(那么您可能需要了解您FILE
在 C 标准库中的实现细节,或者小心谨慎地使用fdopen(3));你可能会找到它的一些实现。请注意,使用它的进程可能需要一些事件循环(例如,在poll(2) ... 之上)以避免潜在的死锁(父进程和子进程在读取时都被阻塞)。
您是否考虑过使用一些现有的事件循环基础设施(例如libevent、libev、 GTK 的glib等......)?
顺便说一句,Linux为其C 标准库提供了几个免费软件实现。GNU libc很常见,但还有musl -libc和其他几个。研究你的 libc 的源代码。