1. 程式人生 > >linux 判斷文件被其他進程占用

linux 判斷文件被其他進程占用

電視 網絡端口 max amp 原因 opendir 結果 lose href

客戶需要將轉碼器中電視直播頻道的hls切片轉存出來,在拷貝文件時,需要判斷該切片文件是否正在被寫入,否則拷貝出來的切片文件不完整。

linux下程序fuser有這個功能,源碼在psmisc包裏,地址:https://gitlab.com/psmisc/psmisc,

fuser功能很強大,可以查找文件,目錄,網絡端口等,我們只用到文件部分

原理是遍歷/proc下的進程目錄,和fd中的描述符做比較

關鍵函數如下:

 1 static void
 2 check_dir(const pid_t pid, const char *dirname, struct device_list *dev_head,
3 struct inode_list *ino_head, const uid_t uid, const char access, 4 dev_t netdev) 5 { 6 char *dirpath, *filepath; 7 DIR *dirp; 8 struct dirent *direntry; 9 struct inode_list *ino_tmp; 10 struct device_list *dev_tmp; 11 struct stat st, lst; 12 13 if ((dirpath = malloc
(MAX_PATHNAME)) == NULL) 14 return; 15 if ((filepath = malloc(MAX_PATHNAME)) == NULL) 16 return; 17 18 snprintf(dirpath, MAX_PATHNAME, "/proc/%d/%s", pid, dirname); 19 if ((dirp = opendir(dirpath)) == NULL) 20 return; 21 while ((direntry = readdir(dirp)) != NULL) {
22 if (direntry->d_name[0] < 0 || direntry->d_name[0] > 9) 23 continue; 24 25 snprintf(filepath, MAX_PATHNAME, "/proc/%d/%s/%s", 26 pid, dirname, direntry->d_name); 27 if (stat(filepath, &st) != 0) { 28 fprintf(stderr, "Cannot stat file %s: %s\n", 29 filepath, strerror(errno)); 30 } 31 else 32 { 33 for (dev_tmp = dev_head; dev_tmp != NULL; 34 dev_tmp = dev_tmp->next) { 35 if (st.st_dev == dev_tmp->device) { 36 if (access == ACCESS_FILE 37 && (lstat(filepath, &lst) == 0) 38 && (lst.st_mode & S_IWUSR)) { 39 add_matched_proc(dev_tmp->name, 40 pid, uid, 41 ACCESS_FILEWR | 42 access); 43 } else { 44 add_matched_proc(dev_tmp->name, 45 pid, uid, 46 access); 47 } 48 } 49 } 50 for (ino_tmp = ino_head; ino_tmp != NULL; 51 ino_tmp = ino_tmp->next) { 52 if (st.st_dev == ino_tmp->device 53 && st.st_ino == ino_tmp->inode) { 54 if (access == ACCESS_FILE 55 && (lstat(filepath, &lst) == 0) 56 && (lst.st_mode & S_IWUSR)) { 57 add_matched_proc(ino_tmp->name, 58 pid, uid, 59 ACCESS_FILEWR | 60 access); 61 } else { 62 add_matched_proc(ino_tmp->name, 63 pid, uid, 64 access); 65 } 66 } 67 } 68 } 69 } /* while fd_dent */ 70 closedir(dirp); 71 }

運行結果:

技術分享

ps:

同學們測試時如使用vi打開文件,但是fuser未顯示文件被占用,原因如下:

技術分享

linux 判斷文件被其他進程占用