防止文件描述符的重复使用

7
在Linux(或POSIX操作系统中)有没有办法确保在程序执行期间,即使关闭了一个文件并打开了另一个文件,也不会重用任何文件描述符?我的理解是,通常情况下,关闭的文件的文件描述符将被重新分配给新打开的文件。
我正在开发一个I/O跟踪项目,如果我可以假设在open() /fopen()调用之后,所有后续对该文件描述符的I/O都是针对同一文件,则可以简化工作。
我可以接受编译时或运行时的解决方案。
如果不可能实现,我可以在处理跟踪文件时进行自己的账户管理(记录所有打开和关闭调用的位置),但我更愿意在跟踪程序执行期间解决问题。

我认为你应该采取第二种方法(自己做会计)。改变文件描述符分配的行为(这是 POSIX 严格规定的)到非一致的方式将以微妙(可能危险)的方式破坏程序。 - R.. GitHub STOP HELPING ICE
3个回答

10
请注意,POSIX要求

open()函数应返回指定文件的文件描述符,该文件描述符是当前进程中未打开的最低文件描述符。

因此,在严格意义上,您的请求将更改程序的环境,不再符合POSIX标准。
话虽如此,我认为您最好使用LD_PRELOAD技巧拦截对close的调用并忽略它们。

谢谢,很高兴在POSIX规范中找到了我一直观察到的行为的确认。 - mhowison

1

您需要编写一个包含close(2)并在旧的FD上打开/dev/null的SO文件,然后使用$LD_PRELOAD将其加载到进程空间中,在启动应用程序之前。


实际上,我已经有一个__wrap_close()调用来实现跟踪例程,所以听起来我只需要在调用FD上的__real_close()之后,在该例程中插入open("/dev/null")即可。这总是有效吗?也就是说,我保证在open("/dev/null")调用中得到与__real_close()调用关闭的相同FD吗? - mhowison
1
不行。这就是为什么你只需要打开一次并使用 dup2(2) 来复制文件描述符。 - Ignacio Vazquez-Abrams
__wrap_close对于跟踪目的来说远远不够。考虑使用syscall(SYS_open, ...) - Employed Russian
好的,__wrap_close 对于我将要跟踪的场景已经足够了,这些场景是几乎总是使用 MPI-IO 层进行集体 I/O 的并行 HPC 应用程序。 - mhowison
在这种情况下,您可以轻松地在关闭包装器中执行防止重新使用的操作,但请参阅我的答案以了解其他要点。 - Employed Russian

1

您必须已经在ptrace应用程序,以拦截其文件打开和关闭操作。

似乎可以通过将dup2(X, Y); close(X);调用“注入”到应用程序中来防止FD重用,并将Y调整为任何您想要的内容。

但是,应用程序本身可能正在使用dup2来强制重新使用先前关闭的FD,如果您阻止这样做,则可能无法正常工作,因此我认为您只能在后处理步骤中处理此问题。

此外,如果不允许重用,编写一个将耗尽FD的应用程序非常容易。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接