我第一個想到的是:可能ioctl可以檢查文件。可惜我猜錯了,看了一下cp的源碼,原來如果一個文件正在運行,另一個進程再open以獲得寫權限的話,這個open本身就會失敗,返回-1,errno為ETXTBSY。
那麼cp -f 為什麼又可以?因為cp -f會先把目標文件(要被覆蓋的文件)刪掉,然後將源文件rename為目標文件名。
從內核代碼看,當運行一個二進制文件時
sys_execve()
do_execve()
open_exec()
deny_write_access()
這裡的deny_write_access會把文件對應inode的i_writecount成員減1,通常i_writecount的值就變成-1了(初始為0)
這時候再有進程想以寫模式open:
do_sys_open()
do_filp_open()
path_openat()
do_last()
nameidata_to_filp()
__dentry_open()
__get_file_write_access()
get_write_access()
get_write_access會發現inode的i_writecount成員為負數了,所以直接返回 -ETXTBSY