LinuxSir.cn,穿越时空的Linuxsir!

 找回密码
 注册
搜索
热搜: shell linux mysql
查看: 1410|回复: 9

监视文件的修改

[复制链接]
发表于 2003-9-17 14:35:17 | 显示全部楼层 |阅读模式
本人想写一个小程序,实现监视一个文件的修改,如果文件的被修改,那么那个子进程就发送一个信号给父进程。
window下有一个函数实现监视文件修改的作用,linux下不知道有没有?我写的这个程序很烂了,那个循环占用了我大量的系统资源,只是说明个意思罢了,
不知道有什么更好的方法,望大家不吝指教。
void sigdeal()
{
printf("sig received\n");
}

newpid = fork();
switch(newpid)
{
case -1:
perror("fork failed");
exit(1);
case 0:

while (1)
{
if (stat("test.log",&filestat) < 0)
{
printf("stat error\n");
exit(-1);
}
if(timelast != filestat.st_mtime)
{
timelast = filestat.st_mtime;
printf("TIME:%d\n",timelast);
if(kill(getppid(),SIGUSR1) < 0)
printf("kill error\n");
}
}
default:

signal(SIGUSR1,sigdeal);
pause();
发表于 2003-9-17 19:01:50 | 显示全部楼层
去查查FAM的资料
发表于 2003-9-17 23:02:31 | 显示全部楼层
更好的实现应该是在内核中实现的

另外如果不是很急
那么可以调用sleep
发表于 2003-9-18 10:58:06 | 显示全部楼层
找到一篇:
http://www-900.ibm.com/developer ... dnotify/index.shtml
他说的是监视目录,用的fd = open(".", O_RDONLY);,不知道单个文件行不行,我还没试过,不过参考一下tail -f命令,应该有实现的办法。
发表于 2003-9-18 15:27:40 | 显示全部楼层
应该也有吧
使用的是fcntl来声明要监视
 楼主| 发表于 2003-9-18 16:08:18 | 显示全部楼层
最初由 libinary 发表
找到一篇:
http://www-900.ibm.com/developer ... dnotify/index.shtml
他说的是监视目录,用的fd = open(".", O_RDONLY);,不知道单个文件行不行,我还没试过,不过参考一下tail -f命令,应该有实现的办法。

谢谢老兄,单个文件是不行的。我试验了。其中的fcntl(fd, F_NOTIFY, DN_MODIFY|DN_CREATE|DN_MULTISHOT);  F_NOTIFY没找到是什么意思。其它参数
都是针对文件夹的改变。
发表于 2003-9-18 19:00:15 | 显示全部楼层
这个可以实现文件监视,我大概写了一段代码,主要部分和上面的文章一样:

  1. #define _GNU_SOURCE
  2. #include <fcntl.h>
  3. #include <signal.h>
  4. #include <stdio.h>
  5. #include <stdlib.h>
  6. #include <unistd.h>

  7. static volatile int event_fd;

  8. static void handler(int sig, siginfo_t *si, void *data)
  9. {
  10.   event_fd = si->si_fd;
  11. }

  12. int
  13. main(void)
  14. {
  15.   int fdd, fd;
  16.   struct sigaction act;
  17.   char buf[100];
  18.   int n;
  19.   
  20.   act.sa_sigaction = handler;
  21.   sigemptyset(&act.sa_mask);
  22.   act.sa_flags = SA_SIGINFO;
  23.   sigaction(SIGRTMIN, &act, NULL);
  24.   
  25.   fd = open("ttxx", O_RDONLY); /* 打开需要监视的文件'ttxx' */
  26.   fdd = open(".", O_RDONLY);   /* 监视当前目录 */
  27.   fcntl(fdd, F_SETSIG, SIGRTMIN);
  28.   fcntl(fdd, F_NOTIFY, DN_MODIFY);
  29.   while(1){
  30.     while((n = read(fd, buf, 100)) > 0) /* 文件改变 */
  31.       write(1, buf, n);
  32.     pause();
  33.     fcntl(fdd, F_NOTIFY, DN_MODIFY); /* 恢复监视 */
  34.   }
  35.   
  36.   exit(0);
  37. }
复制代码

你可以试试,往ttxx里写东西马上就可以输出新写的文本,上面的“文件改变”有个问题,我这里是按上次读到的文件结尾开始向后读的,如果文件被截短了就会有错误,得不到新加的文本,应该再检查一下文件的长度,这个代码我就不加了,反正差不多就是这样了。
发表于 2003-9-18 19:06:39 | 显示全部楼层
可以通过拦截系统调用write()达到监视任何修改文件的 目的
发表于 2003-9-19 08:44:22 | 显示全部楼层
最初由 linux 发表
可以通过拦截系统调用write()达到监视任何修改文件的 目的

嗯,这个方法不错,不过麻烦了一些,还是用fcntl吧。
 楼主| 发表于 2003-11-14 09:05:51 | 显示全部楼层
最近看了ipc通信,觉得可以用消息队列来实现,不知道大家有什么看法?
您需要登录后才可以回帖 登录 | 注册

本版积分规则

快速回复 返回顶部 返回列表