wait.2: Add ESRCH for when pid == INT_MIN
[man-pages.git] / man7 / fanotify.7
blob9c218fd065a8ecff08b22a2a370067a44cf3dcdd
1 .\" Copyright (C) 2013, Heinrich Schuchardt <xypron.glpk@gmx.de>
2 .\" and Copyright (C) 2014, Michael Kerrisk <mtk.manpages@gmail.com>
3 .\"
4 .\" %%%LICENSE_START(VERBATIM)
5 .\" Permission is granted to make and distribute verbatim copies of this
6 .\" manual provided the copyright notice and this permission notice are
7 .\" preserved on all copies.
8 .\"
9 .\" Permission is granted to copy and distribute modified versions of
10 .\" this manual under the conditions for verbatim copying, provided that
11 .\" the entire resulting derived work is distributed under the terms of
12 .\" a permission notice identical to this one.
13 .\"
14 .\" Since the Linux kernel and libraries are constantly changing, this
15 .\" manual page may be incorrect or out-of-date.  The author(s) assume.
16 .\" no responsibility for errors or omissions, or for damages resulting.
17 .\" from the use of the information contained herein.  The author(s) may.
18 .\" not have taken the same level of care in the production of this.
19 .\" manual, which is licensed free of charge, as they might when working.
20 .\" professionally.
21 .\"
22 .\" Formatted or processed versions of this manual, if unaccompanied by
23 .\" the source, must acknowledge the copyright and authors of this work.
24 .\" %%%LICENSE_END
25 .TH FANOTIFY 7 2021-03-22 "Linux" "Linux Programmer's Manual"
26 .SH NAME
27 fanotify \- monitoring filesystem events
28 .SH DESCRIPTION
29 The fanotify API provides notification and interception of
30 filesystem events.
31 Use cases include virus scanning and hierarchical storage management.
32 In the original fanotify API, only a limited set of events was supported.
33 In particular, there was no support for create, delete, and move events.
34 The support for those events was added in Linux 5.1.
35 (See
36 .BR inotify (7)
37 for details of an API that did notify those events pre Linux 5.1.)
38 .PP
39 Additional capabilities compared to the
40 .BR inotify (7)
41 API include the ability to monitor all of the objects
42 in a mounted filesystem,
43 the ability to make access permission decisions, and the
44 possibility to read or modify files before access by other applications.
45 .PP
46 The following system calls are used with this API:
47 .BR fanotify_init (2),
48 .BR fanotify_mark (2),
49 .BR read (2),
50 .BR write (2),
51 and
52 .BR close (2).
53 .SS fanotify_init(), fanotify_mark(), and notification groups
54 The
55 .BR fanotify_init (2)
56 system call creates and initializes an fanotify notification group
57 and returns a file descriptor referring to it.
58 .PP
59 An fanotify notification group is a kernel-internal object that holds
60 a list of files, directories, filesystems, and mount points for which
61 events shall be created.
62 .PP
63 For each entry in an fanotify notification group, two bit masks exist: the
64 .I mark
65 mask and the
66 .I ignore
67 mask.
68 The mark mask defines file activities for which an event shall be created.
69 The ignore mask defines activities for which no event shall be generated.
70 Having these two types of masks permits a filesystem, mount point, or
71 directory to be marked for receiving events, while at the same time
72 ignoring events for specific objects under a mount point or directory.
73 .PP
74 The
75 .BR fanotify_mark (2)
76 system call adds a file, directory, filesystem, or mount point to a
77 notification group and specifies which events
78 shall be reported (or ignored), or removes or modifies such an entry.
79 .PP
80 A possible usage of the ignore mask is for a file cache.
81 Events of interest for a file cache are modification of a file and closing
82 of the same.
83 Hence, the cached directory or mount point is to be marked to receive these
84 events.
85 After receiving the first event informing that a file has been modified,
86 the corresponding cache entry will be invalidated.
87 No further modification events for this file are of interest until the file
88 is closed.
89 Hence, the modify event can be added to the ignore mask.
90 Upon receiving the close event, the modify event can be removed from the
91 ignore mask and the file cache entry can be updated.
92 .PP
93 The entries in the fanotify notification groups refer to files and
94 directories via their inode number and to mounts via their mount ID.
95 If files or directories are renamed or moved within the same mount,
96 the respective entries survive.
97 If files or directories are deleted or moved to another mount or if
98 filesystems or mounts are unmounted, the corresponding entries are deleted.
99 .SS The event queue
100 As events occur on the filesystem objects monitored by a notification group,
101 the fanotify system generates events that are collected in a queue.
102 These events can then be read (using
103 .BR read (2)
104 or similar)
105 from the fanotify file descriptor
106 returned by
107 .BR fanotify_init (2).
109 Two types of events are generated:
110 .I notification
111 events and
112 .I permission
113 events.
114 Notification events are merely informative and require no action to be taken
115 by the receiving application with one exception: if a valid file descriptor
116 is provided within a generic event, the file descriptor must be closed.
117 Permission events are requests to the receiving application to decide
118 whether permission for a file access shall be granted.
119 For these events, the recipient must write a response which decides whether
120 access is granted or not.
122 An event is removed from the event queue of the fanotify group
123 when it has been read.
124 Permission events that have been read are kept in an internal list of the
125 fanotify group until either a permission decision has been taken by
126 writing to the fanotify file descriptor or the fanotify file descriptor
127 is closed.
128 .SS Reading fanotify events
129 Calling
130 .BR read (2)
131 for the file descriptor returned by
132 .BR fanotify_init (2)
133 blocks (if the flag
134 .B FAN_NONBLOCK
135 is not specified in the call to
136 .BR fanotify_init (2))
137 until either a file event occurs or the call is interrupted by a signal
138 (see
139 .BR signal (7)).
141 The use of one of the flags
142 .BR FAN_REPORT_FID ,
143 .BR FAN_REPORT_DIR_FID
145 .BR fanotify_init (2)
146 influences what data structures are returned to the event listener for each
147 event.
148 Events reported to a group initialized with one of these flags will
149 use file handles to identify filesystem objects instead of file descriptors.
151 After a successful
152 .BR read (2),
153 the read buffer contains one or more of the following structures:
155 .in +4n
157 struct fanotify_event_metadata {
158     __u32 event_len;
159     __u8 vers;
160     __u8 reserved;
161     __u16 metadata_len;
162     __aligned_u64 mask;
163     __s32 fd;
164     __s32 pid;
169 In case of an fanotify group that identifies filesystem objects by file
170 handles, you should also expect to receive one or more additional information
171 records of the structure detailed below following the generic
172 .I fanotify_event_metadata
173 structure within the read buffer:
175 .in +4n
177 struct fanotify_event_info_header {
178     __u8 info_type;
179     __u8 pad;
180     __u16 len;
183 struct fanotify_event_info_fid {
184     struct fanotify_event_info_header hdr;
185     __kernel_fsid_t fsid;
186     unsigned char file_handle[0];
191 For performance reasons, it is recommended to use a large
192 buffer size (for example, 4096 bytes),
193 so that multiple events can be retrieved by a single
194 .BR read (2).
196 The return value of
197 .BR read (2)
198 is the number of bytes placed in the buffer,
199 or \-1 in case of an error (but see BUGS).
201 The fields of the
202 .I fanotify_event_metadata
203 structure are as follows:
205 .I event_len
206 This is the length of the data for the current event and the offset
207 to the next event in the buffer.
208 Unless the group identifies filesystem objects by file handles, the value of
209 .I event_len
210 is always
211 .BR FAN_EVENT_METADATA_LEN .
212 For a group that identifies filesystem objects by file handles,
213 .I event_len
214 also includes the variable length file identifier records.
216 .I vers
217 This field holds a version number for the structure.
218 It must be compared to
219 .B FANOTIFY_METADATA_VERSION
220 to verify that the structures returned at run time match
221 the structures defined at compile time.
222 In case of a mismatch, the application should abandon trying to use the
223 fanotify file descriptor.
225 .I reserved
226 This field is not used.
228 .I metadata_len
229 This is the length of the structure.
230 The field was introduced to facilitate the implementation of
231 optional headers per event type.
232 No such optional headers exist in the current implementation.
234 .I mask
235 This is a bit mask describing the event (see below).
237 .I fd
238 This is an open file descriptor for the object being accessed, or
239 .B FAN_NOFD
240 if a queue overflow occurred.
241 With an fanotify group that identifies filesystem objects by file handles,
242 applications should expect this value to be set to
243 .B FAN_NOFD
244 for each event that is received.
245 The file descriptor can be used to access the contents
246 of the monitored file or directory.
247 The reading application is responsible for closing this file descriptor.
249 When calling
250 .BR fanotify_init (2),
251 the caller may specify (via the
252 .I event_f_flags
253 argument) various file status flags that are to be set
254 on the open file description that corresponds to this file descriptor.
255 In addition, the (kernel-internal)
256 .B FMODE_NONOTIFY
257 file status flag is set on the open file description.
258 This flag suppresses fanotify event generation.
259 Hence, when the receiver of the fanotify event accesses the notified file or
260 directory using this file descriptor, no additional events will be created.
262 .I pid
263 If flag
264 .B FAN_REPORT_TID
265 was set in
266 .BR fanotify_init (2),
267 this is the TID of the thread that caused the event.
268 Otherwise, this the PID of the process that caused the event.
270 A program listening to fanotify events can compare this PID
271 to the PID returned by
272 .BR getpid (2),
273 to determine whether the event is caused by the listener itself,
274 or is due to a file access by another process.
276 The bit mask in
277 .I mask
278 indicates which events have occurred for a single filesystem object.
279 Multiple bits may be set in this mask,
280 if more than one event occurred for the monitored filesystem object.
281 In particular,
282 consecutive events for the same filesystem object and originating from the
283 same process may be merged into a single event, with the exception that two
284 permission events are never merged into one queue entry.
286 The bits that may appear in
287 .I mask
288 are as follows:
290 .B FAN_ACCESS
291 A file or a directory (but see BUGS) was accessed (read).
293 .B FAN_OPEN
294 A file or a directory was opened.
296 .B FAN_OPEN_EXEC
297 A file was opened with the intent to be executed.
298 See NOTES in
299 .BR fanotify_mark (2)
300 for additional details.
302 .B FAN_ATTRIB
303 A file or directory metadata was changed.
305 .B FAN_CREATE
306 A child file or directory was created in a watched parent.
308 .B FAN_DELETE
309 A child file or directory was deleted in a watched parent.
311 .B FAN_DELETE_SELF
312 A watched file or directory was deleted.
314 .B FAN_MOVED_FROM
315 A file or directory has been moved from a watched parent directory.
317 .B FAN_MOVED_TO
318 A file or directory has been moved to a watched parent directory.
320 .B FAN_MOVE_SELF
321 A watched file or directory was moved.
323 .B FAN_MODIFY
324 A file was modified.
326 .B FAN_CLOSE_WRITE
327 A file that was opened for writing
328 .RB ( O_WRONLY
330 .BR O_RDWR )
331 was closed.
333 .B FAN_CLOSE_NOWRITE
334 A file or directory that was opened read-only
335 .RB ( O_RDONLY )
336 was closed.
338 .B FAN_Q_OVERFLOW
339 The event queue exceeded the limit of 16384 entries.
340 This limit can be overridden by specifying the
341 .BR FAN_UNLIMITED_QUEUE
342 flag when calling
343 .BR fanotify_init (2).
345 .B FAN_ACCESS_PERM
346 An application wants to read a file or directory, for example using
347 .BR read (2)
349 .BR readdir (2).
350 The reader must write a response (as described below)
351 that determines whether the permission to
352 access the filesystem object shall be granted.
354 .B FAN_OPEN_PERM
355 An application wants to open a file or directory.
356 The reader must write a response that determines whether the permission to
357 open the filesystem object shall be granted.
359 .B FAN_OPEN_EXEC_PERM
360 An application wants to open a file for execution.
361 The reader must write a response that determines whether the permission to
362 open the filesystem object for execution shall be granted.
363 See NOTES in
364 .BR fanotify_mark (2)
365 for additional details.
367 To check for any close event, the following bit mask may be used:
369 .B FAN_CLOSE
370 A file was closed.
371 This is a synonym for:
373     FAN_CLOSE_WRITE | FAN_CLOSE_NOWRITE
375 To check for any move event, the following bit mask may be used:
377 .B FAN_MOVE
378 A file or directory was moved.
379 This is a synonym for:
381     FAN_MOVED_FROM | FAN_MOVED_TO
383 The following bits may appear in
384 .I mask
385 only in conjunction with other event type bits:
387 .B FAN_ONDIR
388 The events described in the
389 .I mask
390 have occurred on a directory object.
391 Reporting events on directories requires setting this flag in the mark mask.
393 .BR fanotify_mark (2)
394 for additional details.
396 .BR FAN_ONDIR
397 flag is reported in an event mask only if the fanotify group identifies
398 filesystem objects by file handles.
400 The fields of the
401 .I fanotify_event_info_fid
402 structure are as follows:
404 .I hdr
405 This is a structure of type
406 .IR fanotify_event_info_header .
407 It is a generic header that contains information used to describe an
408 additional information record attached to the event.
409 For example, when an fanotify file descriptor is created using
410 .BR FAN_REPORT_FID ,
411 a single information record is expected to be attached to the event with
412 .I info_type
413 field value of
414 .BR FAN_EVENT_INFO_TYPE_FID .
415 When an fanotify file descriptor is created using the combination of
416 .BR FAN_REPORT_FID
418 .BR FAN_REPORT_DIR_FID ,
419 there may be two information records attached to the event:
420 one with
421 .I info_type
422 field value of
423 .BR FAN_EVENT_INFO_TYPE_DFID ,
424 identifying a parent directory object, and one with
425 .I info_type
426 field value of
427 .BR FAN_EVENT_INFO_TYPE_FID ,
428 identifying a non-directory object.
430 .I fanotify_event_info_header
431 contains a
432 .I len
433 field.
434 The value of
435 .I len
436 is the size of the additional information record including the
437 .IR fanotify_event_info_header
438 itself.
439 The total size of all additional information records is not expected
440 to be bigger than
442 .IR event_len
444 .IR metadata_len
447 .I fsid
448 This is a unique identifier of the filesystem containing the object
449 associated with the event.
450 It is a structure of type
451 .I __kernel_fsid_t
452 and contains the same value as
453 .I f_fsid
454 when calling
455 .BR statfs (2).
457 .I file_handle
458 This is a variable length structure of type struct file_handle.
459 It is an opaque handle that corresponds to a specified object on a
460 filesystem as returned by
461 .BR name_to_handle_at (2).
462 It can be used to uniquely identify a file on a filesystem and can be
463 passed as an argument to
464 .BR open_by_handle_at (2).
465 Note that for the directory entry modification events
466 .BR FAN_CREATE ,
467 .BR FAN_DELETE ,
469 .BR FAN_MOVE ,
471 .IR file_handle
472 identifies the modified directory and not the created/deleted/moved child
473 object.
474 If the value of
475 .I info_type
476 field is
477 .BR FAN_EVENT_INFO_TYPE_DFID_NAME ,
478 the file handle is followed by a null terminated string that identifies the
479 created/deleted/moved directory entry name.
480 For other events such as
481 .BR FAN_OPEN ,
482 .BR FAN_ATTRIB ,
483 .BR FAN_DELETE_SELF ,
485 .BR FAN_MOVE_SELF ,
486 if the value of
487 .I info_type
488 field is
489 .BR FAN_EVENT_INFO_TYPE_FID ,
491 .IR file_handle
492 identifies the object correlated to the event.
493 If the value of
494 .I info_type
495 field is
496 .BR FAN_EVENT_INFO_TYPE_DFID ,
498 .IR file_handle
499 identifies the directory object correlated to the event or the parent directory
500 of a non-directory object correlated to the event.
501 If the value of
502 .I info_type
503 field is
504 .BR FAN_EVENT_INFO_TYPE_DFID_NAME ,
506 .IR file_handle
507 identifies the same directory object that would be reported with
508 .BR FAN_EVENT_INFO_TYPE_DFID
509 and the file handle is followed by a null terminated string that identifies the
510 name of a directory entry in that directory, or '.' to identify the directory
511 object itself.
513 The following macros are provided to iterate over a buffer containing
514 fanotify event metadata returned by a
515 .BR read (2)
516 from an fanotify file descriptor:
518 .B FAN_EVENT_OK(meta, len)
519 This macro checks the remaining length
520 .I len
521 of the buffer
522 .I meta
523 against the length of the metadata structure and the
524 .I event_len
525 field of the first metadata structure in the buffer.
527 .B FAN_EVENT_NEXT(meta, len)
528 This macro uses the length indicated in the
529 .I event_len
530 field of the metadata structure pointed to by
531 .IR meta
532 to calculate the address of the next metadata structure that follows
533 .IR meta .
534 .I len
535 is the number of bytes of metadata that currently remain in the buffer.
536 The macro returns a pointer to the next metadata structure that follows
537 .IR meta ,
538 and reduces
539 .I len
540 by the number of bytes in the metadata structure that
541 has been skipped over (i.e., it subtracts
542 .IR meta\->event_len
543 from
544 .IR len ).
546 In addition, there is:
548 .B FAN_EVENT_METADATA_LEN
549 This macro returns the size (in bytes) of the structure
550 .IR fanotify_event_metadata .
551 This is the minimum size (and currently the only size) of any event metadata.
553 .SS Monitoring an fanotify file descriptor for events
554 When an fanotify event occurs, the fanotify file descriptor indicates as
555 readable when passed to
556 .BR epoll (7),
557 .BR poll (2),
559 .BR select (2).
560 .SS Dealing with permission events
561 For permission events, the application must
562 .BR write (2)
563 a structure of the following form to the
564 fanotify file descriptor:
566 .in +4n
568 struct fanotify_response {
569     __s32 fd;
570     __u32 response;
575 The fields of this structure are as follows:
577 .I fd
578 This is the file descriptor from the structure
579 .IR fanotify_event_metadata .
581 .I response
582 This field indicates whether or not the permission is to be granted.
583 Its value must be either
584 .B FAN_ALLOW
585 to allow the file operation or
586 .B FAN_DENY
587 to deny the file operation.
589 If access is denied, the requesting application call will receive an
590 .BR EPERM
591 error.
592 Additionally, if the notification group has been created with the
593 .B FAN_ENABLE_AUDIT
594 flag, then the
595 .B FAN_AUDIT
596 flag can be set in the
597 .I response
598 field.
599 In that case, the audit subsystem will log information about the access
600 decision to the audit logs.
602 .SS Closing the fanotify file descriptor
603 When all file descriptors referring to the fanotify notification group are
604 closed, the fanotify group is released and its resources
605 are freed for reuse by the kernel.
606 Upon
607 .BR close (2),
608 outstanding permission events will be set to allowed.
609 .SS /proc/[pid]/fdinfo
610 The file
611 .I /proc/[pid]/fdinfo/[fd]
612 contains information about fanotify marks for file descriptor
613 .I fd
614 of process
615 .IR pid .
617 .BR proc (5)
618 for details.
619 .SH ERRORS
620 In addition to the usual errors for
621 .BR read (2),
622 the following errors can occur when reading from the
623 fanotify file descriptor:
625 .B EINVAL
626 The buffer is too small to hold the event.
628 .B EMFILE
629 The per-process limit on the number of open files has been reached.
630 See the description of
631 .B RLIMIT_NOFILE
633 .BR getrlimit (2).
635 .B ENFILE
636 The system-wide limit on the total number of open files has been reached.
638 .I /proc/sys/fs/file\-max
640 .BR proc (5).
642 .B ETXTBSY
643 This error is returned by
644 .BR read (2)
646 .B O_RDWR
648 .B O_WRONLY
649 was specified in the
650 .I event_f_flags
651 argument when calling
652 .BR fanotify_init (2)
653 and an event occurred for a monitored file that is currently being executed.
655 In addition to the usual errors for
656 .BR write (2),
657 the following errors can occur when writing to the fanotify file descriptor:
659 .B EINVAL
660 Fanotify access permissions are not enabled in the kernel configuration
661 or the value of
662 .I response
663 in the response structure is not valid.
665 .B ENOENT
666 The file descriptor
667 .I fd
668 in the response structure is not valid.
669 This may occur when a response for the permission event has already been
670 written.
671 .SH VERSIONS
672 The fanotify API was introduced in version 2.6.36 of the Linux kernel and
673 enabled in version 2.6.37.
674 Fdinfo support was added in version 3.8.
675 .SH CONFORMING TO
676 The fanotify API is Linux-specific.
677 .SH NOTES
678 The fanotify API is available only if the kernel was built with the
679 .B CONFIG_FANOTIFY
680 configuration option enabled.
681 In addition, fanotify permission handling is available only if the
682 .B CONFIG_FANOTIFY_ACCESS_PERMISSIONS
683 configuration option is enabled.
684 .SS Limitations and caveats
685 Fanotify reports only events that a user-space program triggers through the
686 filesystem API.
687 As a result,
688 it does not catch remote events that occur on network filesystems.
690 The fanotify API does not report file accesses and modifications that
691 may occur because of
692 .BR mmap (2),
693 .BR msync (2),
695 .BR munmap (2).
697 Events for directories are created only if the directory itself is opened,
698 read, and closed.
699 Adding, removing, or changing children of a marked directory does not create
700 events for the monitored directory itself.
702 Fanotify monitoring of directories is not recursive:
703 to monitor subdirectories under a directory,
704 additional marks must be created.
706 .B FAN_CREATE
707 event can be used for detecting when a subdirectory has been created under
708 a marked directory.
709 An additional mark must then be set on the newly created subdirectory.
710 This approach is racy, because it can lose events that occurred inside the
711 newly created subdirectory, before a mark is added on that subdirectory.
712 Monitoring mounts offers the capability to monitor a whole directory tree
713 in a race-free manner.
714 Monitoring filesystems offers the capability to monitor changes made from
715 any mount of a filesystem instance in a race-free manner.
717 The event queue can overflow.
718 In this case, events are lost.
719 .SH BUGS
720 Before Linux 3.19,
721 .BR fallocate (2)
722 did not generate fanotify events.
723 Since Linux 3.19,
724 .\" commit 820c12d5d6c0890bc93dd63893924a13041fdc35
725 calls to
726 .BR fallocate (2)
727 generate
728 .B FAN_MODIFY
729 events.
731 As of Linux 3.17,
732 the following bugs exist:
733 .IP * 3
734 On Linux, a filesystem object may be accessible through multiple paths,
735 for example, a part of a filesystem may be remounted using the
736 .IR \-\-bind
737 option of
738 .BR mount (8).
739 A listener that marked a mount will be notified only of events that were
740 triggered for a filesystem object using the same mount.
741 Any other event will pass unnoticed.
742 .IP *
743 .\" FIXME . A patch was proposed.
744 When an event is generated,
745 no check is made to see whether the user ID of the
746 receiving process has authorization to read or write the file
747 before passing a file descriptor for that file.
748 This poses a security risk, when the
749 .B CAP_SYS_ADMIN
750 capability is set for programs executed by unprivileged users.
751 .IP *
752 If a call to
753 .BR read (2)
754 processes multiple events from the fanotify queue and an error occurs,
755 the return value will be the total length of the events successfully
756 copied to the user-space buffer before the error occurred.
757 The return value will not be \-1, and
758 .I errno
759 will not be set.
760 Thus, the reading application has no way to detect the error.
761 .SH EXAMPLES
762 The two example programs below demonstrate the usage of the fanotify API.
763 .SS Example program: fanotify_example.c
764 The first program is an example of fanotify being
765 used with its event object information passed in the form of a file
766 descriptor.
767 The program marks the mount point passed as a command-line argument and
768 waits for events of type
769 .B FAN_OPEN_PERM
771 .BR FAN_CLOSE_WRITE .
772 When a permission event occurs, a
773 .B FAN_ALLOW
774 response is given.
776 The following shell session shows an example of
777 running this program.
778 This session involved editing the file
779 .IR /home/user/temp/notes .
780 Before the file was opened, a
781 .B FAN_OPEN_PERM
782 event occurred.
783 After the file was closed, a
784 .B FAN_CLOSE_WRITE
785 event occurred.
786 Execution of the program ends when the user presses the ENTER key.
788 .in +4n
790 # \fB./fanotify_example /home\fP
791 Press enter key to terminate.
792 Listening for events.
793 FAN_OPEN_PERM: File /home/user/temp/notes
794 FAN_CLOSE_WRITE: File /home/user/temp/notes
796 Listening for events stopped.
799 .SS Program source: fanotify_example.c
802 #define _GNU_SOURCE     /* Needed to get O_LARGEFILE definition */
803 #include <errno.h>
804 #include <fcntl.h>
805 #include <limits.h>
806 #include <poll.h>
807 #include <stdio.h>
808 #include <stdlib.h>
809 #include <sys/fanotify.h>
810 #include <unistd.h>
812 /* Read all available fanotify events from the file descriptor \(aqfd\(aq. */
814 static void
815 handle_events(int fd)
817     const struct fanotify_event_metadata *metadata;
818     struct fanotify_event_metadata buf[200];
819     ssize_t len;
820     char path[PATH_MAX];
821     ssize_t path_len;
822     char procfd_path[PATH_MAX];
823     struct fanotify_response response;
825     /* Loop while events can be read from fanotify file descriptor. */
827     for (;;) {
829         /* Read some events. */
831         len = read(fd, buf, sizeof(buf));
832         if (len == \-1 && errno != EAGAIN) {
833             perror("read");
834             exit(EXIT_FAILURE);
835         }
837         /* Check if end of available data reached. */
839         if (len <= 0)
840             break;
842         /* Point to the first event in the buffer. */
844         metadata = buf;
846         /* Loop over all events in the buffer. */
848         while (FAN_EVENT_OK(metadata, len)) {
850             /* Check that run\-time and compile\-time structures match. */
852             if (metadata\->vers != FANOTIFY_METADATA_VERSION) {
853                 fprintf(stderr,
854                         "Mismatch of fanotify metadata version.\en");
855                 exit(EXIT_FAILURE);
856             }
858             /* metadata\->fd contains either FAN_NOFD, indicating a
859                queue overflow, or a file descriptor (a nonnegative
860                integer). Here, we simply ignore queue overflow. */
862             if (metadata\->fd >= 0) {
864                 /* Handle open permission event. */
866                 if (metadata\->mask & FAN_OPEN_PERM) {
867                     printf("FAN_OPEN_PERM: ");
869                     /* Allow file to be opened. */
871                     response.fd = metadata\->fd;
872                     response.response = FAN_ALLOW;
873                     write(fd, &response, sizeof(response));
874                 }
876                 /* Handle closing of writable file event. */
878                 if (metadata\->mask & FAN_CLOSE_WRITE)
879                     printf("FAN_CLOSE_WRITE: ");
881                 /* Retrieve and print pathname of the accessed file. */
883                 snprintf(procfd_path, sizeof(procfd_path),
884                          "/proc/self/fd/%d", metadata\->fd);
885                 path_len = readlink(procfd_path, path,
886                                     sizeof(path) \- 1);
887                 if (path_len == \-1) {
888                     perror("readlink");
889                     exit(EXIT_FAILURE);
890                 }
892                 path[path_len] = \(aq\e0\(aq;
893                 printf("File %s\en", path);
895                 /* Close the file descriptor of the event. */
897                 close(metadata\->fd);
898             }
900             /* Advance to next event. */
902             metadata = FAN_EVENT_NEXT(metadata, len);
903         }
904     }
908 main(int argc, char *argv[])
910     char buf;
911     int fd, poll_num;
912     nfds_t nfds;
913     struct pollfd fds[2];
915     /* Check mount point is supplied. */
917     if (argc != 2) {
918         fprintf(stderr, "Usage: %s MOUNT\en", argv[0]);
919         exit(EXIT_FAILURE);
920     }
922     printf("Press enter key to terminate.\en");
924     /* Create the file descriptor for accessing the fanotify API. */
926     fd = fanotify_init(FAN_CLOEXEC | FAN_CLASS_CONTENT | FAN_NONBLOCK,
927                        O_RDONLY | O_LARGEFILE);
928     if (fd == \-1) {
929         perror("fanotify_init");
930         exit(EXIT_FAILURE);
931     }
933     /* Mark the mount for:
934        \- permission events before opening files
935        \- notification events after closing a write\-enabled
936          file descriptor. */
938     if (fanotify_mark(fd, FAN_MARK_ADD | FAN_MARK_MOUNT,
939                       FAN_OPEN_PERM | FAN_CLOSE_WRITE, AT_FDCWD,
940                       argv[1]) == \-1) {
941         perror("fanotify_mark");
942         exit(EXIT_FAILURE);
943     }
945     /* Prepare for polling. */
947     nfds = 2;
949     fds[0].fd = STDIN_FILENO;       /* Console input */
950     fds[0].events = POLLIN;
952     fds[1].fd = fd;                 /* Fanotify input */
953     fds[1].events = POLLIN;
955     /* This is the loop to wait for incoming events. */
957     printf("Listening for events.\en");
959     while (1) {
960         poll_num = poll(fds, nfds, \-1);
961         if (poll_num == \-1) {
962             if (errno == EINTR)     /* Interrupted by a signal */
963                 continue;           /* Restart poll() */
965             perror("poll");         /* Unexpected error */
966             exit(EXIT_FAILURE);
967         }
969         if (poll_num > 0) {
970             if (fds[0].revents & POLLIN) {
972                 /* Console input is available: empty stdin and quit. */
974                 while (read(STDIN_FILENO, &buf, 1) > 0 && buf != \(aq\en\(aq)
975                     continue;
976                 break;
977             }
979             if (fds[1].revents & POLLIN) {
981                 /* Fanotify events are available. */
983                 handle_events(fd);
984             }
985         }
986     }
988     printf("Listening for events stopped.\en");
989     exit(EXIT_SUCCESS);
993 .SS Example program: fanotify_fid.c
994 The second program is an example of fanotify being used with a group that
995 identifies objects by file handles.
996 The program marks the filesystem object that is passed as
997 a command-line argument
998 and waits until an event of type
999 .B FAN_CREATE
1000 has occurred.
1001 The event mask indicates which type of filesystem object\(emeither
1002 a file or a directory\(emwas created.
1003 Once all events have been read from the buffer and processed accordingly,
1004 the program simply terminates.
1006 The following shell sessions show two different invocations of
1007 this program, with different actions performed on a watched object.
1009 The first session shows a mark being placed on
1010 .IR /home/user .
1011 This is followed by the creation of a regular file,
1012 .IR /home/user/testfile.txt .
1013 This results in a
1014 .B FAN_CREATE
1015 event being generated and reported against the file's parent watched
1016 directory object and with the created file name.
1017 Program execution ends once all events captured within the buffer have
1018 been processed.
1020 .in +4n
1022 # \fB./fanotify_fid /home/user\fP
1023 Listening for events.
1024 FAN_CREATE (file created):
1025         Directory /home/user has been modified.
1026         Entry \(aqtestfile.txt\(aq is not a subdirectory.
1027 All events processed successfully. Program exiting.
1029 $ \fBtouch /home/user/testfile.txt\fP              # In another terminal
1033 The second session shows a mark being placed on
1034 .IR /home/user .
1035 This is followed by the creation of a directory,
1036 .IR /home/user/testdir .
1037 This specific action results in a
1038 .B FAN_CREATE
1039 event being generated and is reported with the
1040 .B FAN_ONDIR
1041 flag set and with the created directory name.
1043 .in +4n
1045 # \fB./fanotify_fid /home/user\fP
1046 Listening for events.
1047 FAN_CREATE | FAN_ONDIR (subdirectory created):
1048         Directory /home/user has been modified.
1049         Entry \(aqtestdir\(aq is a subdirectory.
1050 All events processed successfully. Program exiting.
1052 $ \fBmkdir \-p /home/user/testdir\fP          # In another terminal
1055 .SS Program source: fanotify_fid.c
1058 #define _GNU_SOURCE
1059 #include <errno.h>
1060 #include <fcntl.h>
1061 #include <limits.h>
1062 #include <stdio.h>
1063 #include <stdlib.h>
1064 #include <sys/types.h>
1065 #include <sys/stat.h>
1066 #include <sys/fanotify.h>
1067 #include <unistd.h>
1069 #define BUF_SIZE 256
1072 main(int argc, char *argv[])
1074     int fd, ret, event_fd, mount_fd;
1075     ssize_t len, path_len;
1076     char path[PATH_MAX];
1077     char procfd_path[PATH_MAX];
1078     char events_buf[BUF_SIZE];
1079     struct file_handle *file_handle;
1080     struct fanotify_event_metadata *metadata;
1081     struct fanotify_event_info_fid *fid;
1082     const char *file_name;
1083     struct stat sb;
1085     if (argc != 2) {
1086         fprintf(stderr, "Invalid number of command line arguments.\en");
1087         exit(EXIT_FAILURE);
1088     }
1090     mount_fd = open(argv[1], O_DIRECTORY | O_RDONLY);
1091     if (mount_fd == \-1) {
1092         perror(argv[1]);
1093         exit(EXIT_FAILURE);
1094     }
1097     /* Create an fanotify file descriptor with FAN_REPORT_DFID_NAME as
1098        a flag so that program can receive fid events with directory
1099        entry name. */
1101     fd = fanotify_init(FAN_CLASS_NOTIF | FAN_REPORT_DFID_NAME, 0);
1102     if (fd == \-1) {
1103         perror("fanotify_init");
1104         exit(EXIT_FAILURE);
1105     }
1107     /* Place a mark on the filesystem object supplied in argv[1]. */
1109     ret = fanotify_mark(fd, FAN_MARK_ADD | FAN_MARK_ONLYDIR,
1110                         FAN_CREATE | FAN_ONDIR,
1111                         AT_FDCWD, argv[1]);
1112     if (ret == \-1) {
1113         perror("fanotify_mark");
1114         exit(EXIT_FAILURE);
1115     }
1117     printf("Listening for events.\en");
1119     /* Read events from the event queue into a buffer. */
1121     len = read(fd, events_buf, sizeof(events_buf));
1122     if (len == \-1 && errno != EAGAIN) {
1123         perror("read");
1124         exit(EXIT_FAILURE);
1125     }
1127     /* Process all events within the buffer. */
1129     for (metadata = (struct fanotify_event_metadata *) events_buf;
1130             FAN_EVENT_OK(metadata, len);
1131             metadata = FAN_EVENT_NEXT(metadata, len)) {
1132         fid = (struct fanotify_event_info_fid *) (metadata + 1);
1133         file_handle = (struct file_handle *) fid\->handle;
1135         /* Ensure that the event info is of the correct type. */
1137         if (fid\->hdr.info_type == FAN_EVENT_INFO_TYPE_FID ||
1138             fid\->hdr.info_type == FAN_EVENT_INFO_TYPE_DFID) {
1139             file_name = NULL;
1140         } else if (fid\->hdr.info_type == FAN_EVENT_INFO_TYPE_DFID_NAME) {
1141             file_name = file_handle\->f_handle +
1142                         file_handle\->handle_bytes;
1143         } else {
1144             fprintf(stderr, "Received unexpected event info type.\en");
1145             exit(EXIT_FAILURE);
1146         }
1148         if (metadata\->mask == FAN_CREATE)
1149             printf("FAN_CREATE (file created):\en");
1151         if (metadata\->mask == (FAN_CREATE | FAN_ONDIR))
1152             printf("FAN_CREATE | FAN_ONDIR (subdirectory created):\en");
1154         /* metadata\->fd is set to FAN_NOFD when the group identifies
1155            objects by file handles.  To obtain a file descriptor for
1156            the file object corresponding to an event you can use the
1157            struct file_handle that\(aqs provided within the
1158            fanotify_event_info_fid in conjunction with the
1159            open_by_handle_at(2) system call.  A check for ESTALE is
1160            done to accommodate for the situation where the file handle
1161            for the object was deleted prior to this system call. */
1163         event_fd = open_by_handle_at(mount_fd, file_handle, O_RDONLY);
1164         if (event_fd == \-1) {
1165             if (errno == ESTALE) {
1166                 printf("File handle is no longer valid. "
1167                         "File has been deleted\en");
1168                 continue;
1169             } else {
1170                 perror("open_by_handle_at");
1171                 exit(EXIT_FAILURE);
1172             }
1173         }
1175         snprintf(procfd_path, sizeof(procfd_path), "/proc/self/fd/%d",
1176                 event_fd);
1178         /* Retrieve and print the path of the modified dentry. */
1180         path_len = readlink(procfd_path, path, sizeof(path) \- 1);
1181         if (path_len == \-1) {
1182             perror("readlink");
1183             exit(EXIT_FAILURE);
1184         }
1186         path[path_len] = \(aq\e0\(aq;
1187         printf("\etDirectory \(aq%s\(aq has been modified.\en", path);
1189         if (file_name) {
1190             ret = fstatat(event_fd, file_name, &sb, 0);
1191             if (ret == \-1) {
1192                 if (errno != ENOENT) {
1193                     perror("fstatat");
1194                     exit(EXIT_FAILURE);
1195                 }
1196                 printf("\etEntry \(aq%s\(aq does not exist.\en", file_name);
1197             } else if ((sb.st_mode & S_IFMT) == S_IFDIR) {
1198                 printf("\etEntry \(aq%s\(aq is a subdirectory.\en", file_name);
1199             } else {
1200                 printf("\etEntry \(aq%s\(aq is not a subdirectory.\en",
1201                         file_name);
1202             }
1203         }
1205         /* Close associated file descriptor for this event. */
1207         close(event_fd);
1208     }
1210     printf("All events processed successfully. Program exiting.\en");
1211     exit(EXIT_SUCCESS);
1214 .SH SEE ALSO
1215 .ad l
1216 .BR fanotify_init (2),
1217 .BR fanotify_mark (2),
1218 .BR inotify (7)