|簡體中文

比思論壇

 找回密碼
 按這成為會員
搜索



查看: 1037|回復: 0
打印 上一主題 下一主題

fanotify(7) — Linux manual page

[複製鏈接]

56

主題

0

好友

490

積分

中學生

Rank: 3Rank: 3

  • TA的每日心情

    6 天前
  • 簽到天數: 204 天

    [LV.7]常住居民III

    推廣值
    0
    貢獻值
    0
    金錢
    156
    威望
    490
    主題
    56
    樓主
    發表於 2020-11-26 17:07:26
    The two example programs below demonstrate the usage of the fanotify       API.   Example program: fanotify_example.c       The first program is an example of fanotify being used with its event       object information passed in the form of a file descriptor.  The       program marks the mount point passed as a command-line argument and       waits for events of type FAN_OPEN_PERM and FAN_CLOSE_WRITE.  When a       permission event occurs, a FAN_ALLOW response is given.       The following shell session shows an example of running this program.       This session involved editing the file /home/user/temp/notes.  Before       the file was opened, a FAN_OPEN_PERM event occurred.  After the file       was closed, a FAN_CLOSE_WRITE event occurred.  Execution of the       program ends when the user presses the ENTER key.           # ./fanotify_example /home           Press enter key to terminate.           Listening for events.           FAN_OPEN_PERM: File /home/user/temp/notes           FAN_CLOSE_WRITE: File /home/user/temp/notes           Listening for events stopped.   Program source: fanotify_example.c       #define _GNU_SOURCE     /* Needed to get O_LARGEFILE definition */       #include <errno.h>       #include <fcntl.h>       #include <limits.h>       #include <poll.h>       #include <stdio.h>       #include <stdlib.h>       #include <sys/fanotify.h>       #include <unistd.h>       /* Read all available fanotify events from the file descriptor 'fd' */       static void       handle_events(int fd)       {           const struct fanotify_event_metadata *metadata;           struct fanotify_event_metadata buf[200];           ssize_t len;           char path[PATH_MAX];           ssize_t path_len;           char procfd_path[PATH_MAX];           struct fanotify_response response;           /* Loop while events can be read from fanotify file descriptor */           for (;;) {               /* Read some events */               len = read(fd, buf, sizeof(buf));               if (len == -1 && errno != EAGAIN) {                   perror("read");                   exit(EXIT_FAILURE);               }               /* Check if end of available data reached */               if (len <= 0)                   break;               /* Point to the first event in the buffer */               metadata = buf;               /* Loop over all events in the buffer */               while (FAN_EVENT_OK(metadata, len)) {                   /* Check that run-time and compile-time structures match */                   if (metadata->vers != FANOTIFY_METADATA_VERSION) {                       fprintf(stderr,                               "Mismatch of fanotify metadata version.\n");                       exit(EXIT_FAILURE);                   }                   /* metadata->fd contains either FAN_NOFD, indicating a                      queue overflow, or a file descriptor (a nonnegative                      integer). Here, we simply ignore queue overflow. */                   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(response));                       }                       /* Handle closing of writable file event */                       if (metadata->mask & FAN_CLOSE_WRITE)                           printf("FAN_CLOSE_WRITE: ");                       /* Retrieve and print pathname of the accessed file */                       snprintf(procfd_path, sizeof(procfd_path),                                "/proc/self/fd/%d", metadata->fd);                       path_len = readlink(procfd_path, path,                                           sizeof(path) - 1);                       if (path_len == -1) {                           perror("readlink");                           exit(EXIT_FAILURE);                       }                       path[path_len] = '\0';                       printf("File %s\n", path);                       /* Close the file descriptor of the event */                       close(metadata->fd);                   }                   /* Advance to next event */                   metadata = FAN_EVENT_NEXT(metadata, len);               }           }       }       int       main(int argc, char *argv[])       {           char buf;           int fd, poll_num;           nfds_t nfds;           struct pollfd fds[2];           /* Check mount point is supplied */           if (argc != 2) {               fprintf(stderr, "Usage: %s MOUNT\n", argv[0]);               exit(EXIT_FAILURE);           }           printf("Press enter key to terminate.\n");           /* 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");               exit(EXIT_FAILURE);           }           /* Mark the 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, AT_FDCWD,                             argv[1]) == -1) {               perror("fanotify_mark");               exit(EXIT_FAILURE);           }           /* Prepare for polling */           nfds = 2;           /* Console input */           fds[0].fd = STDIN_FILENO;           fds[0].events = POLLIN;           /* Fanotify input */           fds[1].fd = fd;           fds[1].events = POLLIN;           /* This is the loop to wait for incoming events */           printf("Listening for events.\n");           while (1) {               poll_num = poll(fds, nfds, -1);               if (poll_num == -1) {                   if (errno == EINTR)     /* Interrupted by a signal */                       continue;           /* Restart poll() */                   perror("poll");         /* Unexpected error */                   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 != '\n')                           continue;                       break;                   }                   if (fds[1].revents & POLLIN) {                       /* Fanotify events are available */                       handle_events(fd);                   }               }           }           printf("Listening for events stopped.\n");           exit(EXIT_SUCCESS);       }
    重要聲明:本論壇是以即時上載留言的方式運作,比思論壇對所有留言的真實性、完整性及立場等,不負任何法律責任。而一切留言之言論只代表留言者個人意見,並非本網站之立場,讀者及用戶不應信賴內容,並應自行判斷內容之真實性。於有關情形下,讀者及用戶應尋求專業意見(如涉及醫療、法律或投資等問題)。 由於本論壇受到「即時上載留言」運作方式所規限,故不能完全監察所有留言,若讀者及用戶發現有留言出現問題,請聯絡我們比思論壇有權刪除任何留言及拒絕任何人士上載留言 (刪除前或不會作事先警告及通知 ),同時亦有不刪除留言的權利,如有任何爭議,管理員擁有最終的詮釋權。用戶切勿撰寫粗言穢語、誹謗、渲染色情暴力或人身攻擊的言論,敬請自律。本網站保留一切法律權利。

    手機版| 廣告聯繫

    GMT+8, 2024-11-1 06:48 , Processed in 0.026444 second(s), 20 queries , Gzip On, Memcache On.

    Powered by Discuz! X2.5

    © 2001-2012 Comsenz Inc.

    回頂部