diff options
Diffstat (limited to 'man7/inotify.7')
-rw-r--r-- | man7/inotify.7 | 1100 |
1 files changed, 0 insertions, 1100 deletions
diff --git a/man7/inotify.7 b/man7/inotify.7 deleted file mode 100644 index 51faaaa..0000000 --- a/man7/inotify.7 +++ /dev/null @@ -1,1100 +0,0 @@ -.\" Copyright (C) 2006, 2014 Michael Kerrisk <mtk.manpages@gmail.com> -.\" Copyright (C) 2014 Heinrich Schuchardt <xypron.glpk@gmx.de> -.\" -.\" SPDX-License-Identifier: Linux-man-pages-copyleft -.\" -.TH inotify 7 2023-10-31 "Linux man-pages 6.7" -.SH NAME -inotify \- monitoring filesystem events -.SH DESCRIPTION -The -.I inotify -API provides a mechanism for monitoring filesystem events. -Inotify can be used to monitor individual files, -or to monitor directories. -When a directory is monitored, inotify will return events -for the directory itself, and for files inside the directory. -.P -The following system calls are used with this API: -.IP \[bu] 3 -.BR inotify_init (2) -creates an inotify instance and returns a file descriptor -referring to the inotify instance. -The more recent -.BR inotify_init1 (2) -is like -.BR inotify_init (2), -but has a -.I flags -argument that provides access to some extra functionality. -.IP \[bu] -.BR inotify_add_watch (2) -manipulates the "watch list" associated with an inotify instance. -Each item ("watch") in the watch list specifies the pathname of -a file or directory, -along with some set of events that the kernel should monitor for the -file referred to by that pathname. -.BR inotify_add_watch (2) -either creates a new watch item, or modifies an existing watch. -Each watch has a unique "watch descriptor", an integer -returned by -.BR inotify_add_watch (2) -when the watch is created. -.IP \[bu] -When events occur for monitored files and directories, -those events are made available to the application as structured data that -can be read from the inotify file descriptor using -.BR read (2) -(see below). -.IP \[bu] -.BR inotify_rm_watch (2) -removes an item from an inotify watch list. -.IP \[bu] -When all file descriptors referring to an inotify -instance have been closed (using -.BR close (2)), -the underlying object and its resources are -freed for reuse by the kernel; -all associated watches are automatically freed. -.P -With careful programming, -an application can use inotify to efficiently monitor and cache -the state of a set of filesystem objects. -However, robust applications should allow for the fact that bugs -in the monitoring logic or races of the kind described below -may leave the cache inconsistent with the filesystem state. -It is probably wise to do some consistency checking, -and rebuild the cache when inconsistencies are detected. -.SS Reading events from an inotify file descriptor -To determine what events have occurred, an application -.BR read (2)s -from the inotify file descriptor. -If no events have so far occurred, then, -assuming a blocking file descriptor, -.BR read (2) -will block until at least one event occurs -(unless interrupted by a signal, -in which case the call fails with the error -.BR EINTR ; -see -.BR signal (7)). -.P -Each successful -.BR read (2) -returns a buffer containing one or more of the following structures: -.P -.in +4n -.EX -struct inotify_event { - int wd; /* Watch descriptor */ -.\" FIXME . The type of the 'wd' field should probably be "int32_t". -.\" I submitted a patch to fix this. See the LKML thread -.\" "[patch] Fix type errors in inotify interfaces", 18 Nov 2008 -.\" glibc bug filed: https://www.sourceware.org/bugzilla/show_bug.cgi?id=7040 - uint32_t mask; /* Mask describing event */ - uint32_t cookie; /* Unique cookie associating related - events (for rename(2)) */ - uint32_t len; /* Size of \fIname\fP field */ - char name[]; /* Optional null\-terminated name */ -}; -.EE -.in -.P -.I wd -identifies the watch for which this event occurs. -It is one of the watch descriptors returned by a previous call to -.BR inotify_add_watch (2). -.P -.I mask -contains bits that describe the event that occurred (see below). -.P -.I cookie -is a unique integer that connects related events. -Currently, this is used only for rename events, and -allows the resulting pair of -.B IN_MOVED_FROM -and -.B IN_MOVED_TO -events to be connected by the application. -For all other event types, -.I cookie -is set to 0. -.P -The -.I name -field is present only when an event is returned -for a file inside a watched directory; -it identifies the filename within the watched directory. -This filename is null-terminated, -and may include further null bytes (\[aq]\e0\[aq]) -to align subsequent reads to a suitable address boundary. -.P -The -.I len -field counts all of the bytes in -.IR name , -including the null bytes; -the length of each -.I inotify_event -structure is thus -.IR "sizeof(struct inotify_event)+len" . -.P -The behavior when the buffer given to -.BR read (2) -is too small to return information about the next event depends -on the kernel version: before Linux 2.6.21, -.BR read (2) -returns 0; since Linux 2.6.21, -.BR read (2) -fails with the error -.BR EINVAL . -Specifying a buffer of size -.P -.in +4n -.EX -sizeof(struct inotify_event) + NAME_MAX + 1 -.EE -.in -.P -will be sufficient to read at least one event. -.SS inotify events -The -.BR inotify_add_watch (2) -.I mask -argument and the -.I mask -field of the -.I inotify_event -structure returned when -.BR read (2)ing -an inotify file descriptor are both bit masks identifying -inotify events. -The following bits can be specified in -.I mask -when calling -.BR inotify_add_watch (2) -and may be returned in the -.I mask -field returned by -.BR read (2): -.RS 4 -.TP -.BR IN_ACCESS " (+)" -File was accessed (e.g., -.BR read (2), -.BR execve (2)). -.TP -.BR IN_ATTRIB " (*)" -Metadata changed\[em]for example, permissions (e.g., -.BR chmod (2)), -timestamps (e.g., -.BR utimensat (2)), -extended attributes -.RB ( setxattr (2)), -link count (since Linux 2.6.25; e.g., -.\" FIXME . -.\" Events do not occur for link count changes on a file inside a monitored -.\" directory. This differs from other metadata changes for files inside -.\" a monitored directory. -for the target of -.BR link (2) -and for -.BR unlink (2)), -and user/group ID (e.g., -.BR chown (2)). -.TP -.BR IN_CLOSE_WRITE " (+)" -File opened for writing was closed. -.TP -.BR IN_CLOSE_NOWRITE " (*)" -File or directory not opened for writing was closed. -.TP -.BR IN_CREATE " (+)" -File/directory created in watched directory (e.g., -.BR open (2) -.BR O_CREAT , -.BR mkdir (2), -.BR link (2), -.BR symlink (2), -.BR bind (2) -on a UNIX domain socket). -.TP -.BR IN_DELETE " (+)" -File/directory deleted from watched directory. -.TP -.B IN_DELETE_SELF -Watched file/directory was itself deleted. -(This event also occurs if an object is moved to another filesystem, -since -.BR mv (1) -in effect copies the file to the other filesystem and -then deletes it from the original filesystem.) -In addition, an -.B IN_IGNORED -event will subsequently be generated for the watch descriptor. -.TP -.BR IN_MODIFY " (+)" -File was modified (e.g., -.BR write (2), -.BR truncate (2)). -.TP -.B IN_MOVE_SELF -Watched file/directory was itself moved. -.TP -.BR IN_MOVED_FROM " (+)" -Generated for the directory containing the old filename -when a file is renamed. -.TP -.BR IN_MOVED_TO " (+)" -Generated for the directory containing the new filename -when a file is renamed. -.TP -.BR IN_OPEN " (*)" -File or directory was opened. -.RE -.P -Inotify monitoring is inode-based: when monitoring a file -(but not when monitoring the directory containing a file), -an event can be generated for activity on any link to the file -(in the same or a different directory). -.P -When monitoring a directory: -.IP \[bu] 3 -the events marked above with an asterisk (*) can occur both -for the directory itself and for objects inside the directory; and -.IP \[bu] -the events marked with a plus sign (+) occur only for objects -inside the directory (not for the directory itself). -.P -.IR Note : -when monitoring a directory, -events are not generated for the files inside the directory -when the events are performed via a pathname (i.e., a link) -that lies outside the monitored directory. -.P -When events are generated for objects inside a watched directory, the -.I name -field in the returned -.I inotify_event -structure identifies the name of the file within the directory. -.P -The -.B IN_ALL_EVENTS -macro is defined as a bit mask of all of the above events. -This macro can be used as the -.I mask -argument when calling -.BR inotify_add_watch (2). -.P -Two additional convenience macros are defined: -.RS 4 -.TP -.B IN_MOVE -Equates to -.BR "IN_MOVED_FROM | IN_MOVED_TO" . -.TP -.B IN_CLOSE -Equates to -.BR "IN_CLOSE_WRITE | IN_CLOSE_NOWRITE" . -.RE -.P -The following further bits can be specified in -.I mask -when calling -.BR inotify_add_watch (2): -.RS 4 -.TP -.BR IN_DONT_FOLLOW " (since Linux 2.6.15)" -Don't dereference -.I pathname -if it is a symbolic link. -.TP -.BR IN_EXCL_UNLINK " (since Linux 2.6.36)" -.\" commit 8c1934c8d70b22ca8333b216aec6c7d09fdbd6a6 -By default, when watching events on the children of a directory, -events are generated for children even after they have been unlinked -from the directory. -This can result in large numbers of uninteresting events for -some applications (e.g., if watching -.IR /tmp , -in which many applications create temporary files whose -names are immediately unlinked). -Specifying -.B IN_EXCL_UNLINK -changes the default behavior, -so that events are not generated for children after -they have been unlinked from the watched directory. -.TP -.B IN_MASK_ADD -If a watch instance already exists for the filesystem object corresponding to -.IR pathname , -add (OR) the events in -.I mask -to the watch mask (instead of replacing the mask); -the error -.B EINVAL -results if -.B IN_MASK_CREATE -is also specified. -.TP -.B IN_ONESHOT -Monitor the filesystem object corresponding to -.I pathname -for one event, then remove from -watch list. -.TP -.BR IN_ONLYDIR " (since Linux 2.6.15)" -Watch -.I pathname -only if it is a directory; -the error -.B ENOTDIR -results if -.I pathname -is not a directory. -Using this flag provides an application with a race-free way of -ensuring that the monitored object is a directory. -.TP -.BR IN_MASK_CREATE " (since Linux 4.18)" -Watch -.I pathname -only if it does not already have a watch associated with it; -the error -.B EEXIST -results if -.I pathname -is already being watched. -.IP -Using this flag provides an application with a way of ensuring -that new watches do not modify existing ones. -This is useful because multiple paths may refer to the same inode, -and multiple calls to -.BR inotify_add_watch (2) -without this flag may clobber existing watch masks. -.RE -.P -The following bits may be set in the -.I mask -field returned by -.BR read (2): -.RS 4 -.TP -.B IN_IGNORED -Watch was removed explicitly -.RB ( inotify_rm_watch (2)) -or automatically (file was deleted, or filesystem was unmounted). -See also BUGS. -.TP -.B IN_ISDIR -Subject of this event is a directory. -.TP -.B IN_Q_OVERFLOW -Event queue overflowed -.RI ( wd -is \-1 for this event). -.TP -.B IN_UNMOUNT -Filesystem containing watched object was unmounted. -In addition, an -.B IN_IGNORED -event will subsequently be generated for the watch descriptor. -.RE -.SS Examples -Suppose an application is watching the directory -.I dir -and the file -.I dir/myfile -for all events. -The examples below show some events that will be generated -for these two objects. -.RS 4 -.TP -fd = open("dir/myfile", O_RDWR); -Generates -.B IN_OPEN -events for both -.I dir -and -.IR dir/myfile . -.TP -read(fd, buf, count); -Generates -.B IN_ACCESS -events for both -.I dir -and -.IR dir/myfile . -.TP -write(fd, buf, count); -Generates -.B IN_MODIFY -events for both -.I dir -and -.IR dir/myfile . -.TP -fchmod(fd, mode); -Generates -.B IN_ATTRIB -events for both -.I dir -and -.IR dir/myfile . -.TP -close(fd); -Generates -.B IN_CLOSE_WRITE -events for both -.I dir -and -.IR dir/myfile . -.RE -.P -Suppose an application is watching the directories -.I dir1 -and -.IR dir2 , -and the file -.IR dir1/myfile . -The following examples show some events that may be generated. -.RS 4 -.TP -link("dir1/myfile", "dir2/new"); -Generates an -.B IN_ATTRIB -event for -.I myfile -and an -.B IN_CREATE -event for -.IR dir2 . -.TP -rename("dir1/myfile", "dir2/myfile"); -Generates an -.B IN_MOVED_FROM -event for -.IR dir1 , -an -.B IN_MOVED_TO -event for -.IR dir2 , -and an -.B IN_MOVE_SELF -event for -.IR myfile . -The -.B IN_MOVED_FROM -and -.B IN_MOVED_TO -events will have the same -.I cookie -value. -.RE -.P -Suppose that -.I dir1/xx -and -.I dir2/yy -are (the only) links to the same file, and an application is watching -.IR dir1 , -.IR dir2 , -.IR dir1/xx , -and -.IR dir2/yy . -Executing the following calls in the order given below will generate -the following events: -.RS 4 -.TP -unlink("dir2/yy"); -Generates an -.B IN_ATTRIB -event for -.I xx -(because its link count changes) -and an -.B IN_DELETE -event for -.IR dir2 . -.TP -unlink("dir1/xx"); -Generates -.BR IN_ATTRIB , -.BR IN_DELETE_SELF , -and -.B IN_IGNORED -events for -.IR xx , -and an -.B IN_DELETE -event for -.IR dir1 . -.RE -.P -Suppose an application is watching the directory -.I dir -and (the empty) directory -.IR dir/subdir . -The following examples show some events that may be generated. -.RS 4 -.TP -mkdir("dir/new", mode); -Generates an -.B "IN_CREATE | IN_ISDIR" -event for -.IR dir . -.TP -rmdir("dir/subdir"); -Generates -.B IN_DELETE_SELF -and -.B IN_IGNORED -events for -.IR subdir , -and an -.B "IN_DELETE | IN_ISDIR" -event for -.IR dir . -.RE -.SS /proc interfaces -The following interfaces can be used to limit the amount of -kernel memory consumed by inotify: -.TP -.I /proc/sys/fs/inotify/max_queued_events -The value in this file is used when an application calls -.BR inotify_init (2) -to set an upper limit on the number of events that can be -queued to the corresponding inotify instance. -Events in excess of this limit are dropped, but an -.B IN_Q_OVERFLOW -event is always generated. -.TP -.I /proc/sys/fs/inotify/max_user_instances -This specifies an upper limit on the number of inotify instances -that can be created per real user ID. -.TP -.I /proc/sys/fs/inotify/max_user_watches -This specifies an upper limit on the number of watches -that can be created per real user ID. -.SH STANDARDS -Linux. -.SH HISTORY -Inotify was merged into Linux 2.6.13. -The required library interfaces were added in glibc 2.4. -.RB ( IN_DONT_FOLLOW , -.BR IN_MASK_ADD , -and -.B IN_ONLYDIR -were added in glibc 2.5.) -.SH NOTES -Inotify file descriptors can be monitored using -.BR select (2), -.BR poll (2), -and -.BR epoll (7). -When an event is available, the file descriptor indicates as readable. -.P -Since Linux 2.6.25, -signal-driven I/O notification is available for inotify file descriptors; -see the discussion of -.B F_SETFL -(for setting the -.B O_ASYNC -flag), -.BR F_SETOWN , -and -.B F_SETSIG -in -.BR fcntl (2). -The -.I siginfo_t -structure (described in -.BR sigaction (2)) -that is passed to the signal handler has the following fields set: -.I si_fd -is set to the inotify file descriptor number; -.I si_signo -is set to the signal number; -.I si_code -is set to -.BR POLL_IN ; -and -.B POLLIN -is set in -.IR si_band . -.P -If successive output inotify events produced on the -inotify file descriptor are identical (same -.IR wd , -.IR mask , -.IR cookie , -and -.IR name ), -then they are coalesced into a single event if the -older event has not yet been read (but see BUGS). -This reduces the amount of kernel memory required for the event queue, -but also means that an application can't use inotify to reliably count -file events. -.P -The events returned by reading from an inotify file descriptor -form an ordered queue. -Thus, for example, it is guaranteed that when renaming from -one directory to another, events will be produced in the -correct order on the inotify file descriptor. -.P -The set of watch descriptors that is being monitored via -an inotify file descriptor can be viewed via the entry for -the inotify file descriptor in the process's -.IR /proc/ pid /fdinfo -directory. -See -.BR proc (5) -for further details. -The -.B FIONREAD -.BR ioctl (2) -returns the number of bytes available to read from an -inotify file descriptor. -.SS Limitations and caveats -The inotify API provides no information about the user or process that -triggered the inotify event. -In particular, there is no easy -way for a process that is monitoring events via inotify -to distinguish events that it triggers -itself from those that are triggered by other processes. -.P -Inotify reports only events that a user-space program triggers through -the filesystem API. -As a result, it does not catch remote events that occur -on network filesystems. -(Applications must fall back to polling the filesystem -to catch such events.) -Furthermore, various pseudo-filesystems such as -.IR /proc , -.IR /sys , -and -.I /dev/pts -are not monitorable with inotify. -.P -The inotify API does not report file accesses and modifications that -may occur because of -.BR mmap (2), -.BR msync (2), -and -.BR munmap (2). -.P -The inotify API identifies affected files by filename. -However, by the time an application processes an inotify event, -the filename may already have been deleted or renamed. -.P -The inotify API identifies events via watch descriptors. -It is the application's responsibility to cache a mapping -(if one is needed) between watch descriptors and pathnames. -Be aware that directory renamings may affect multiple cached pathnames. -.P -Inotify monitoring of directories is not recursive: -to monitor subdirectories under a directory, -additional watches must be created. -This can take a significant amount time for large directory trees. -.P -If monitoring an entire directory subtree, -and a new subdirectory is created in that tree or an existing directory -is renamed into that tree, -be aware that by the time you create a watch for the new subdirectory, -new files (and subdirectories) may already exist inside the subdirectory. -Therefore, you may want to scan the contents of the subdirectory -immediately after adding the watch (and, if desired, -recursively add watches for any subdirectories that it contains). -.P -Note that the event queue can overflow. -In this case, events are lost. -Robust applications should handle the possibility of -lost events gracefully. -For example, it may be necessary to rebuild part or all of -the application cache. -(One simple, but possibly expensive, -approach is to close the inotify file descriptor, empty the cache, -create a new inotify file descriptor, -and then re-create watches and cache entries -for the objects to be monitored.) -.P -If a filesystem is mounted on top of a monitored directory, -no event is generated, and no events are generated -for objects immediately under the new mount point. -If the filesystem is subsequently unmounted, -events will subsequently be generated for the directory and -the objects it contains. -.\" -.SS Dealing with rename() events -As noted above, the -.B IN_MOVED_FROM -and -.B IN_MOVED_TO -event pair that is generated by -.BR rename (2) -can be matched up via their shared cookie value. -However, the task of matching has some challenges. -.P -These two events are usually consecutive in the event stream available -when reading from the inotify file descriptor. -However, this is not guaranteed. -If multiple processes are triggering events for monitored objects, -then (on rare occasions) an arbitrary number of -other events may appear between the -.B IN_MOVED_FROM -and -.B IN_MOVED_TO -events. -Furthermore, it is not guaranteed that the event pair is atomically -inserted into the queue: there may be a brief interval where the -.B IN_MOVED_FROM -has appeared, but the -.B IN_MOVED_TO -has not. -.P -Matching up the -.B IN_MOVED_FROM -and -.B IN_MOVED_TO -event pair generated by -.BR rename (2) -is thus inherently racy. -(Don't forget that if an object is renamed outside of a monitored directory, -there may not even be an -.B IN_MOVED_TO -event.) -Heuristic approaches (e.g., assume the events are always consecutive) -can be used to ensure a match in most cases, -but will inevitably miss some cases, -causing the application to perceive the -.B IN_MOVED_FROM -and -.B IN_MOVED_TO -events as being unrelated. -If watch descriptors are destroyed and re-created as a result, -then those watch descriptors will be inconsistent with -the watch descriptors in any pending events. -(Re-creating the inotify file descriptor and rebuilding the cache may -be useful to deal with this scenario.) -.P -Applications should also allow for the possibility that the -.B IN_MOVED_FROM -event was the last event that could fit in the buffer -returned by the current call to -.BR read (2), -and the accompanying -.B IN_MOVED_TO -event might be fetched only on the next -.BR read (2), -which should be done with a (small) timeout to allow for the fact that -insertion of the -.BR IN_MOVED_FROM + IN_MOVED_TO -event pair is not atomic, -and also the possibility that there may not be any -.B IN_MOVED_TO -event. -.SH BUGS -Before Linux 3.19, -.BR fallocate (2) -did not create any inotify events. -Since Linux 3.19, -.\" commit 820c12d5d6c0890bc93dd63893924a13041fdc35 -calls to -.BR fallocate (2) -generate -.B IN_MODIFY -events. -.P -.\" FIXME . kernel commit 611da04f7a31b2208e838be55a42c7a1310ae321 -.\" implies that unmount events were buggy since Linux 2.6.11 to Linux 2.6.36 -.\" -Before Linux 2.6.16, the -.B IN_ONESHOT -.I mask -flag does not work. -.P -As originally designed and implemented, the -.B IN_ONESHOT -flag did not cause an -.B IN_IGNORED -event to be generated when the watch was dropped after one event. -However, as an unintended effect of other changes, -since Linux 2.6.36, an -.B IN_IGNORED -event is generated in this case. -.P -Before Linux 2.6.25, -.\" commit 1c17d18e3775485bf1e0ce79575eb637a94494a2 -the kernel code that was intended to coalesce successive identical events -(i.e., the two most recent events could potentially be coalesced -if the older had not yet been read) -instead checked if the most recent event could be coalesced with the -.I oldest -unread event. -.P -When a watch descriptor is removed by calling -.BR inotify_rm_watch (2) -(or because a watch file is deleted or the filesystem -that contains it is unmounted), -any pending unread events for that watch descriptor remain available to read. -As watch descriptors are subsequently allocated with -.BR inotify_add_watch (2), -the kernel cycles through the range of possible watch descriptors (1 to -.BR INT_MAX ) -incrementally. -When allocating a free watch descriptor, no check is made to see whether that -watch descriptor number has any pending unread events in the inotify queue. -Thus, it can happen that a watch descriptor is reallocated even -when pending unread events exist for a previous incarnation of -that watch descriptor number, with the result that the application -might then read those events and interpret them as belonging to -the file associated with the newly recycled watch descriptor. -In practice, the likelihood of hitting this bug may be extremely low, -since it requires that an application cycle through -.B INT_MAX -watch descriptors, -release a watch descriptor while leaving unread events for that -watch descriptor in the queue, -and then recycle that watch descriptor. -For this reason, and because there have been no reports -of the bug occurring in real-world applications, -as of Linux 3.15, -.\" FIXME . https://bugzilla.kernel.org/show_bug.cgi?id=77111 -no kernel changes have yet been made to eliminate this possible bug. -.SH EXAMPLES -The following program demonstrates the usage of the inotify API. -It marks the directories passed as a command-line arguments -and waits for events of type -.BR IN_OPEN , -.BR IN_CLOSE_NOWRITE , -and -.BR IN_CLOSE_WRITE . -.P -The following output was recorded while editing the file -.I /home/user/temp/foo -and listing directory -.IR /tmp . -Before the file and the directory were opened, -.B IN_OPEN -events occurred. -After the file was closed, an -.B IN_CLOSE_WRITE -event occurred. -After the directory was closed, an -.B IN_CLOSE_NOWRITE -event occurred. -Execution of the program ended when the user pressed the ENTER key. -.SS Example output -.in +4n -.EX -$ \fB./a.out /tmp /home/user/temp\fP -Press enter key to terminate. -Listening for events. -IN_OPEN: /home/user/temp/foo [file] -IN_CLOSE_WRITE: /home/user/temp/foo [file] -IN_OPEN: /tmp/ [directory] -IN_CLOSE_NOWRITE: /tmp/ [directory] -\& -Listening for events stopped. -.EE -.in -.SS Program source -\& -.EX -#include <errno.h> -#include <poll.h> -#include <stdio.h> -#include <stdlib.h> -#include <sys/inotify.h> -#include <unistd.h> -#include <string.h> -\& -/* Read all available inotify events from the file descriptor \[aq]fd\[aq]. - wd is the table of watch descriptors for the directories in argv. - argc is the length of wd and argv. - argv is the list of watched directories. - Entry 0 of wd and argv is unused. */ -\& -static void -handle_events(int fd, int *wd, int argc, char* argv[]) -{ - /* Some systems cannot read integer variables if they are not - properly aligned. On other systems, incorrect alignment may - decrease performance. Hence, the buffer used for reading from - the inotify file descriptor should have the same alignment as - struct inotify_event. */ -\& - char buf[4096] - __attribute__ ((aligned(__alignof__(struct inotify_event)))); - const struct inotify_event *event; - ssize_t len; -\& - /* Loop while events can be read from inotify file descriptor. */ -\& - for (;;) { -\& - /* Read some events. */ -\& - len = read(fd, buf, sizeof(buf)); - if (len == \-1 && errno != EAGAIN) { - perror("read"); - exit(EXIT_FAILURE); - } -\& - /* If the nonblocking read() found no events to read, then - it returns \-1 with errno set to EAGAIN. In that case, - we exit the loop. */ -\& - if (len <= 0) - break; -\& - /* Loop over all events in the buffer. */ -\& - for (char *ptr = buf; ptr < buf + len; - ptr += sizeof(struct inotify_event) + event\->len) { -\& - event = (const struct inotify_event *) ptr; -\& - /* Print event type. */ -\& - if (event\->mask & IN_OPEN) - printf("IN_OPEN: "); - if (event\->mask & IN_CLOSE_NOWRITE) - printf("IN_CLOSE_NOWRITE: "); - if (event\->mask & IN_CLOSE_WRITE) - printf("IN_CLOSE_WRITE: "); -\& - /* Print the name of the watched directory. */ -\& - for (size_t i = 1; i < argc; ++i) { - if (wd[i] == event\->wd) { - printf("%s/", argv[i]); - break; - } - } -\& - /* Print the name of the file. */ -\& - if (event\->len) - printf("%s", event\->name); -\& - /* Print type of filesystem object. */ -\& - if (event\->mask & IN_ISDIR) - printf(" [directory]\en"); - else - printf(" [file]\en"); - } - } -} -\& -int -main(int argc, char* argv[]) -{ - char buf; - int fd, i, poll_num; - int *wd; - nfds_t nfds; - struct pollfd fds[2]; -\& - if (argc < 2) { - printf("Usage: %s PATH [PATH ...]\en", argv[0]); - exit(EXIT_FAILURE); - } -\& - printf("Press ENTER key to terminate.\en"); -\& - /* Create the file descriptor for accessing the inotify API. */ -\& - fd = inotify_init1(IN_NONBLOCK); - if (fd == \-1) { - perror("inotify_init1"); - exit(EXIT_FAILURE); - } -\& - /* Allocate memory for watch descriptors. */ -\& - wd = calloc(argc, sizeof(int)); - if (wd == NULL) { - perror("calloc"); - exit(EXIT_FAILURE); - } -\& - /* Mark directories for events - \- file was opened - \- file was closed */ -\& - for (i = 1; i < argc; i++) { - wd[i] = inotify_add_watch(fd, argv[i], - IN_OPEN | IN_CLOSE); - if (wd[i] == \-1) { - fprintf(stderr, "Cannot watch \[aq]%s\[aq]: %s\en", - argv[i], strerror(errno)); - exit(EXIT_FAILURE); - } - } -\& - /* Prepare for polling. */ -\& - nfds = 2; -\& - fds[0].fd = STDIN_FILENO; /* Console input */ - fds[0].events = POLLIN; -\& - fds[1].fd = fd; /* Inotify input */ - fds[1].events = POLLIN; -\& - /* Wait for events and/or terminal input. */ -\& - printf("Listening for events.\en"); - while (1) { - poll_num = poll(fds, nfds, \-1); - if (poll_num == \-1) { - if (errno == EINTR) - continue; - perror("poll"); - exit(EXIT_FAILURE); - } -\& - if (poll_num > 0) { -\& - if (fds[0].revents & POLLIN) { -\& - /* Console input is available. Empty stdin and quit. */ -\& - while (read(STDIN_FILENO, &buf, 1) > 0 && buf != \[aq]\en\[aq]) - continue; - break; - } -\& - if (fds[1].revents & POLLIN) { -\& - /* Inotify events are available. */ -\& - handle_events(fd, wd, argc, argv); - } - } - } -\& - printf("Listening for events stopped.\en"); -\& - /* Close inotify file descriptor. */ -\& - close(fd); -\& - free(wd); - exit(EXIT_SUCCESS); -} -.EE -.SH SEE ALSO -.BR inotifywait (1), -.BR inotifywatch (1), -.BR inotify_add_watch (2), -.BR inotify_init (2), -.BR inotify_init1 (2), -.BR inotify_rm_watch (2), -.BR read (2), -.BR stat (2), -.BR fanotify (7) -.P -.I Documentation/filesystems/inotify.txt -in the Linux kernel source tree |