如何识别两个文件描述符是否指向同一个文件



我正在编写一个必须处理文件的程序(打开/写入/关闭/等)。如果我打开一个文件并获取文件描述符,并且其他某个进程将文件移动到文件系统上的另一个位置,则我之前获得的文件描述符仍然有效。例如:

SYS_exit equ 0x3C
SYS_inotify_init equ 253
SYS_read equ 0x00
SYS_open equ 0x02
O_RDONLY equ 0x00
O_WRONLY equ 0x01
O_RDWR equ 0x02
section .text
global _start
_start:
mov rax, SYS_inotify_init
syscall
mov r13, rax            ;storing inotify instance
mov rax, SYS_open
mov rdi, dir_name_moved_from_file
mov rsi, O_RDWR
mov rdx, 0x00
syscall                 ; <---- OPEN 1
mov rax, SYS_open
mov rdi, dir_name_moved_from_file
mov rsi, O_RDWR
mov rdx, 0x00
syscall                 ; <---- OPEN 2
;listening inotify events and doing some other useful things
mov eax, SYS_exit
mov rdi, 0x00
syscall
section .data
dir_name_moved_from_file: db '/tmp/data/test', 0

问题是,即使我打开同一个文件两次,OPEN 1OPEN 2返回的文件描述符也是不同的。

问:是否有一种独立于文件系统的方法来识别文件是否已被当前进程打开?

fstat

在FD上,并比较st_devst_ino。 如果它们相等,则您拥有相同的文件。 FD 可能已使用同一 inode 的不同硬链接名称打开,但这种情况被视为同一文件有多个名称。

fstat正是 GNUcmp所做的,如果你strace它,你可以看到它。 (如果您给它两次相同的输入,它有一个提前退出检查以退出 true。

但是为什么只对相同的文件系统是正确的呢?当我检查索引节点号时,它包含硬盘驱动器上的位置,在我看来与文件系统无关

每个st_dev都有自己的st_ino地址空间。 索引节点号对应于文件系统中的位置,而不是相对于物理硬盘驱动器的启动位置。 因此,它通常相对于 FS 分区的开始。

它没有其他方式的意义:文件系统不在乎它们是否在 RAID 上,或者由具有 Linux LVM 的多个硬盘驱动器的一部分组成的逻辑块设备,或者其他什么。

最新更新