我正在编写一个必须处理文件的程序(open / write / close / etc)。如果我打开一个文件并获取文件描述符,而其他一些进程将文件移动到文件系统上的另一个位置,我之前获得的文件描述符仍然有效。例如:
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 1
和OPEN 2
返回的文件描述符是不同的,即使我打开两次相同的文件。
问题: 是否有与文件系统无关的方法来识别当前进程是否已打开该文件?
答案 0 :(得分:3)
fstat
,并比较st_dev
和st_ino
。如果它们相等,则您拥有相同的文件。可能已使用相同inode的不同硬链接名称打开FD,但这种情况被视为具有同一文件的多个名称。
fstat
正是GNU cmp
所做的,如果你strace
,你可以看到它。 (如果你给它两次相同的输入,它有一个提前检查退出true。)
但为什么只有相同的文件系统才真实?正如我检查的inode编号包含硬盘上的位置,这在我看来是独立于文件系统的
每个st_dev
都有自己的st_ino
地址空间。 inode编号对应于文件系统中的位置,而不是相对于物理硬盘驱动器的起始位置。所以通常它相对于FS的分区的开始。
任何其他方式都没有意义:文件系统不关心他们是在RAID上,还是由Linux LVM组成的多个硬盘驱动器的逻辑块设备,或者不管。