【问题标题】:How to enumerate file descriptors? (to close them after fork)如何枚举文件描述符? (分叉后关闭它们)
【发布时间】:2014-04-12 16:40:00
【问题描述】:

我有一个大型程序。它非常喜欢打开文件(与它们一起工作,数量可能很大 - 超过 10k )。在某个时候,我想产生一个可以过自己的生活的子进程(进程外网络浏览器)。由于其大小(> 10GB 的代码)和第三方(以及插件)依赖项,我无法控制谁以及如何在我的主程序中创建文件。我想要:

  • 默认为 O_CLOEXEC / FD_CLOEXEC。我怀疑没有这种能力。或者
  • 一种枚举所有文件(套接字、管道等)描述符以便能够在 fork 后关闭它们的方法。感兴趣的操作系统:Mac OS X 和 Linux。

【问题讨论】:

  • “我无法控制谁以及如何在我的主程序中创建文件”。你能解释清楚一点吗?
  • 有时只是糟糕的代码,像网络和磁盘这样的几个域。大量的图书馆,其中一些是第三方的。也就是说,如果我在某个库的帮助下打开文件,我无法控制文件在其中的打开方式,因此无法设置 FD_CLOEXEC 标志。
  • 让你的程序维护一个你确实想要保持打开的fds的小列表,并关闭所有fds,除了这个列表中的那些。

标签: c linux macos fork posix


【解决方案1】:

文件描述符都是小的正整数,所以你可以枚举它们并关闭它们。关闭未打开的会导致错误,但您可以忽略:

#include <sys/resource.h>
struct rlimit lim;
getrlimit(RLIMIT_NOFILE, &lim);
for (int i = 3; i < lim.rlim_cur; i++)
    close(i);   // close all file descriptors other that stdin/stdout/stderr

【讨论】:

  • 杀光他们。 Linux 会知道自己的。
【解决方案2】:

不能默认设置close-on-exec。(相关:how to set close-on-exec by default)。

枚举一个进程内的所有文件描述符,可以在Linux中查找/proc/PID/fd/。 然而,在 Mac OS X 中,除了使用 lsof(8) 实用程序外,我没有任何编程解决方案。 lsof(8) 也可以在 Linux 上使用。

编辑: 或者,您可以覆盖open(2) 调用以默认指定O_CLOSEXEC,并在Linux 上使用LD_PRELOAD 运行您的程序。 对于 Mac,请关注 What is the exact equivalent to LD_PRELOAD on OSX?

【讨论】:

  • 启动外部 lsof 似乎有点不对...谢谢你的 linux 选项。
  • @dev_null 覆盖 open(2) 调用怎么样?
  • 这是可能的,我之前什至做过类似的事情,但并不是所有的东西都是通过 open 打开的。所以应该有一套功能和任务很快就变得复杂了。如果我想处理所有情况(stackoverflow.com/questions/20387225/…
猜你喜欢
  • 2021-03-12
  • 2013-05-23
  • 1970-01-01
  • 2017-09-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-01-12
  • 2015-12-30
相关资源
最近更新 更多