inotify_init,
inotify_init1,
inotify_add_watch,
inotify_add_watch_at,
inotify_rm_watch —
monitor file system events
Standard C Library (libc, -lc)
#include
<sys/inotify.h>
int
inotify_init();
int
inotify_init1(int flags);
int
inotify_add_watch(int fd,
const char *pathname, uint32_t
mask);
int
inotify_add_watch_at(int fd,
int dfd, const char *pathname,
uint32_t mask);
int
inotify_rm_watch(int fd,
uint32_t wd);
struct inotify_event {
int wd; /* Watch descriptor */
uint32_t mask; /* Event and flags */
uint32_t cookie; /* Unique ID which links rename events */
uint32_t len; /* Name field size, including nul bytes */
char name[0]; /* Filename (nul-terminated) */
};
The inotify system calls provide an interface to monitor file
system events. They aim to be compatible with the Linux inotify interface.
The provided functionality is similar to the
EVFILT_VNODE filter of the
kevent(2) system call, but further allows monitoring of a
directory without needing to open each object in that directory. This avoids
races and reduces the number of file descriptors needed to monitor a large
file hierarchy.
inotify allows one or more file system objects,
generally files or directories, to be watched for events, such as file open
or close. Watched objects are associated with a file descriptor returned by
inotify_init()
or inotify_init1(). When an event occurs, a record
describing the event becomes available for reading from the inotify file
descriptor. Each inotify descriptor thus refers to a queue of events waiting
to be read. inotify descriptors are inherited across
fork(2) calls and may be passed to other processes via
unix(4) sockets.
The
inotify_init1()
system call accepts two flags. The IN_NONBLOCK flag
causes the inotify descriptor to be opened in non-blocking mode, such that
read(2) calls will not block if no records are available to
consume, and will instead return EWOULDBLOCK. The
IN_CLOEXEC flag causes the inotify descriptor to be
closed automatically when
execve(2) is called.
To watch a file or directory, the
inotify_add_watch()
or
inotify_add_watch_at()
system calls must be used. They take a path and a mask of events to watch
for, and return a “watch descriptor”, a non-negative integer
which uniquely identifies the watched object within the inotify
descriptor.
The
inotify_rm_watch()
system call removes a watch from an inotify descriptor.
When watching a directory, objects within the directory are
monitored for events as well as the directory itself. A record describing an
inotify event consists of a “struct inotify_event” followed by
the name of the object in the directory being watched. If the watched object
itself generates an event, no name is present. Extra nul bytes may follow
the file name in order to provide alignment for a subsequent record.
The following events are defined:
IN_ACCESS
- A file's contents were accessed, e.g., by
read(2)
copy_file_range(2),
sendfile(2), or
getdirentries(2).
IN_ATTRIB
- A file's metadata was changed, e.g., by
chmod(2) or
unlink(2).
IN_CLOSE_WRITE
- A file that was previously opened for writing was closed.
IN_CLOSE_NOWRITE
- A file that was previously opened read-only was closed.
IN_CREATE
- A file within a watched directory was created, e.g., by
open(2),
mkdir(2),
symlink(2),
mknod(2), or
bind(2).
IN_DELETE
- A file or directory within a watched directory was removed.
IN_DELETE_SELF
- The watched file or directory itself was deleted. This event is generated
only when the link count of the file drops to zero.
IN_MODIFY
- A file's contents were modified, e.g., by
write(2) or
copy_file_range(2).
IN_MOVE_SELF
- The watched file or directory itself was renamed.
IN_MOVED_FROM
- A file or directory was moved from a watched directory.
IN_MOVED_TO
- A file or directory was moved into a watched directory. A
rename(2) call thus may generate two events, one for the
old name and one for the new name. These are linked together by the
cookie field in the inotify record, which can be
compared to link the two records to the same event.
IN_OPEN
- A file was opened.
Some additional flags may be set in inotify event records:
IN_IGNORED
- When a watch is removed from a file, for example because it was created
with the
IN_ONESHOT flag, the file was deleted, or
the watch was explicitly removed with
inotify_rm_watch(2), an event with this mask is generated
to indicate that the watch will not generate any more events. Once this
event is generated, the watch is automatically removed, and in particular
should not be removed manually with
inotify_rm_watch(2).
IN_ISDIR
- When the subject of an event is a directory, this flag is set in the
mask
IN_Q_OVERFLOW
- One or more events were dropped, for example because of a kernel memory
allocation failure or because the event queue size hit a limit.
IN_UNMOUNT
- The filesystem containing the watched object was unmounted.
A number of flags may also be specified
in the mask given to
inotify_add_watch()
and
inotify_add_watch_at():
IN_DONT_FOLLOW
- If pathname is a symbolic link, do not follow
it.
IN_EXCL_UNLINK
- This currently has no effect, see the BUGS
section.
IN_MASK_ADD When adding a watch to an
object, and that object is already watched by the same inotify descriptor,
by default the mask of the existing watch is overwritten. When
IN_MASK_ADD is specified, the mask of the existing
watch is instead logically ORed with the new mask.
IN_MASK_CREATE When
inotify_add(watch)
is used to add a watch to an object,
IN_MASK_CREATE is specified, and that object is
already watched by the same inotify descriptor, return an error instead of
updating the existing watch. IN_ONESHOT Monitor
the object for a single event, after which the watch is automatically
removed. As part of removal, a IN_IGNORED event is
generated. IN_ONLYDIR When creating a watch, fail
with ENOTDIR if the path does not refer to a
directory.
The following variables are available as both
sysctl(8) variables and
loader(8) tunables:
- vfs.inotify.max_events
- The maximum number of inotify records that can be queued for a single
inotify descriptor. Records in excess of this limit are discarded, and a
single event with mask equal to
IN_Q_OVERFLOW will
be present in the queue.
- vfs.inotify.max_user_instances
- The maximum number of inotify descriptors that can be created by a single
user.
- vfs.inotify.max_user_watches
- The maximum number of inotify watches per user.
See the example program in
/usr/share/examples/inotify/inotify.c.
The inotify_init() and
inotify_init1() functions will fail if:
- [
ENFILE]
- The system limit on the total number of open files has been reached.
- [
EMFILE]
- A per-process limit on the number of open files has been reached.
- [
EMFILE]
- The system limit on the number of inotify descriptors has been
reached.
- [
EINVAL]
- An unrecognized flag was passed to
inotify_init1().
The inotify_add_watch() and
inotify_add_watch_at() system calls will fail
if:
- [
EBADF]
- The fd parameter is not a valid file
descriptor.
- [
EINVAL]
- The fd parameter is not an inotify descriptor.
- [
EINVAL]
- The mask parameter does not specify an event, or the
IN_MASK_CREATE and
IN_MASK_ADD flags are both set, or an unrecognized
flag was passed.
- [
ENOTDIR]
- The pathname parameter refers to a file that is not
a directory, and the
IN_ONLYDIR flag was
specified.
- [
ENOSPC]
- The per-user limit on the total number of inotify watches has been
reached.
- [
ECAPMODE]
- The process is in capability mode and
inotify_add_watch() was called, or
inotify_add_watch_at() was called with
AT_FDCWD as the directory file descriptor
dfd.
- [
ENOTCAPABLE]
- The process is in capability mode and pathname
contains a “..” component leading to a directory outside the
directory hierarchy specified by dfd.
The inotify_rm_watch() system call will
fail if:
- [
EBADF]
- The fd parameter is not a valid file
descriptor.
- [
EINVAL]
- The fd parameter is not an inotify descriptor.
- [
EINVAL]
- The wd parameter is not a valid watch
descriptor.
The inotify_init interface originates from
Linux and is non-standard. This implementation aims to be compatible with
that of Linux and is based on the documentation available at
https://man7.org/linux/man-pages/man7/inotify.7.html.
The inotify system calls first appeared in
FreeBSD 15.0.
If a file in a watched directory has multiple hard links, an
access via any hard link for that file will generate an event, even if the
accessed link belongs to an unwatched directory. This is not the case for
the Linux implementation, where only accesses via the hard link in the
watched directory will generate an event.
If a watched directory contains multiple hard links of a file, an
event on one of the hard links will generate an inotify record for each link
in the directory.
When a file is unlinked, no more events will be generated for that
file, even if it continues to be accessed. By default, the Linux
implementation will continue to generate events in this case. Thus, the
FreeBSD implementation behaves as though
IN_EXCL_UNLINK is always set.