xref: /freebsd/lib/libsys/inotify.2 (revision ae07a5805b1906f29e786f415d67bef334557bd3)
1.\"
2.\" SPDX-License-Identifier: BSD-2-Clause
3.\"
4.\" Copyright (c) 2025 Klara, Inc.
5.\"
6.Dd May 19, 2025
7.Dt INOTIFY 2
8.Os
9.Sh NAME
10.Nm inotify_init ,
11.Nm inotify_init1 ,
12.Nm inotify_add_watch ,
13.Nm inotify_add_watch_at ,
14.Nm inotify_rm_watch
15.Nd monitor file system events
16.Sh LIBRARY
17.Lb libc
18.Sh SYNOPSIS
19.In sys/inotify.h
20.Ft int
21.Fo inotify_init
22.Fc
23.Ft int
24.Fo inotify_init1
25.Fa "int flags"
26.Fc
27.Ft int
28.Fo inotify_add_watch
29.Fa "int fd"
30.Fa "const char *pathname"
31.Fa "uint32_t mask"
32.Fc
33.Ft int
34.Fo inotify_add_watch_at
35.Fa "int fd"
36.Fa "int dfd"
37.Fa "const char *pathname"
38.Fa "uint32_t mask"
39.Fc
40.Ft int
41.Fo inotify_rm_watch
42.Fa "int fd"
43.Fa "uint32_t wd"
44.Fc
45.Bd -literal
46struct inotify_event {
47	int wd;			/* Watch descriptor */
48	uint32_t mask;		/* Event and flags */
49	uint32_t cookie;	/* Unique ID which links rename events */
50	uint32_t len;		/* Name field size, including nul bytes */
51	char name[0];		/* Filename (nul-terminated) */
52};
53.Ed
54.Sh DESCRIPTION
55The inotify system calls provide an interface to monitor file system events.
56They aim to be compatible with the Linux inotify interface.
57The provided functionality is similar to the
58.Dv EVFILT_VNODE
59filter of the
60.Xr kevent 2
61system call, but further allows monitoring of a directory without needing to
62open each object in that directory.
63This avoids races and reduces the number of file descriptors needed to monitor
64a large file hierarchy.
65.Pp
66inotify allows one or more file system objects, generally files or directories,
67to be watched for events, such as file open or close.
68Watched objects are associated with a file descriptor returned
69by
70.Fn inotify_init
71or
72.Fn inotify_init1 .
73When an event occurs, a record describing the event becomes available for
74reading from the inotify file descriptor.
75Each inotify descriptor thus refers to a queue of events waiting to be read.
76inotify descriptors are inherited across
77.Xr fork 2
78calls and may be passed to other processes via
79.Xr unix 4
80sockets.
81.Pp
82The
83.Fn inotify_init1
84system call accepts two flags.
85The
86.Dv IN_NONBLOCK
87flag causes the inotify descriptor to be opened in non-blocking mode, such that
88.Xr read 2
89calls will not block if no records are available to consume, and will instead
90return
91.Er EWOULDBLOCK .
92The
93.Dv IN_CLOEXEC
94flag causes the inotify descriptor to be closed automatically when
95.Xr execve 2
96is called.
97.Pp
98To watch a file or directory, the
99.Fn inotify_add_watch
100or
101.Fn inotify_add_watch_at
102system calls must be used.
103They take a path and a mask of events to watch for, and return a
104.Dq watch descriptor ,
105a non-negative integer which uniquely identifies the watched object within the
106inotify descriptor.
107.Pp
108The
109.Fn inotify_rm_watch
110system call removes a watch from an inotify descriptor.
111.Pp
112When watching a directory, objects within the directory are monitored for events
113as well as the directory itself.
114A record describing an inotify event consists of a
115.Dq struct inotify_event
116followed by the name of the object in the directory being watched.
117If the watched object itself generates an event, no name is present.
118Extra nul bytes may follow the file name in order to provide alignment for a
119subsequent record.
120.Pp
121The following events are defined:
122.Bl -tag -width IN_CLOSE_NOWRITE
123.It Dv IN_ACCESS
124A file's contents were accessed, e.g., by
125.Xr read 2
126.Xr copy_file_range 2 ,
127.Xr sendfile 2 ,
128or
129.Xr getdirentries 2 .
130.It Dv IN_ATTRIB
131A file's metadata was changed, e.g., by
132.Xr chmod 2
133or
134.Xr unlink 2 .
135.It Dv IN_CLOSE_WRITE
136A file that was previously opened for writing was closed.
137.It Dv IN_CLOSE_NOWRITE
138A file that was previously opened read-only was closed.
139.It Dv IN_CREATE
140A file within a watched directory was created, e.g., by
141.Xr open 2 ,
142.Xr mkdir 2 ,
143.Xr symlink 2 ,
144.Xr mknod 2 ,
145or
146.Xr bind 2 .
147.It Dv IN_DELETE
148A file or directory within a watched directory was removed.
149.It Dv IN_DELETE_SELF
150The watched file or directory itself was deleted.
151This event is generated only when the link count of the file drops
152to zero.
153.It Dv IN_MODIFY
154A file's contents were modified, e.g., by
155.Xr write 2
156or
157.Xr copy_file_range 2 .
158.It Dv IN_MOVE_SELF
159The watched file or directory itself was renamed.
160.It Dv IN_MOVED_FROM
161A file or directory was moved from a watched directory.
162.It Dv IN_MOVED_TO
163A file or directory was moved into a watched directory.
164A
165.Xr rename 2
166call thus may generate two events, one for the old name and one for the new
167name.
168These are linked together by the
169.Ar cookie
170field in the inotify record, which can be compared to link the two records
171to the same event.
172.It Dv IN_OPEN
173A file was opened.
174.El
175.Pp
176Some additional flags may be set in inotify event records:
177.Bl -tag -width IN_Q_OVERFLOW
178.It Dv IN_IGNORED
179When a watch is removed from a file, for example because it was created with the
180.Dv IN_ONESHOT
181flag, the file was deleted, or the watch was explicitly removed with
182.Xr inotify_rm_watch 2 ,
183an event with this mask is generated to indicate that the watch will not
184generate any more events.
185Once this event is generated, the watch is automatically removed, and in
186particular should not be removed manually with
187.Xr inotify_rm_watch 2 .
188.It Dv IN_ISDIR
189When the subject of an event is a directory, this flag is set in the
190.Ar mask
191.It Dv IN_Q_OVERFLOW
192One or more events were dropped, for example because of a kernel memory allocation
193failure or because the event queue size hit a limit.
194.It Dv IN_UNMOUNT
195The filesystem containing the watched object was unmounted.
196.El
197.Pp
198A number of flags may also be specified in the
199.Ar mask
200given to
201.Fn inotify_add_watch
202and
203.Fn inotify_add_watch_at :
204.Bl -tag -width IN_DONT_FOLLOW
205.It Dv IN_DONT_FOLLOW
206If
207.Ar pathname
208is a symbolic link, do not follow it.
209.It Dv IN_EXCL_UNLINK
210This currently has no effect, see the
211.Sx BUGS
212section.
213.In Dv IN_MASK_ADD
214When adding a watch to an object, and that object is already watched by the
215same inotify descriptor, by default the mask of the existing watch is
216overwritten.
217When
218.Dv IN_MASK_ADD
219is specified, the mask of the existing watch is instead logically ORed with
220the new mask.
221.In Dv IN_MASK_CREATE
222When
223.Fn inotify_add watch
224is used to add a watch to an object,
225.Dv IN_MASK_CREATE
226is specified, and that object is already watched by the same inotify descriptor,
227return an error instead of updating the existing watch.
228.In Dv IN_ONESHOT
229Monitor the object for a single event, after which the watch is automatically
230removed.
231As part of removal, a
232.Dv IN_IGNORED
233event is generated.
234.In Dv IN_ONLYDIR
235When creating a watch, fail with
236.Er ENOTDIR
237if the path does not refer to a directory.
238.El
239.Sh SYSCTL VARIABLES
240The following variables are available as both
241.Xr sysctl 8
242variables and
243.Xr loader 8
244tunables:
245.Bl -tag -width 15
246.It Va vfs.inotify.max_events
247The maximum number of inotify records that can be queued for a single
248inotify descriptor.
249Records in excess of this limit are discarded, and a single event with
250mask equal to
251.Dv IN_Q_OVERFLOW
252will be present in the queue.
253.It Va vfs.inotify.max_user_instances
254The maximum number of inotify descriptors that can be created by a single
255user.
256.It Va vfs.inotify.max_user_watches
257The maximum number of inotify watches per user.
258.El
259.Sh EXAMPLES
260See the example program in
261.Pa /usr/share/examples/inotify/inotify.c .
262.Sh ERRORS
263The
264.Fn inotify_init
265and
266.Fn inotify_init1
267functions will fail if:
268.Bl -tag -width Er
269.It Bq Er ENFILE
270The system limit on the total number of open files has been reached.
271.It Bq Er EMFILE
272A per-process limit on the number of open files has been reached.
273.It Bq Er EMFILE
274The system limit on the number of inotify descriptors has been reached.
275.It Bq Er EINVAL
276An unrecognized flag was passed to
277.Fn inotify_init1 .
278.El
279.Pp
280The
281.Fn inotify_add_watch
282and
283.Fn inotify_add_watch_at
284system calls will fail if:
285.Bl -tag -width Er
286.It Bq Er EBADF
287The
288.Ar fd
289parameter is not a valid file descriptor.
290.It Bq Er EINVAL
291The
292.Ar fd
293parameter is not an inotify descriptor.
294.It Bq Er EINVAL
295The
296.Ar mask
297parameter does not specify an event, or
298the
299.Dv IN_MASK_CREATE
300and
301.Dv IN_MASK_ADD
302flags are both set, or an unrecognized flag was passed.
303.It Bq Er ENOTDIR
304The
305.Ar pathname
306parameter refers to a file that is not a directory, and the
307.Dv IN_ONLYDIR
308flag was specified.
309.It Bq Er ENOSPC
310The per-user limit on the total number of inotify watches has been reached.
311.It Bq Er ECAPMODE
312The process is in capability mode and
313.Fn inotify_add_watch
314was called, or
315.Fn inotify_add_watch_at
316was called with
317.Dv AT_FDCWD
318as the directory file descriptor
319.Ar dfd .
320.It Bq Er ENOTCAPABLE
321The process is in capability mode and
322.Ar pathname
323contains a
324.Dq ..
325component leading to a directory outside the directory hierarchy specified
326by
327.Ar dfd .
328.El
329.Pp
330The
331.Fn inotify_rm_watch
332system call will fail if:
333.Bl -tag -width Er
334.It Bq Er EBADF
335The
336.Ar fd
337parameter is not a valid file descriptor.
338.It Bq Er EINVAL
339The
340.Ar fd
341parameter is not an inotify descriptor.
342.It Bq Er EINVAL
343The
344.Ar wd
345parameter is not a valid watch descriptor.
346.El
347.Sh SEE ALSO
348.Xr kevent 2 ,
349.Xr capsicum 4
350.Sh STANDARDS
351The
352.Nm
353interface originates from Linux and is non-standard.
354This implementation aims to be compatible with that of Linux and is based
355on the documentation available at
356.Pa https://man7.org/linux/man-pages/man7/inotify.7.html .
357.Sh HISTORY
358The inotify system calls first appeared in
359.Fx 15.0 .
360.Sh BUGS
361If a file in a watched directory has multiple hard links,
362an access via any hard link for that file will generate an event, even
363if the accessed link belongs to an unwatched directory.
364This is not the case for the Linux implementation, where only accesses
365via the hard link in the watched directory will generate an event.
366.Pp
367If a watched directory contains multiple hard links of a file, an event
368on one of the hard links will generate an inotify record for each link
369in the directory.
370.Pp
371When a file is unlinked, no more events will be generated for that file,
372even if it continues to be accessed.
373By default, the Linux implementation will continue to generate events in
374this case.
375Thus, the
376.Fx
377implementation behaves as though
378.Dv IN_EXCL_UNLINK
379is always set.
380