summaryrefslogtreecommitdiffstats
path: root/man7/inotify.7
diff options
context:
space:
mode:
Diffstat (limited to 'man7/inotify.7')
-rw-r--r--man7/inotify.71100
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