linux 判断文件被其他进程占用

客户需要将转码器中电视直播频道的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未显示文件被占用,原因如下:

 

posted @ 2017-06-07 12:17  黑车司机  阅读(1441)  评论(0编辑  收藏  举报