找出哪些文件描述符共享相同的“打开文件描述”

Sté*_*las 22 file-descriptors

如果我这样做(在类似 Bourne 的外壳中):

exec 3> file 4>&3 5> file 6>> file
Run Code Online (Sandbox Code Playgroud)

文件描述符 3 和 4,因为 4dup()来自 3,共享相同的打开文件描述(相同的属性,文件内的相同偏移量......)。虽然该进程的文件描述符 5 和 6 位于不同的打开文件描述上(例如,它们在文件中都有自己的指针)。

现在,在lsof输出中,我们看到的是:

zsh     21519 stephane    3w   REG  254,2        0 10505865 /home/stephane/file
zsh     21519 stephane    4w   REG  254,2        0 10505865 /home/stephane/file
zsh     21519 stephane    5w   REG  254,2        0 10505865 /home/stephane/file
zsh     21519 stephane    6w   REG  254,2        0 10505865 /home/stephane/file
Run Code Online (Sandbox Code Playgroud)

更好一点lsof +fg

zsh     21519 stephane    3w   REG          W,LG  254,2        0 10505865 /home/stephane/file
zsh     21519 stephane    4w   REG          W,LG  254,2        0 10505865 /home/stephane/file
zsh     21519 stephane    5w   REG          W,LG  254,2        0 10505865 /home/stephane/file
zsh     21519 stephane    6w   REG       W,AP,LG  254,2        0 10505865 /home/stephane/file
Run Code Online (Sandbox Code Playgroud)

(此处在 Linux 3.16 上)因为我们看到 fd 6 具有不同的标志,因此它必须与fd 3、4 或 5 上的打开文件描述不同,但由此我们无法判断 fd 5 位于不同的打开文件描述。使用-o,我们也可以看到偏移量,但同样的偏移量并不能保证它是相同的打开文件描述

是否有任何非侵入性的1方法可以找出答案?外部的,还是进程自己的文件描述符?


1 . 一种启发式方法可能是更改一个 fd 的标志,fcntl()然后查看其他文件描述符的标志更新结果,但这显然不是理想的,也不是万无一失的

min*_*avg 5

对于 Linux 3.5 及更高版本,可以使用kcmp(2)来完成:

KCMP_FILE

  • 检查进程pid1中的文件描述符idx1是否引用与进程pid2中的文件描述符idx2相同的打开文件描述(请参阅open(2))。由于dup(2)(和类似的)fork(2)或通过域套接字传递文件描述符(请参阅unix(7)),可能会出现引用同一打开文件描述的两个文件描述符。

手册页提供了一个专门针对 OP 所询问的用例的示例。请注意,此系统调用需要使用 set 来编译内核CONFIG_CHECKPOINT_RESTORE