Linux provides an interface, inotify, for monitoring files—for example, to see when they are moved, read from, written to, or deleted.

Linux提供了inotify接口来监控文件——例如,文件的移动、读取、写入或者删除。

1. 初始化inotify

#include <sys/inotify.h>
int inotify_init1 (int flags);
The flags parameter is usually 0, but may be a bitwise OR of the following flags:
IN_CLOEXEC
Sets close-on-exec on the new file descriptor.
IN_NONBLOCK
Sets O_NONBLOCK on the new file descriptor.
On error, inotify_init1() returns −1 and sets errno to one of the following codes:
EMFILE
The per-user limit on the maximum number of inotify instances has been reached.
ENFILE
The system-wide limit on the maximum number of file descriptors has been
reached.
ENOMEM
There is insufficient memory available to complete the request.


2. 添加新的监控

#include <sys/inotify.h>
int inotify_add_watch (int fd,
const char *path,
uint32_t mask);
On success, the call returns a new watch descriptor. On failure, inotify_add_watch() returns −1 and sets errno to one of the following:
EACCES
Read access to the file specified by path is not permitted. The invoking process must be able to read the file to add a watch to it.
EBADF
The file descriptor fd is not a valid inotify instance.
EFAULT
The pointer path is not valid.
EINVAL
The watch mask, mask, contains no valid events.
ENOMEM
There is insufficient memory available to complete the request.
ENOSPC
The per-user limit on the total number of inotify watches has been reached.
Watch masks
The watch mask is a binary OR of one or more inotify events, which <inotify.h>defines:

IN_ACCESS
The file was read from.


IN_MODIFY
The file was written to.


IN_ATTRIB
The file’s metadata (for example, the owner, permissions, or extended attributes) was changed.


IN_CLOSE_WRITE
The file was closed and had been open for writing.


IN_CLOSE_NOWRITE
The file was closed and had not been open for writing.


IN_OPEN
The file was opened.


IN_MOVED_FROM
A file was moved away from the watched directory.


IN_MOVED_TO
A file was moved into the watched directory.


IN_CREATE
A file was created in the watched directory.


IN_DELETE
A file was deleted from the watched directory.


IN_DELETE_SELF
The watched object itself was deleted.


IN_MOVE_SELF
The watched object itself was moved.


The following events are also defined, grouping two or more events into a single value:


IN_ALL_EVENTS
All legal events.


IN_CLOSE
All events related to closing (currently, both IN_CLOSE_WRITE and IN_CLOSE_NOWRITE).


IN_MOVE
All move-related events (currently, both IN_MOVED_FROM and IN_MOVED_TO).


3. 读取监控(有变化时)

#include <sys/inotify.h>
struct inotify_event {
int wd; /* watch descriptor */
uint32_t mask; /* mask of events */
uint32_t cookie; /* unique cookie */
uint32_t len; /* size of 'name' field */
char name[]; /* nul-terminated name */
};
特别要注意name字段,它是一个zero-length arrays. 后面会有其用法例子。
char buf[BUF_LEN] __attribute__((aligned(4)));
ssize_t len, i = 0;
/* read BUF_LEN bytes' worth of events */
len = read (fd, buf, BUF_LEN);
/* loop over every read event until none remain */
while (i < len) {
struct inotify_event *event =
(struct inotify_event *) &buf[i];
printf ("wd=%d mask=%d cookie=%d len=%d dir=%s\n",
event->wd, event->mask,
event->cookie, event->len,
(event->mask & IN_ISDIR) ? "yes" : "no");
/* if there is a name, print it */
if (event->len)
printf ("name=%s\n", event->name);
/* update the index to the start of the next event */
i += sizeof (struct inotify_event) + event->len;
}


4. 移除监控

#include <inotify.h>
int inotify_rm_watch (int fd, uint32_t wd);


5. 销毁inotify实例
#include <inotify.h>
int inotify_rm_watch (int fd, uint32_t wd);


==>例程:监控日志文件的变化,并将其变化打印在屏幕上

#include <sys/inotify.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>

#define INOTIFY_LEN 1024
#define BUFFER_LEN 1024

int main()
{
	int fd;
	fd = inotify_init1(0);
	if (fd == -1)
	{
		perror("inotify_init1");
		exit(EXIT_FAILURE);
	}
	int wd = inotify_add_watch(fd, "./log.log", IN_CLOSE_WRITE);
	if (wd == -1)
	{
		perror("inotify_add_watch");
		exit(EXIT_FAILURE);
	}
	char buf[INOTIFY_LEN] __attribute__((aligned(4)));
	ssize_t len;
	off_t curr = 0;
	char f_buf[BUFFER_LEN];
	//
	int f_fd = open("./log.log", O_RDONLY);
	if (f_fd == -1)
	{
		perror("open");
		exit(EXIT_FAILURE);
	}
	curr = lseek(f_fd, 0, SEEK_END);
	close(f_fd);
	while(1)
	{
		//wait the inotify event
		len = read(fd, buf, INOTIFY_LEN);
		//
		f_fd = open("./log.log", O_RDONLY);
		if (f_fd == -1)
		{
			perror("open");
			exit(EXIT_FAILURE);
		}
		off_t n_curr = lseek(f_fd, 0, SEEK_END);
		if (n_curr > curr)
		{
			pread(f_fd, f_buf, BUFFER_LEN, curr);
			f_buf[n_curr - curr] = '\0';
			printf("%s\n", f_buf);
			curr = n_curr;
			close(f_fd);
		}
	}
	close(fd);
	return 0;
}




更多相关文章

  1. 将JSON文件中的所有时间戳转换为bash(Ubuntu)中的unix时间戳
  2. linux下如何导出.txt文件?
  3. Linux的五个文件查找命令:find,locate,whereis,which,type
  4. Re:从零开始的Linux之路(文件权限)
  5. Linux 删除文件夹和文件的命令
  6. Linux比较两个文件之间的不同
  7. 詹金斯死了,但是pid文件存在
  8. Linux下的文件时间
  9. Linux下非root用户能创建新文件,却不能拷贝文件的问题

随机推荐

  1. 【python之路45】tornado的用法 (三)
  2. 建模分析之机器学习算法(附python&R代码)
  3. Python新式类和经典类的区别
  4. python--继承--方法的重写---和父类的扩
  5. centos 7 mini版中安装Python3.x
  6. python小练习-对序列分组2
  7. Python csv。读者:我如何返回到文件的顶
  8. 大家好我刚来到请多帮助呀
  9. Python入门:函数加括号和不加括号的区别
  10. 与kubectl exec运行后台进程