[PATCH 1/1] Man pages for the fanotify API

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



From: Heinrich Schuchardt <xypron.glpk@xxxxxx>

Michael,

thank you for all your comments. I reflected these in the appended
revised patch.

I studied the proposal by Stephan Mueller dated 2011 but the proposed pages are
not a superset of his proposal due to some changes in the API
(e.g. FAN_READONLY_FALLBACK).

Include linux/fcntl.h is needed for O_LARGEFILE.

Signed-off-by: Heinrich Schuchardt <xypron.glpk@xxxxxx>
---
 man2/fanotify_init.2 |  199 ++++++++++++++++++++
 man2/fanotify_mark.2 |  216 ++++++++++++++++++++++
 man7/fanotify.7      |  497 ++++++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 912 insertions(+)
 create mode 100644 man2/fanotify_init.2
 create mode 100644 man2/fanotify_mark.2
 create mode 100644 man7/fanotify.7

diff --git a/man2/fanotify_init.2 b/man2/fanotify_init.2
new file mode 100644
index 0000000..2847f09
--- /dev/null
+++ b/man2/fanotify_init.2
@@ -0,0 +1,199 @@
+.\" Copyright (C) 2013, Heinrich Schuchardt <xypron.glpk@xxxxxx>
+.\" 
+.\" %%%LICENSE_START(VERBATIM)
+.\" Permission is granted to make and distribute verbatim copies of this
+.\" manual provided the copyright notice and this permission notice are
+.\" preserved on all copies.
+.\"
+.\" Permission is granted to copy and distribute modified versions of
+.\" this manual under the conditions for verbatim copying, provided that
+.\" the entire resulting derived work is distributed under the terms of
+.\" a permission notice identical to this one.
+.\"
+.\" Since the Linux kernel and libraries are constantly changing, this
+.\" manual page may be incorrect or out-of-date.  The author(s) assume.
+.\" no responsibility for errors or omissions, or for damages resulting.
+.\" from the use of the information contained herein.  The author(s) may.
+.\" not have taken the same level of care in the production of this.
+.\" manual, which is licensed free of charge, as they might when working.
+.\" professionally.
+.\"
+.\" Formatted or processed versions of this manual, if unaccompanied by
+.\" the source, must acknowledge the copyright and authors of this work.
+.\" %%%LICENSE_END
+.TH FANOTIFY_INIT 2 2014-03-14 "Linux" "Linux Programmer's Manual"
+.SH NAME
+fanotify_init \- create and initialize fanotify group
+.SH SYNOPSIS
+.B #include <linux/fcntl.h>
+.br
+.B #include <sys/fanotify.h>
+.sp
+.BI "int fanotify_init(unsigned int " flags ", unsigned int " event_f_flags );
+.SH DESCRIPTION
+.BR fanotify_init()
+initializes a new fanotify group and returns a file descriptor for the event
+queue.
+.PP
+The file decriptor is used in calls to
+.BR fanotify_mark (2)
+to define for which files, directories, or mounts fanotify events shall be
+created.
+These events are received by reading from the file descriptor.
+Some events only inform that a file has been accessed.
+Other events allow to decide if another application may access a file.
+Decisions upon the permission to access files are made by writing to the file
+descriptor.
+An overview is provided in
+.BR fanotify (7).
+.PP
+Multiple programs may be using the fanotify interface at the same time to
+monitor the same files. 
+By indicating in
+.I flags
+which kind of operations will be executed a logical sequence can be defined
+in which events are forwarded to the listeners. The following bitmasks define
+the kind of usage.
+Only one of them may be used when calling
+.B fanotify_init()
+.TP
+.B FAN_CLASS_PRE_CONTENT
+sets a priority level which allows to receive events notifying that a file has
+been accessed and events for permission decisions before the file is accessed.
+This priority level is intended for event listeners that need to access files
+before they contain their final data.
+It is useful for hierarchical storage managers.
+.TP
+.B FAN_CLASS_CONTENT
+sets a priority level which allows to receive events notifying that a file has
+been accessed and events for permission decisions before the file is accessed.
+This priority level is intended for event listeners that need to access files
+when they already contain their final content.
+This may be used by malware detection programs.
+.TP
+.B FAN_CLASS_NOTIF
+sets a priority level which allows only to receive events notifying that a file
+has been accessed.
+Permission decisions before the file is accessed are not possible.
+.PP
+Listeners will receive events in this order of priority levels.
+The call sequence among listeners of the same priority level is undefined.
+.PP
+Calling
+.BR fanotify_init()
+requires the
+.B CAP_SYS_ADMIN
+capability.
+This constraint might be relaxed in future versions of the API.
+Hence additional local capability checks have been implemented as indicated
+below.
+.PP
+.IR flags
+defines the behavior of the file descriptor.
+It is a bitmask composed of the following values:
+.TP
+.B FAN_CLOEXEC
+sets the close-on-exec flag
+.RB ( FD_CLOEXEC )
+on the new file descriptor.
+When calling
+.BR execve (2)
+the inherited file descriptor of the child process will be closed.
+See the description of the
+.B O_CLOEXEC
+flag in
+.BR open (2).
+.TP
+.B FAN_NONBLOCK
+enables the non-blocking flag
+.RB ( O_NONBLOCK )
+for the file descriptor.
+Reading from the file descriptor will not block.
+Instead if no data is available in a call to
+.BR read (2)
+an error
+.B EAGAIN
+will occur.
+.TP
+.B FAN_CLASS_PRE_CONTENT
+see above.
+.TP
+.B FAN_CLASS_CONTENT
+see above.
+.TP
+.B FAN_CLASS_NOTIF
+see above.
+.TP
+.B FAN_UNLIMITED_QUEUE
+removes the limit of 16384 events on the size of the event queue.
+This flag requires the
+.B CAP_SYS_ADMIN
+capability.
+.TP
+.B FAN_UNLIMITED_MARKS
+removes the limiti of 8192 marks on the number of marks.
+This flag requires the
+.B CAP_SYS_ADMIN
+capability.
+.PP
+.IR event_f_flags
+defines the file flags, with which file descriptors for fanotify events shall
+be created.
+For explanations of possible values see parameter
+.I flags
+of the 
+.BR open (2)
+system call.
+Useful values are
+.TP
+.B O_RDONLY
+read only access.
+.TP
+.B O_WRONLY
+write only access.
+.TP
+.B O_RDWR
+read and write access.
+.TP
+.B O_CLOEXEC
+enable close-on-exec.
+.TP
+.B O_LARGEFILE
+support files exceeding 2 GB.
+Failing to set this flag will result in an
+.B EOVERFLOW
+error when trying to open a large file which is monitored by a fanotify group.
+.SH RETURN VALUE
+If the system
+.BR fanotify_init ()
+is successful a new file descriptor is returned.
+In case of an error \-1 is returned, and
+.I errno
+is set to indicate the error.
+.SH ERRORS
+.TP
+.B EINVAL
+An invalid value was passed in
+.IR flags .
+.B FAN_ALL_INIT_FLAGS
+defines all allowable bits.
+.TP
+.B EMFILE
+indicates the number of listeners exceeds 128.
+.TP
+.B ENOMEM
+Out of memory, the allocation of memory for the notification group failed. 
+.TP
+.B EPERM
+Operation not permitted because capability
+.B CAP_SYS_ADMIN
+is missing.
+.SH VERSIONS
+.BR fanotify_init ()
+was introduced in version 2.6.36 of the Linux kernel and enabled in version
+2.6.37.
+.SH "CONFORMING TO"
+This system call is Linux-specific.
+.SH "SEE ALSO"
+.BR fanotify_mark (2),
+.BR fanotify (7)
diff --git a/man2/fanotify_mark.2 b/man2/fanotify_mark.2
new file mode 100644
index 0000000..9439d18
--- /dev/null
+++ b/man2/fanotify_mark.2
@@ -0,0 +1,216 @@
+.\" Copyright (C) 2013,  Heinrich Schuchardt <xypron.glpk@xxxxxx>
+.\" 
+.\" %%%LICENSE_START(VERBATIM)
+.\" Permission is granted to make and distribute verbatim copies of this
+.\" manual provided the copyright notice and this permission notice are
+.\" preserved on all copies.
+.\"
+.\" Permission is granted to copy and distribute modified versions of
+.\" this manual under the conditions for verbatim copying, provided that
+.\" the entire resulting derived work is distributed under the terms of
+.\" a permission notice identical to this one.
+.\"
+.\" Since the Linux kernel and libraries are constantly changing, this
+.\" manual page may be incorrect or out-of-date.  The author(s) assume.
+.\" no responsibility for errors or omissions, or for damages resulting.
+.\" from the use of the information contained herein.  The author(s) may.
+.\" not have taken the same level of care in the production of this.
+.\" manual, which is licensed free of charge, as they might when working.
+.\" professionally.
+.\"
+.\" Formatted or processed versions of this manual, if unaccompanied by
+.\" the source, must acknowledge the copyright and authors of this work.
+.\" %%%LICENSE_END
+.TH FANOTIFY_MARK 2 2014-03-14 "Linux" "Linux Programmer's Manual"
+.SH NAME
+fanotify_mark \- add, remove, or modify a fanotify mark on a filesystem
+object.
+.SH SYNOPSIS
+.nf
+.B #include <sys/fanotify.h>
+.sp
+.BI "int fanotify_mark (int " fanotify_fd ", unsigned int " flags ,
+.BI "                   uint64_t " mask ", int " dfd ,
+.BI "                   const char *" pathname );
+.fi
+.SH DESCRIPTION
+.BR fanotify_mark (2)
+adds, removes, or modifies a fanotify mark on a filesystem.
+.PP
+.I fd
+is the file descriptor returned by
+.BR fanotify_init (2).
+.PP
+.I flags
+is a bitmask describing the modification to perform.
+It is composed of the following values:
+.TP
+.B FAN_MARK_ADD
+Add the events in
+.IR mask .
+.I mask
+must be nonempty or an error
+.B EINVAL
+will occur.
+.TP
+.B FAN_MARK_REMOVE
+Remove the events in
+.IR mask .
+.I mask
+must be nonempty or an error
+.B EINVAL
+will occur.
+.TP
+.B FAN_MARK_DONT_FOLLOW
+Do not follow symbolic links.
+.TP
+.B FAN_MARK_ONLYDIR
+Fail if the path to be marked is not a directory.
+.TP
+.B FAN_MARK_MOUNT
+The path indicates a mount to be marked.
+.TP
+.B FAN_MARK_IGNORED_MASK
+Add to or remove from the ignored event mask.
+.TP
+.B FAN_MARK_IGNORED_SURV_MODIFY
+The ignored mask shall survive modify events.
+If this flag is not set the ignored mask is cleared if a modify event occurs
+for the fanotify group.
+.TP
+.B FAN_MARK_FLUSH
+Remove all events from the whole group.
+.PP
+Only one of
+.BR FAN_MARK_ADD , FAN_MARK_REMOVE ,
+or
+.B FAN_MARK_FLUSH
+can be used. Failure to do so results in an error
+.BR EINVAL .
+.PP
+.I mask
+defines which events shall be listened to.
+It is a bitmask composed of the following values:
+.TP
+.B FAN_ACCESS
+A file was accessed (read).
+.TP
+.B FAN_MODIFY
+A file was modified (write).
+.TP
+.B FAN_CLOSE_WRITE
+A writable file was closed.
+.TP
+.B FAN_CLOSE_NOWRITE
+An readonly file was closed.
+.TP
+.B FAN_OPEN
+A file was opened.
+.TP
+.B FAN_Q_OVERFLOW
+The event queue overflowed.
+.TP
+.B FAN_OPEN_PERM
+A file open permission was requested.
+.TP
+.B FAN_ACCESS_PERM
+An access permission for a file was requested.
+.TP
+.B FAN_ONDIR
+The event occurred against a directory.
+.TP
+.B FAN_EVENT_ON_CHILD
+An event for a child of a monitored directory occurred.
+.PP
+The following composed value is defined
+.TP
+.B FAN_CLOSE
+A file was closed (FAN_CLOSE_WRITE | FAN_CLOSE_NOWRITE).
+.PP
+.I dfd
+is a file descriptor.
+.IP - 2
+If 
+.I pathname
+is NULL
+.I dfd
+defines the path to be marked.
+.IP - 2
+If
+.I pathname
+is NULL and dfd takes the special value
+.B AT_FDCWD
+defined in <fcntl.h> the current working directory is to be marked.
+.IP - 2
+If
+.I pathname
+is absolute it defines the path to be marked.
+.IP - 2
+If
+.I pathname
+is relative it defines a path relative to the path indicated by the file
+descriptor in
+.I dfd
+to be marked.
+.IP - 2
+If
+.I pathname
+is relative and
+.I dfd
+takes the special value
+.B AT_FDCWD
+it defines a path relative to the current working directory to be marked.
+.PP
+.I pathname
+is an absolute or relative path to be marked.
+.SH RETURN VALUE
+If
+.BR fanotify_mark ()
+is successful 0 is returned.
+In case of an error \-1 is returned, and
+.I errno
+is set to indicate the error.
+.SH ERRORS
+.TP
+.B EBADF
+An invalid file descriptor was passed in
+.IR fanotify_fd .
+.TP
+.B EINVAL
+An invalid value was passed in
+.IR flags ,
+or
+.IR mask ,
+or
+.I fd
+was not a fanotify file descriptor.
+.TP
+.B ENOENT
+The directory indicated by
+.IR pathname
+is not valid.
+This error also occurs when trying to remove a mark from a directory or mount
+which is not marked.
+.TP
+.B ENOMEM
+Out of memory.
+.TP
+.B ENOSPC
+Too many marks.
+.TP
+.B ENOTDIR
+.I flags
+contains
+.B FAN_MARK_ONLYDIR
+and
+.I dfd
+does not point to a directory.
+.SH VERSIONS
+.BR fanotify_mark ()
+was introduced in version 2.6.36 of the Linux kernel and enabled in version
+2.6.37.
+.SH "CONFORMING TO"
+This system call is Linux-specific.
+.SH "SEE ALSO"
+.BR fanotify_init (2),
+.BR fanotify (7)
diff --git a/man7/fanotify.7 b/man7/fanotify.7
new file mode 100644
index 0000000..1174488
--- /dev/null
+++ b/man7/fanotify.7
@@ -0,0 +1,497 @@
+.\" Copyright (C) 2013, Heinrich Schuchardt <xypron.glpk@xxxxxx>
+.\" 
+.\" %%%LICENSE_START(VERBATIM)
+.\" Permission is granted to make and distribute verbatim copies of this
+.\" manual provided the copyright notice and this permission notice are
+.\" preserved on all copies.
+.\"
+.\" Permission is granted to copy and distribute modified versions of
+.\" this manual under the conditions for verbatim copying, provided that
+.\" the entire resulting derived work is distributed under the terms of
+.\" a permission notice identical to this one.
+.\"
+.\" Since the Linux kernel and libraries are constantly changing, this
+.\" manual page may be incorrect or out-of-date.  The author(s) assume.
+.\" no responsibility for errors or omissions, or for damages resulting.
+.\" from the use of the information contained herein.  The author(s) may.
+.\" not have taken the same level of care in the production of this.
+.\" manual, which is licensed free of charge, as they might when working.
+.\" professionally.
+.\"
+.\" Formatted or processed versions of this manual, if unaccompanied by
+.\" the source, must acknowledge the copyright and authors of this work.
+.\" %%%LICENSE_END
+.TH FANOTIFY 7 2014-03-14 "Linux" "Linux Programmer's Manual"
+.SH NAME
+fanotify \- monitoring filesystem events
+.SH DESCRIPTION
+The
+.B fanotify
+API provides notification and interception of filesystem events.
+Use cases are virus scanning and hierarchical storage management.
+
+The following system calls are used with this API:
+.BR fanotify_init (2),
+.BR fanotify_mark (2),
+.BR poll (2),
+.BR ppoll (2),
+.BR read (2),
+.BR write (2),
+and
+.BR close (2).
+.PP
+.BR fanotify_init (2)
+creates and initializes a fanotify notification group and returns a file
+descriptor referring to it.
+A fanotify notification group is an internal object of the kernel which holds a
+list of files, directories and mounts for which events shall be created when a
+file is accessed, and a list of files for which a decision is pending whether
+access shall be granted.
+.PP
+When all file descriptors referring to the group are closed, the group is
+released and the resources are freed for reuse by the kernel.
+.PP
+.BR fanotify_mark (2)
+adds a file, a directory, or a mount from the group and specifies which events
+shall be reported, or removes or modifies such an entry.
+.PP
+The fanotify file descriptor signals when data becomes available when passed to
+either of
+.BR epoll (7),
+.BR poll (2),
+.BR select (2).
+.PP
+Calling
+.BR read (2)
+for the file descriptor returned by
+.BR fanotify_init (2)
+blocks (if flag
+.B FAN_NONBLOCK
+is not set in the call to
+.BR fanotify_init (2))
+until either a file event occurs or it is interrupted by a signal
+(see
+.BR signal (7)).
+
+The return value of
+.BR read (2)
+is the length of the filled buffer or -1 in case of an error.
+In case of success the read buffer contains one or more of the following
+structures:
+
+.in +4n
+.nf
+struct fanotify_event_metadata {
+    __u32 event_len;
+    __u8 vers;
+    __u8 reserved;
+    __u16 metadata_len;
+    __aligned_u64 mask;
+    __s32 fd; 
+    __s32 pid;
+};
+.fi
+.in
+
+.TP 15
+.I event_len
+is the length of the data for the current event and the offset to the next
+event in the buffer.
+This length might be longer than the size of structure
+.I fanotify_event_metadata.
+Therefore it is recommended to use a larger buffer size when reading,
+e.g. 4096 bytes.
+.TP
+.I vers
+holds the version of the
+.B fanotify
+API. The value should be checked against
+.B FANOTIFY_METADATA_VERSION.
+.TP
+.I reserved
+is not used.
+.TP
+.I metadata_len
+is the length of the structure.
+The field was introduced to facilitate the implementation of optional headers
+per event type.
+.TP
+.I mask
+is a bitmask describing the event.
+.TP
+.I fd
+is an open file descriptor for the object being accessed or
+.B FAN_NOFD
+if a queue overflow occurred.
+The reading application is responsible for closing this file descriptor.
+.TP
+.I pid
+is the ID of the process that caused the event.
+A program listening to fanotify events can compare this pid to the pid returned
+by
+.BR getpid (2)
+to detect if the event is caused internally or is due to a file access by another
+program.
+.PP
+The bitmask in
+.I mask
+is composed of the following values:
+.TP
+.B FAN_ACCESS
+file was accessed.
+.TP
+.B FAN_OPEN
+file was opened.
+.TP
+.B FAN_MODIFY
+file was modified.
+.TP
+.B FAN_CLOSE_WRITE
+writable file closed.
+.TP
+.B FAN_CLOSE_NOWRITE
+unwritable file closed.
+.TP
+.B FAN_Q_OVERFLOW
+event queue overflowed.
+.TP
+.B FAN_ACCESS_PERM
+file accessed in perm check.
+.TP
+.B FAN_OPEN_PERM
+file open in perm check.
+.TP
+.B FAN_ONDIR
+event occurred against directory.
+.TP
+.B FAN_EVENT_ON_CHILD
+event for a child of a directory occurred.
+.PP
+To check for any close event the following bitmask may be used
+.TP
+.B FAN_CLOSE
+a file was closed 
+(FAN_CLOSE_WRITE | FAN_CLOSE_NOWRITE).
+.PP
+The following macros are provided to iterate over a buffer of
+.B fanotify
+event metadata:
+.TP
+.B FAN_EVENT_OK(meta, len)
+checks the remaining length
+.I len
+of the buffer
+.I meta
+against the length of the metadata structure and the
+.I event_len
+field of the first metadata structure in the buffer.
+.TP
+.B FAN_EVENT_NEXT(meta, len)
+lets the pointer
+.I meta
+point to the next metadata structure using the length indicated in the
+.I event_len
+field of the metadata structure and reduces the remaining length of the
+buffer
+.I len.
+.PP
+For permission events the application must
+.BR write (2)
+to the
+.B fanotify
+file descriptor a structure
+
+.in +4n
+.nf
+struct fanotify_response {
+        __s32 fd;
+        __u32 response;
+};
+.fi
+.in
+
+.TP 15
+.I fd
+is the file descriptor from structure
+.I fanotify_event_metadata.
+.TP
+.I response
+must be either
+.br
+.B FAN_ALLOW
+to allow the file operation or
+.br
+.B FAN_DENY
+to deny the file operation.
+.PP
+To end listening it is sufficient to
+.BR close (2)
+the
+.B fanotify
+file descriptor.
+The open permission events will be set to allowed, and all resources will be
+returned to the kernel.
+.PP
+File /proc/<pid>/fdinfo/<fd> contains information about fanotify marks for
+file descriptor fd of process pid. See
+.I Documentation/filesystems/proc.txt
+for details.
+.SH ERRORS
+The following errors may occur when reading from the
+.B fanotify
+file descriptor:
+.TP
+.B EAGAIN
+a nonblocking call did not return any data.
+.TP
+.B EFAULT
+the read buffer is outside your accessible address space.
+.TP
+.B EINTR
+a signal has occurred.
+.TP
+.B EINVAL
+the buffer is too short to hold the event.
+.PP
+The following errors may occur when writing to the
+.B fanotify
+file descriptor:
+.TP
+.B EFAULT
+the write buffer is outside your accessible address space.
+.TP
+.B EINVAL
+fanotify access permissions are not enabled or the value of
+.I response
+in the response structure is not valid.
+.TP
+.B ENOENT
+the file descriptor
+.I fd
+in the response structure is not valid.
+This might occur because the file was already deleted by another thread or
+process.
+.SH VERSIONS
+The
+.B fanotify
+API was introduced in version 2.6.36 of the Linux kernel and enabled in
+version 2.6.37. Fdinfo support was added in version 3.8.
+.SH "CONFORMING TO"
+The
+.B fanotify
+API is Linux-specific.
+.SH NOTES
+The notification is based on the kernel filesystem notification system
+.B fsnotify.
+.PP
+To enable the
+.B fanotify
+API the following setting in the Kernel configuration is needed:
+CONFIG_FANOTIFY=y. For permission handling
+CONFIG_FANOTIFY_ACCESS_PERMISSIONS=y must be set.
+.SH EXAMPLE
+The following program demonstrates the usage of the
+.B fanotify
+API. It creates a thread waiting for
+.B FAN_PERM_OPEN
+and
+.B FAN_CLOSE_WRITE
+events
+for mount /home.
+If a permission event arises a
+.B FAN_ALLOW
+response is given.
+.PP
+The following output was recorded while editing file /home/user/temp/notes.
+Before the file was opened a
+.B FAN_OPEN_PERM
+event occured.
+After the file was closed a
+.B FAN_CLOSE_WRITE
+event occured.
+The example program ended when hitting the enter key.
+.SS Example output
+.nf
+Press enter key to terminate.
+Listening for events.
+FAN_OPEN_PERM: File /home/zfsdt/temp/notes
+FAN_CLOSE_WRITE: File /home/zfsdt/temp/notes
+
+Listening for events stopped.
+.fi
+.SS Program source
+.nf
+#include <linux/fcntl.h>
+#include <linux/limits.h>
+#include <errno.h>
+#include <poll.h>
+#include <pthread.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/fanotify.h>
+#include <unistd.h>
+
+#define RUNNING 1
+#define STOPPING 2
+
+static int status;
+
+// Handle available events.
+static void
+handle_events(int fd)
+{
+    const struct fanotify_event_metadata *metadata;
+    char buf[4096];
+    int len;
+    char path[PATH_MAX];
+    int path_len;
+    struct fanotify_response response;
+
+    // Loop while events can be read from fanotify file descriptor.
+    for(;;) {
+
+        // Read next events.
+        len = read(fd, (void *) &buf, sizeof (buf));
+        if (len > 0) {
+
+            // Point to the first event in the buffer.
+            metadata = (struct fanotify_event_metadata *) buf;
+
+            // Loop over all events in the buffer.
+            while (FAN_EVENT_OK(metadata, len)) {
+
+                // Check event contains a file descriptor.
+                if (metadata\->fd >= 0) {
+
+                    // Handle open permission event.
+                    if (metadata\->mask & FAN_OPEN_PERM) {
+                        printf("FAN_OPEN_PERM: ");
+                        // Allow file to be opened.
+                        response.fd = metadata\->fd;
+                        response.response = FAN_ALLOW;
+                        write(fd, &response, sizeof (
+                                  struct fanotify_response));
+                    }
+
+                    // Handle closing of writable file event.
+                    if (metadata\->mask & FAN_CLOSE_WRITE) {
+                        printf("FAN_CLOSE_WRITE: ");
+                    }
+
+                    // Determine path of the file accessed.
+                    sprintf(path, "/proc/self/fd/%d", metadata\->fd);
+                    path_len = readlink(path, path, sizeof (path) \- 1);
+
+                    // Write path.
+                    if (path_len > 0) {
+                        path[path_len] = '\\0';
+                        printf("File %s", path);
+                    }
+
+                    // Close the file descriptor of the event.
+                    close(metadata\->fd);
+                    printf("\\n");
+                }
+
+                // Forward pointer to next event.
+                metadata = FAN_EVENT_NEXT(metadata, len);
+            }
+        } else {
+
+            // No more events are available.
+            break;
+        }
+    }
+}
+
+// Worker thread.
+static void *
+run(void *data)
+{
+    int fd;
+    nfds_t nfds;
+    struct pollfd fds;
+
+    // Create the file descriptor for accessing the fanotify API.
+    fd = fanotify_init(FAN_CLOEXEC | FAN_CLASS_CONTENT | FAN_NONBLOCK,
+                       O_RDONLY | O_LARGEFILE);
+    if (fd == \-1) {
+        perror("fanotify_init");
+        return NULL;
+    }
+
+    // Mark the home mount for
+    // \- permission events before opening files
+    // \- notification events after closing a write enabled file descriptor.
+    if (fanotify_mark(fd, FAN_MARK_ADD | FAN_MARK_MOUNT,
+                      FAN_OPEN_PERM | FAN_CLOSE_WRITE, FAN_NOFD,
+                      "/home") == \-1) {
+        perror("fanotify_mark");
+        close(fd);
+        return NULL;
+    }
+
+    // Prepare for polling.
+    nfds = 1;
+    fds.fd = fd;
+    fds.events = POLLIN;
+    fds.revents = 0;
+    status = RUNNING;
+
+    // This is the loop to wait for  incoming events.
+    printf("Listening for events.\\n");
+    while (status == RUNNING) {
+        int ret;
+
+        // Poll for 1 s.
+        ret = poll(&fds, nfds, 1000);
+        if (ret > 0) {
+            if (fds.revents & POLLIN) {
+                // Events are available.
+                handle_events(fd);
+            }
+            fds.revents = 0;
+        }
+        if (ret == \-1 && errno != EINTR) {
+            perror("poll");
+            break;
+        }
+    }
+
+    // Close fanotify file descriptor.
+    close(fd);
+    printf("Listening for events stopped.\\n");
+    return NULL;
+}
+
+int
+main(int argc, char *argv[])
+{
+    pthread_attr_t attr;
+    pthread_t thread;
+    void *result;
+
+    printf("Press enter key to terminate.\\n");
+
+    // Create a worker thread for monitoring file events.
+    if (pthread_attr_init(&attr)) {
+        return EXIT_FAILURE;
+    }
+    if (pthread_create(&thread, &attr, run, NULL)) {
+        return EXIT_FAILURE;
+    }
+
+    // Wait for user input.
+    getchar();
+
+    // Terminate worker thread.
+    status = STOPPING;
+    pthread_join(thread, &result);
+    return EXIT_SUCCESS;
+}
+.fi
+.SH "SEE ALSO"
+.ad l
+.BR fanotify_init (2),
+.BR fanotify_mark (2),
+.BR inotify (7)
-- 
1.7.10.4

--
To unsubscribe from this list: send the line "unsubscribe linux-man" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html




[Index of Archives]     [Kernel Documentation]     [Netdev]     [Linux Ethernet Bridging]     [Linux Wireless]     [Kernel Newbies]     [Security]     [Linux for Hams]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux RAID]     [Linux Admin]     [Samba]

  Powered by Linux