小记——inotify文件监控

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 
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 
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  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 
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 
int inotify_rm_watch (int fd, uint32_t wd);


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


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

#include 
#include 
#include 
#include 
#include 
#include 
#include 

#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;
}




你可能感兴趣的:(个人小记)