fanotify

FANOTIFY(7)     Ð ÑководÑÑво пÑогÑаммиÑÑа Linux     FANOTIFY(7)



ÐÐЯ
       fanotify - оÑÑлеживание ÑобÑÑий в Ñайловой
       ÑиÑÑеме

ÐÐÐСÐÐÐÐ
       ÐÑогÑаммнÑй инÑеÑÑÐµÐ¹Ñ fanotify ÑведомлÑÐµÑ Ð¾
       ÑобÑÑиÑÑ Ð² Ñайловой ÑиÑÑеме и пеÑеÑваÑÑваеÑ
       иÑ. ÐапÑимеÑ, его можно иÑполÑзоваÑÑ Ð´Ð»Ñ
       ÑканиÑÐ¾Ð²Ð°Ð½Ð¸Ñ Ñайлов на виÑÑÑÑ Ð¸ ÑпÑавлениÑ
       иеÑаÑÑиÑеÑким ÑÑанилиÑем. РнаÑÑоÑÑее вÑемÑ,
       поддеÑживаеÑÑÑ ÑолÑко огÑаниÑеннÑй набоÑ
       ÑобÑÑий. Ð ÑаÑÑноÑÑи, не поддеÑживаÑÑÑÑ ÑобÑÑиÑ
       ÑозданиÑ, ÑÐ´Ð°Ð»ÐµÐ½Ð¸Ñ Ð¸ пеÑемеÑÐµÐ½Ð¸Ñ (о
       пÑогÑаммном инÑеÑÑейÑе Ð´Ð»Ñ ÑÑÐ¸Ñ ÑобÑÑий
       ÑмоÑÑиÑе в inotify(7)).

       ÐополниÑелÑнÑе возможноÑÑи по ÑÑÐ°Ð²Ð½ÐµÐ½Ð¸Ñ Ñ
       пÑогÑаммнÑм инÑеÑÑейÑом inotify(7): ÑпоÑобноÑÑÑ
       оÑÑлеживаÑÑ Ð²Ñе обÑекÑÑ Ð² ÑмонÑиÑованной
       Ñайловой ÑиÑÑеме, даваÑÑ Ð¿Ñава на доÑÑÑп и
       ÑиÑаÑÑ Ð¸Ð»Ð¸ изменÑÑÑ ÑÐ°Ð¹Ð»Ñ Ð¿ÐµÑед Ñем как доÑÑÑп
       полÑÑÐ°Ñ Ð´ÑÑгие пÑиложениÑ.

       РпÑогÑаммнÑй инÑеÑÑÐµÐ¹Ñ Ð²ÑодÑÑ ÑледÑÑÑие
       ÑиÑÑемнÑе вÑзовÑ: fanotify_init(2), fanotify_mark(2), read(2),
       write(2) и close(2).

   ÐÑÐ·Ð¾Ð²Ñ fanotify_init(), fanotify_mark() и гÑÑппÑ
       Ñведомлений
       СиÑÑемнÑй вÑзов fanotify_init(2) ÑоздаÑÑ Ð¸
       иниÑиализиÑÑÐµÑ Ð³ÑÑÐ¿Ð¿Ñ ÑÐ²ÐµÐ´Ð¾Ð¼Ð»ÐµÐ½Ð¸Ñ fanotify и
       возвÑаÑÐ°ÐµÑ ÑказÑваÑÑий на Ð½ÐµÑ ÑайловÑй
       деÑкÑипÑоÑ.

       ÐÑÑппа ÑÐ²ÐµÐ´Ð¾Ð¼Ð»ÐµÐ½Ð¸Ñ fanotify â ÑÑо внÑÑÑенний
       обÑÐµÐºÑ ÑдÑа, в коÑоÑом ÑÑаниÑÑÑ ÑпиÑок Ñайлов,
       каÑалогов и ÑоÑек монÑиÑованиÑ, Ð´Ð»Ñ ÐºÐ¾ÑоÑÑÑ
       Ð´Ð¾Ð»Ð¶Ð½Ñ ÑоздаваÑÑÑÑ ÑобÑÑиÑ.

       У каждой запиÑи в гÑÑппе ÑÐ²ÐµÐ´Ð¾Ð¼Ð»ÐµÐ½Ð¸Ñ fanotify
       еÑÑÑ Ð´Ð²Ðµ биÑовÑе маÑки: меÑок и
       игноÑиÑованиÑ. РмаÑке меÑок ÑказÑваеÑÑÑ Ð´Ð»Ñ
       ÐºÐ°ÐºÐ¸Ñ Ð´ÐµÐ¹ÑÑвий на Ñайлами должнÑ
       ÑоздаваÑÑÑÑ ÑобÑÑиÑ. РмаÑке игноÑиÑованиÑ
       ÑказÑваеÑÑÑ Ð´Ð»Ñ ÐºÐ°ÐºÐ¸Ñ Ð´ÐµÐ¹ÑÑвий не должнÑ
       ÑоздаваÑÑÑÑ ÑобÑÑиÑ. ÐÐ¼ÐµÑ Ð¼Ð°Ñки ÑÐ°ÐºÐ¸Ñ Ñипов
       можно помеÑиÑÑ ÑоÑÐºÑ Ð¼Ð¾Ð½ÑиÑÐ¾Ð²Ð°Ð½Ð¸Ñ Ð¸Ð»Ð¸
       каÑалог Ð´Ð»Ñ Ð¿Ð¾Ð»ÑÑÐµÐ½Ð¸Ñ ÑобÑÑий, и в Ñоже вÑемÑ
       игноÑиÑоваÑÑ ÑобÑÑÐ¸Ñ Ð´Ð»Ñ Ð¾Ð¿ÑеделÑннÑÑ
       обÑекÑов в ÑÑой ÑоÑке монÑиÑÐ¾Ð²Ð°Ð½Ð¸Ñ Ð¸Ð»Ð¸
       каÑалоге.

       СиÑÑемнÑй вÑзов fanotify_mark(2) добавлÑÐµÑ Ñайл,
       каÑалог или ÑоÑÐºÑ Ð¼Ð¾Ð½ÑиÑÐ¾Ð²Ð°Ð½Ð¸Ñ Ð² гÑÑппÑ
       ÑÐ²ÐµÐ´Ð¾Ð¼Ð»ÐµÐ½Ð¸Ñ Ð¸ задаÑÑ ÐºÐ°ÐºÐ¸Ðµ ÑобÑÑÐ¸Ñ Ð´Ð¾Ð»Ð¶Ð½Ñ
       оÑÑлеживаÑÑÑÑ (или игноÑиÑоваÑÑÑÑ), или
       ÑдалÑÐµÑ Ð¸Ð»Ð¸ изменÑÐµÑ Ð½ÑжнÑÑ Ð·Ð°Ð¿Ð¸ÑÑ.

       Ðозможное пÑименение маÑки игноÑиÑованиÑ
       â кÑÑ Ñайлов. ÐнÑеÑеÑÑÑÑие ÑобÑÑÐ¸Ñ Ð´Ð»Ñ
       Ñайлового кÑÑа â изменение Ñайла и
       закÑÑÑие. ÐÐ»Ñ ÑÑого добавлÑем кÑÑиÑÑемÑй
       каÑалог или ÑоÑÐºÑ Ð¼Ð¾Ð½ÑиÑÐ¾Ð²Ð°Ð½Ð¸Ñ Ð´Ð»Ñ Ð¿ÑиÑма
       ÑÑÐ¸Ñ ÑобÑÑий. ÐоÑле полÑÑÐµÐ½Ð¸Ñ Ð¿ÐµÑвого ÑобÑÑиÑ
       об изменении Ñайла, ÑооÑвеÑÑÑвÑÑÑÐ°Ñ Ð·Ð°Ð¿Ð¸ÑÑ
       кÑÑа помеÑаеÑÑÑ ÐºÐ°Ðº недейÑÑвиÑелÑнаÑ.
       ÐалÑнейÑие ÑобÑÑÐ¸Ñ Ð¾Ð± изменении Ñайла наÑ
       не инÑеÑеÑÑÑÑ, пока Ñайл не бÑÐ´ÐµÑ Ð·Ð°ÐºÑÑÑ. ÐлÑ
       ÑÑого ÑобÑÑие об изменении можно добавиÑÑ
       в маÑÐºÑ Ð¸Ð³Ð½Ð¾ÑиÑованиÑ. ÐÑи полÑÑении ÑобÑÑиÑ
       о закÑÑÑии, ÑобÑÑие об изменении можно
       ÑдалиÑÑ Ð¸Ð· маÑки игноÑиÑÐ¾Ð²Ð°Ð½Ð¸Ñ Ð¸ запиÑÑ
       Ñайлового кÑÑа можно обновиÑÑ.

       ÐапиÑи в гÑÑппе ÑÐ²ÐµÐ´Ð¾Ð¼Ð»ÐµÐ½Ð¸Ñ fanotify ÑÑÑлаÑÑÑÑ Ð½Ð°
       Ñайл и каÑалог по номеÑÑ Ð¸Ð½Ð¾Ð´Ñ (inode), а на
       ÑоÑÐºÑ Ð¼Ð¾Ð½ÑиÑÐ¾Ð²Ð°Ð½Ð¸Ñ â ÑеÑез ID монÑиÑованиÑ. ÐÑи
       пеÑеименовании или пеÑемеÑении Ñайла
       или каÑалога внÑÑÑи Ñой же ÑоÑки
       монÑиÑÐ¾Ð²Ð°Ð½Ð¸Ñ ÑооÑвеÑÑÑвÑÑÑÐ°Ñ Ð·Ð°Ð¿Ð¸ÑÑ Ð¾ÑÑаÑÑÑÑ.
       ÐÑли Ñайл или каÑалог ÑдалÑеÑÑÑ Ð¸Ð»Ð¸
       пеÑемеÑаеÑÑÑ Ð² дÑÑгÑÑ ÑоÑÐºÑ Ð¼Ð¾Ð½ÑиÑованиÑ, или
       еÑли ÑоÑка монÑиÑÐ¾Ð²Ð°Ð½Ð¸Ñ ÑазмонÑиÑÑеÑÑÑ, Ñо
       ÑооÑвеÑÑÑвÑÑÑÐ°Ñ Ð·Ð°Ð¿Ð¸ÑÑ ÑдалÑеÑÑÑ.

   ÐÑеÑÐµÐ´Ñ ÑобÑÑий
       ÐÐ»Ñ Ð²Ð¾Ð·Ð½Ð¸ÐºÐ°ÑÑÐ¸Ñ ÑобÑÑий Ñ Ð¾Ð±ÑекÑами Ñайловой
       ÑиÑÑемÑ, коÑоÑÑе оÑÑлеживаÑÑÑÑ Ð³ÑÑппой
       ÑведомлениÑ, ÑиÑÑема fanotify генеÑиÑÑÐµÑ ÑобÑÑиÑ
       и помеÑÐ°ÐµÑ Ð¸Ñ Ð² оÑеÑедÑ. ÐоÑле ÑÑого ÑобÑÑиÑ
       можно пÑоÑиÑаÑÑ (Ñ Ð¿Ð¾Ð¼Ð¾ÑÑÑ read(2) и подобнÑÑ) из
       Ñайлового деÑкÑипÑоÑа fanotify, возвÑаÑÑнного
       fanotify_init(2).

       ÐенеÑиÑÑеÑÑÑ Ð´Ð²Ð° Ñипа ÑобÑÑий: ÑобÑÑиÑ
       ÑÐ²ÐµÐ´Ð¾Ð¼Ð»ÐµÐ½Ð¸Ñ Ð¸ ÑобÑÑÐ¸Ñ Ð´Ð¾ÑÑÑпа. УведомлÑÑÑие
       ÑобÑÑÐ¸Ñ Ð¿ÑоÑÑо инÑоÑмиÑÑÑÑ Ð¸ не ÑÑебÑÑÑ Ð´ÐµÐ¹ÑÑвиÑ
       Ð¾Ñ Ð¿ÑинÑвÑего пÑиложениÑ, за иÑклÑÑением
       закÑÑÑÐ¸Ñ Ñайлового деÑкÑипÑоÑа,
       пеÑедаваемого в ÑобÑÑии (ÑмоÑÑиÑе далее).
       СобÑÑÐ¸Ñ Ð´Ð¾ÑÑÑпа запÑаÑиваÑÑ Ð¿Ð¾Ð»ÑÑивÑее
       пÑиложение о ÑазÑеÑении доÑÑÑпа к ÑайлÑ. ÐлÑ
       ÑÑÐ¸Ñ ÑобÑÑий полÑÑаÑÐµÐ»Ñ Ð´Ð¾Ð»Ð¶ÐµÐ½ напиÑаÑÑ Ð¾ÑвеÑ,
       даваÑÑ Ð»Ð¸ доÑÑÑп или неÑ.

       СобÑÑие ÑдалÑеÑÑÑ Ð¸Ð· оÑеÑеди ÑобÑÑий гÑÑппÑ
       fanotify поÑле пÑоÑÑениÑ. СобÑÑÐ¸Ñ Ð´Ð¾ÑÑÑпа, коÑоÑÑе
       бÑли пÑоÑиÑанÑ, оÑÑаÑÑÑÑ Ð²Ð¾ внÑÑÑеннем ÑпиÑке
       гÑÑÐ¿Ð¿Ñ fanotify до ÑÐµÑ Ð¿Ð¾Ñ, пока ÑеÑение о
       доÑÑÑпе не бÑÐ´ÐµÑ Ð·Ð°Ð¿Ð¸Ñано в ÑайловÑй
       деÑкÑипÑÐ¾Ñ fanotify, или ÑайловÑй деÑкÑипÑоÑ
       fanotify не бÑÐ´ÐµÑ Ð·Ð°ÐºÑÑÑ.

   ЧÑение ÑобÑÑий fanotify
       ÐÑзов read(2) Ñ ÑайловÑм деÑкÑипÑоÑом,
       полÑÑеннÑм Ð¾Ñ fanotify_init(2), блокиÑÑеÑ
       вÑполнение (еÑли не Ñказан Ñлаг FAN_NONBLOCK в
       вÑзове fanotify_init(2)) до ÑÐµÑ Ð¿Ð¾Ñ, пока не
       пÑоизойдÑÑ Ñайловое ÑобÑÑие или вÑзов не
       бÑÐ´ÐµÑ Ð¿ÑеÑван Ñигналом (ÑмоÑÑиÑе signal(7)).

       ÐоÑле ÑÑпеÑного вÑÐ¿Ð¾Ð»Ð½ÐµÐ½Ð¸Ñ read(2) бÑÑÐµÑ ÑÑениÑ
       ÑодеÑÐ¶Ð¸Ñ Ð¾Ð´Ð½Ñ Ð¸Ð»Ð¸ более ÑледÑÑÑÐ¸Ñ ÑÑÑÑкÑÑÑ:

           struct fanotify_event_metadata {
               __u32 event_len;
               __u8 vers;
               __u8 reserved;
               __u16 metadata_len;
               __aligned_u64 mask;
               __s32 fd;
               __s32 pid;
           };

       ÐÐ»Ñ ÑвелиÑÐµÐ½Ð¸Ñ Ð¿ÑоизводиÑелÑноÑÑи
       ÑекомендÑеÑÑÑ Ð¸ÑполÑзоваÑÑ Ð±ÑÑÐµÑ Ð±Ð¾Ð»ÑÑого
       ÑазмеÑа (напÑимеÑ, 4096 байÑ) Ð´Ð»Ñ Ñого, ÑÑобÑ
       полÑÑиÑÑ Ð½ÐµÑколÑко ÑобÑÑий за один вÑзов
       read(2).

       ÐозвÑаÑаемое read(2) знаÑение â колиÑеÑÑво
       Ð±Ð°Ð¹Ñ Ð¿Ð¾Ð¼ÐµÑÑннÑÑ Ð² бÑÑеÑ, или -1 в ÑлÑÑае оÑибки
       (но ÑмоÑÑиÑе ÐÐФÐÐТЫ).

       ÐÐ¾Ð»Ñ ÑÑÑÑкÑÑÑÑ fanotify_event_metadata:

       event_len
              Ðлина даннÑÑ ÑекÑÑего ÑобÑÑÐ¸Ñ Ð¸ ÑмеÑение
              на ÑледÑÑÑее ÑобÑÑие в бÑÑеÑе. Ð ÑекÑÑей
              ÑеализаÑии знаÑение event_len вÑегда
              Ñавно FAN_EVENT_METADATA_LEN. Ðднако, благодаÑÑ
              пÑогÑÐ°Ð¼Ð¼Ð½Ð¾Ð¼Ñ Ð¸Ð½ÑеÑÑейÑÑ Ð² бÑдÑÑем бÑдÑÑ
              возвÑаÑаÑÑÑÑ ÑÑÑÑкÑÑÑÑ Ð¿ÐµÑеменной длинÑ.

       vers   ÐÐ¾Ð¼ÐµÑ Ð²ÐµÑÑии ÑÑÑÑкÑÑÑÑ. Ðн должен
              ÑÑавниваÑÑÑÑ Ñ FANOTIFY_METADATA_VERSION длÑ
              пÑовеÑки Ñого, ÑÑо ÑÑÑÑкÑÑÑÑ, возвÑаÑаемÑе
              во вÑÐµÐ¼Ñ Ð²ÑполнениÑ, ÑооÑвеÑÑÑвÑÑÑ
              ÑÑÑÑкÑÑÑам, опÑеделÑннÑм во вÑемÑ
              компилÑÑиÑ. Ð ÑлÑÑае неÑооÑвеÑÑÑвиÑ
              пÑиложение должно пÑекÑаÑиÑÑ Ð¿Ð¾Ð¿ÑÑки
              иÑполÑзоваÑÑ ÑайловÑй деÑкÑипÑÐ¾Ñ fanotify.

       reserved
              Ðе иÑполÑзÑеÑÑÑ.

       metadata_len
              Ðлина ÑÑÑÑкÑÑÑÑ. ÐÑо поле бÑло добавлено
              Ð´Ð»Ñ Ð¾Ð±Ð»ÐµÐ³ÑÐµÐ½Ð¸Ñ ÑеализаÑии
              необÑзаÑелÑнÑÑ Ð·Ð°Ð³Ð¾Ð»Ð¾Ð²ÐºÐ¾Ð² ÑазнÑÑ Ñипов
              ÑобÑÑий. Ð ÑекÑÑей ÑеализаÑии Ñакие
              необÑзаÑелÑнÑе заголовки оÑÑÑÑÑÑвÑÑÑ.

       mask   ÐиÑÐ¾Ð²Ð°Ñ Ð¼Ð°Ñка, опиÑÑваÑÑÐ°Ñ ÑобÑÑие
              (ÑмоÑÑиÑе далее).

       fd     ФайловÑй деÑкÑипÑÐ¾Ñ Ð¾ÑÑлеживаемого
              обÑекÑа или FAN_NOFD, еÑли возникло
              пеÑеполнение оÑеÑеди. ФайловÑй
              деÑкÑипÑÐ¾Ñ Ð¼Ð¾Ð¶Ð½Ð¾ иÑполÑзоваÑÑ Ð´Ð»Ñ
              доÑÑÑпа к ÑодеÑÐ¶Ð¸Ð¼Ð¾Ð¼Ñ Ð¾ÑÑлеживаемого
              Ñайла или каÑалога. ЧиÑаÑÑее
              пÑиложение оÑвеÑÑÑвенно за закÑÑÑие
              ÑÑого Ñайлового деÑкÑипÑоÑа.

              Ðогда вÑзÑваеÑÑÑ fanotify_init(2) вÑзÑваÑÑий
              Ð¼Ð¾Ð¶ÐµÑ ÑказаÑÑ (в аÑгÑменÑе event_f_flags)
              ÑазлиÑнÑе Ñлаги ÑоÑÑоÑÐ½Ð¸Ñ Ñайла, коÑоÑÑе
              бÑдÑÑ ÑÑÑÐ°Ð½Ð¾Ð²Ð»ÐµÐ½Ñ Ð½Ð° оÑкÑÑÑом Ñайловом
              деÑкÑипÑоÑе, ÑооÑвеÑÑÑвÑÑÑем ÑÑомÑ
              ÑÐ°Ð¹Ð»Ð¾Ð²Ð¾Ð¼Ñ Ð´ÐµÑкÑипÑоÑÑ. Также, на
              оÑÑÑваемом Ñайловом деÑкÑипÑоÑе
              ÑÑÑанавливаеÑÑÑ (внÑÑÑи ÑдÑа) Ñлаг
              ÑоÑÑоÑÐ½Ð¸Ñ Ñайла FMODE_NONOTIFY. ÐÑÐ¾Ñ Ñлаг
              подавлÑÐµÑ Ð³ÐµÐ½ÐµÑаÑÐ¸Ñ ÑобÑÑий fanotify.
              Таким обÑазом, когда полÑÑаÑÐµÐ»Ñ ÑобÑÑиÑ
              fanotify обÑаÑиÑÑÑ Ðº оÑÑÐ»ÐµÐ¶Ð¸Ð²Ð°ÐµÐ¼Ð¾Ð¼Ñ ÑайлÑ
              или каÑÐ°Ð»Ð¾Ð³Ñ ÑеÑез ÑÑÐ¾Ñ ÑайловÑй
              деÑкÑипÑоÑ, дополниÑелÑнÑÑ ÑобÑÑий
              Ñоздано не бÑдеÑ.

       pid    ÐденÑиÑикаÑÐ¾Ñ Ð¿ÑоÑеÑÑа, из-за коÑоÑого
              пÑоизоÑло ÑобÑÑие. ÐÑогÑамма, ÑлÑÑаÑÑаÑ
              ÑобÑÑÐ¸Ñ fanotify, Ð¼Ð¾Ð¶ÐµÑ ÑÑавниÑÑ ÑÑÐ¾Ñ PID Ñ PID,
              возвÑаÑаемÑм getpid(2), Ð´Ð»Ñ Ð¿ÑовеÑки, ÑÑо
              ÑобÑÑие не возникло из-за Ñамого
              ÑлÑÑаÑÑего, а из-за доÑÑÑпа к ÑайлÑ
              дÑÑгого пÑоÑеÑÑа.

       РбиÑовой маÑке mask ÑказÑваÑÑ ÑобÑÑиÑ,
       пÑоизоÑедÑие Ñ Ð¾Ð´Ð¸Ð½Ð¾ÑнÑм обÑекÑом Ñайловой
       ÑиÑÑемÑ. РмаÑке Ð¼Ð¾Ð¶ÐµÑ Ð±ÑÑÑ ÑÑÑановлено
       неÑколÑко биÑ, еÑли бÑло более одного
       ÑобÑÑÐ¸Ñ Ñ Ð¾ÑÑлеживаемÑм обÑекÑом Ñайловой
       ÑиÑÑемÑ. Ð ÑаÑÑноÑÑи, возникÑие дÑÑг за дÑÑгом
       ÑобÑÑÐ¸Ñ Ñ Ð¾Ð´Ð½Ð¸Ð¼ обÑекÑом Ñайловой ÑиÑÑÐµÐ¼Ñ Ð¸
       пÑоизоÑедÑие из-за одного пÑоÑеÑÑа могÑÑ
       бÑÑÑ Ð¾Ð±ÑÐµÐ´Ð¸Ð½ÐµÐ½Ñ Ð² одно ÑобÑÑие, за
       иÑклÑÑением Ñого, ÑÑо два ÑобÑÑÐ¸Ñ Ð´Ð¾ÑÑÑпа
       никогда не обÑединÑÑÑÑÑ Ð² одном ÑлеменÑе
       оÑеÑеди.

       ÐиÑÑ Ð¼Ð°Ñки mask:

       FAN_ACCESS
              ÐоÑÑÑп (на ÑÑение) к ÑÐ°Ð¹Ð»Ñ Ð¸Ð»Ð¸ каÑалогÑ
              (но ÑмоÑÑиÑе ÐÐФÐÐТЫ).

       FAN_OPEN
              Файл или каÑалог оÑкÑÑÑ.

       FAN_MODIFY
              Файл изменÑн.

       FAN_CLOSE_WRITE
              Файл, оÑкÑÑÑÑй на запиÑÑ (O_WRONLY или O_RDWR),
              закÑÑÑ.

       FAN_CLOSE_NOWRITE
              Файл или каÑалог, оÑкÑÑÑÑй ÑолÑко длÑ
              ÑÑÐµÐ½Ð¸Ñ (O_RDONLY), закÑÑÑ.

       FAN_Q_OVERFLOW
              ÐÑеÑÐµÐ´Ñ ÑобÑÑий пÑевÑÑила огÑаниÑение в
              16384 запиÑи. ÐÑо огÑаниÑение можно
              измениÑÑ, Ñказав Ñлаг FAN_UNLIMITED_QUEUE пÑи
              вÑзове fanotify_init(2).

       FAN_ACCESS_PERM
              ÐÑиложение ÑоÑÐµÑ Ð¿ÑоÑиÑаÑÑ Ñайл или
              каÑалог, напÑимеÑ, Ñ Ð¿Ð¾Ð¼Ð¾ÑÑÑ read(2) или
              readdir(2). ЧиÑаÑÐµÐ»Ñ ÑобÑÑÐ¸Ñ Ð´Ð¾Ð»Ð¶ÐµÐ½ напиÑаÑÑ
              оÑÐ²ÐµÑ (опиÑано далее) о ÑазÑеÑении
              доÑÑÑпа к обÑекÑÑ Ñайловой ÑиÑÑемÑ.

       FAN_OPEN_PERM
              ÐÑиложение ÑоÑÐµÑ Ð¾ÑкÑÑÑÑ Ñайл или
              каÑалог. ЧиÑаÑÐµÐ»Ñ ÑобÑÑÐ¸Ñ Ð´Ð¾Ð»Ð¶ÐµÐ½
              напиÑаÑÑ Ð¾ÑÐ²ÐµÑ Ð¾ ÑазÑеÑении оÑкÑÑÑиÑ
              обÑекÑа Ñайловой ÑиÑÑемÑ.

       ÐÐ»Ñ Ð¿ÑовеÑки лÑбого ÑобÑÑÐ¸Ñ Ð·Ð°ÐºÑÑÑÐ¸Ñ Ð¼Ð¾Ð¶ÐµÑ
       иÑполÑзоваÑÑÑÑ ÑледÑÑÑÐ°Ñ Ð±Ð¸ÑÐ¾Ð²Ð°Ñ Ð¼Ð°Ñка:

       FAN_CLOSE
              Файл закÑÑÑ. ÐÑо Ñиноним:

                  FAN_CLOSE_WRITE | FAN_CLOSE_NOWRITE

       СледÑÑÑие макÑоÑÑ Ð¿Ð¾Ð·Ð²Ð¾Ð»ÑÑÑ Ð¾Ð±ÑодиÑÑ Ð±ÑÑÐµÑ Ñ
       меÑаданнÑми ÑобÑÑий fanotify, возвÑаÑаемÑй
       read(2) из Ñайлового деÑкÑипÑоÑа fanotify:

       FAN_EVENT_OK(meta, len)
              ÐÑÐ¾Ñ Ð¼Ð°ÐºÑÐ¾Ñ ÑвеÑÑÐµÑ Ð¾ÑÑавÑÑÑÑÑ Ð´Ð»Ð¸Ð½Ñ len
              бÑÑеÑа meta Ñ Ð´Ð»Ð¸Ð½Ð¾Ð¹ ÑÑÑÑкÑÑÑÑ Ð¼ÐµÑаданнÑÑ Ð¸
              полем event_len из пеÑвой ÑÑÑÑкÑÑÑÑ
              меÑаданнÑÑ Ð² бÑÑеÑе.

       FAN_EVENT_NEXT(meta, len)
              ÐÑÐ¾Ñ Ð¼Ð°ÐºÑÐ¾Ñ Ð¸ÑполÑзÑÐµÑ Ð´Ð»Ð¸Ð½Ñ Ð¸Ð· полÑ
              event_len ÑÑÑÑкÑÑÑÑ Ð¼ÐµÑаданнÑÑ, на коÑоÑÑÑ
              ÑказÑÐ²Ð°ÐµÑ meta, Ð´Ð»Ñ Ð²ÑÑиÑÐ»ÐµÐ½Ð¸Ñ Ð°Ð´ÑеÑа
              ÑледÑÑÑей ÑÑÑÑкÑÑÑÑ Ð¼ÐµÑаданнÑÑ, коÑоÑаÑ
              наÑодиÑÑÑ Ð¿Ð¾Ñле meta. Рполе len Ñказано
              колиÑеÑÑво Ð±Ð°Ð¹Ñ Ð¼ÐµÑаданнÑÑ, оÑÑавÑиÑÑÑ Ð²
              бÑÑеÑе. ÐакÑÐ¾Ñ Ð²Ð¾Ð·Ð²ÑаÑÐ°ÐµÑ ÑказаÑÐµÐ»Ñ Ð½Ð°
              ÑледÑÑÑÑÑ ÑÑÑÑкÑÑÑÑ Ð¼ÐµÑаданнÑÑ Ð¿Ð¾Ñле meta и
              ÑменÑÑÐ°ÐµÑ len на колиÑеÑÑво Ð±Ð°Ð¹Ñ Ð² ÑÑÑÑкÑÑÑе
              меÑаданнÑÑ, коÑоÑÐ°Ñ Ð±Ñла пÑопÑÑена (Ñ. е.,
              вÑÑиÑÐ°ÐµÑ meta->event_len из len).

       ÐополниÑелÑно еÑÑÑ:

       FAN_EVENT_METADATA_LEN
              ÐÑÐ¾Ñ Ð¼Ð°ÐºÑÐ¾Ñ Ð²Ð¾Ð·Ð²ÑаÑÐ°ÐµÑ ÑÐ°Ð·Ð¼ÐµÑ (в байÑаÑ)
              ÑÑÑÑкÑÑÑÑ fanotify_event_metadata. ÐÑо минималÑнÑй
              ÑÐ°Ð·Ð¼ÐµÑ (и, в наÑÑоÑÑее вÑемÑ,
              единÑÑвеннÑй) меÑаданнÑÑ Ð»Ñбого ÑобÑÑиÑ.

   ÐÑÑлеживание ÑобÑÑий ÑеÑез ÑайловÑй деÑкÑипÑоÑ
       fanotify
       Ðогда Ð²Ð¾Ð·Ð½Ð¸ÐºÐ°ÐµÑ ÑобÑÑие fanotify ÑайловÑй
       деÑкÑипÑÐ¾Ñ fanotify помеÑаеÑÑÑ ÐºÐ°Ðº доÑÑÑпнÑй длÑ
       ÑÑÐµÐ½Ð¸Ñ Ð¿Ñи его пеÑедаÑе в epoll(7), poll(2) или
       select(2).

   РабоÑа Ñ ÑобÑÑиÑми доÑÑÑпа
       ÐÐ»Ñ ÑобÑÑий доÑÑÑпа пÑиложение должно
       запиÑаÑÑ (write(2)) в ÑайловÑй деÑкÑипÑÐ¾Ñ fanotify
       ÑледÑÑÑÑÑ ÑÑÑÑкÑÑÑÑ:

           struct fanotify_response {
               __s32 fd;
               __u32 response;
           };

       ÐÐ¾Ð»Ñ ÑÑой ÑÑÑÑкÑÑÑÑ Ð¸Ð¼ÐµÑÑ ÑледÑÑÑее назнаÑение:

       fd     ФайловÑй деÑкÑипÑÐ¾Ñ Ð¸Ð· ÑÑÑÑкÑÑÑÑ
              fanotify_event_metadata.

       response
              Ð ÑÑом поле ÑказÑÐ²Ð°ÐµÑ Ð¾ ÑазÑеÑении
              доÑÑÑпа или запÑеÑении. Ðанное
              знаÑение должно бÑÑÑ Ñавно FAN_ALLOW, ÑÑобÑ
              ÑазÑеÑиÑÑ Ð¾Ð¿ÐµÑаÑÐ¸Ñ Ñ Ñайлом, или FAN_DENY длÑ
              запÑеÑа.

       ÐÑли доÑÑÑп запÑеÑаеÑÑÑ, Ñо запÑаÑиваÑÑее
       пÑиложение полÑÑÐ¸Ñ Ð¾ÑÐ¸Ð±ÐºÑ EPERM.

   ÐакÑÑÑие Ñайлового деÑкÑипÑоÑа fanotify
       Ðогда вÑе ÑайловÑе деÑкÑипÑоÑÑ, ÑказÑваÑÑие
       на гÑÑÐ¿Ð¿Ñ ÑÐ²ÐµÐ´Ð¾Ð¼Ð»ÐµÐ½Ð¸Ñ fanotify, закÑÑÑÑ, гÑÑппа
       fanotify оÑвобождаеÑÑÑ Ð¸ ÐµÑ ÑеÑÑÑÑÑ ÑÑановÑÑÑÑ
       доÑÑÑÐ¿Ð½Ñ ÑдÑÑ Ð´Ð»Ñ Ð¿Ð¾Ð²ÑоÑного иÑполÑзованиÑ.
       ÐоÑле close(2) вÑе оÑÑавÑиеÑÑ Ð½ÐµÐ¿ÑоÑмоÑÑеннÑе
       ÑобÑÑÐ¸Ñ Ð´Ð¾ÑÑÑпа бÑдÑÑ ÑазÑеÑенÑ.

   /proc/[pid]/fdinfo
       Файл /proc/[pid]/fdinfo/[fd] ÑодеÑÐ¶Ð¸Ñ Ð¸Ð½ÑоÑмаÑÐ¸Ñ Ð¾
       меÑÐºÐ°Ñ fanotify Ð´Ð»Ñ Ñайлового деÑкÑипÑоÑа fd
       пÑоÑеÑÑа pid ÐодÑобноÑÑи ÑмоÑÑиÑе в proc(5).

ÐШÐÐÐÐ
       ÐÑоме обÑÑнÑÑ Ð¾Ñибок read(2) пÑи ÑÑении из
       Ñайлового деÑкÑипÑоÑа fanotify могÑÑ Ð²Ð¾Ð·Ð½Ð¸ÐºÐ°ÑÑ
       ÑледÑÑÑие оÑибки:

       EINVAL ÐÑÑÐµÑ ÑлиÑком мал Ð´Ð»Ñ ÑÑÐ°Ð½ÐµÐ½Ð¸Ñ ÑобÑÑиÑ.

       EMFILE ÐоÑÑигнÑÑо макÑималÑное попÑоÑеÑÑное
              колиÑеÑÑво оÑкÑÑÑÑÑ Ñайлов. СмоÑÑиÑе
              опиÑание RLIMIT_NOFILE в getrlimit(2).

       ENFILE ÐоÑÑигнÑÑ Ð¿Ñедел на обÑее колиÑеÑÑво
              оÑкÑÑÑÑÑ Ñайлов в ÑиÑÑеме. СмоÑÑиÑе
              /proc/sys/fs/file-max в proc(5).

       ETXTBSY
              ÐÑа оÑибка возвÑаÑаеÑÑÑ read(2), еÑли пÑи
              вÑзове fanotify_init(2) в аÑгÑменÑе event_f_flags
              бÑл Ñказан O_RDWR или O_WRONLY и пÑоизоÑло
              ÑобÑÑие Ñ Ð¾ÑÑлеживаемÑм Ñайлом, коÑоÑÑй
              в даннÑй Ð¼Ð¾Ð¼ÐµÐ½Ñ Ð²ÑполнÑеÑÑÑ.

       ÐÑоме обÑÑнÑÑ Ð¾Ñибок write(2) пÑи запиÑи в
       ÑайловÑй деÑкÑипÑÐ¾Ñ fanotify могÑÑ Ð²Ð¾Ð·Ð½Ð¸ÐºÐ°ÑÑ
       ÑледÑÑÑие оÑибки:

       EINVAL СвойÑÑво Ð´Ð»Ñ Ð¿ÑовеÑки пÑав доÑÑÑпа fanotify
              не вклÑÑено в наÑÑÑÐ¾Ð¹ÐºÐ°Ñ ÑдÑа или
              некоÑÑекÑное знаÑение response в ÑÑÑÑкÑÑÑе
              оÑвеÑа.

       ENOENT ÐекоÑÑекÑнÑй ÑайловÑй деÑкÑипÑÐ¾Ñ fd в
              ÑÑÑÑкÑÑÑе оÑвеÑа. ÐÑо Ð¼Ð¾Ð¶ÐµÑ Ð¿ÑоиÑÑодиÑÑ,
              когда оÑÐ²ÐµÑ Ð½Ð° пÑаво доÑÑÑпа Ñже бÑл
              запиÑан.

ÐÐРСÐÐ
       ÐÑогÑаммнÑй инÑеÑÑÐµÐ¹Ñ fanotify пÑедÑÑавлен в
       веÑÑии 2.6.36 ÑдÑа Linux и вклÑÑÑн в веÑÑии 2.6.37.
       ÐоддеÑжка fdinfo бÑла добавлена в веÑÑии 3.8.

СÐÐТÐÐТСТÐÐРСТÐÐÐÐРТÐÐ
       ÐÑогÑаммнÑй инÑеÑÑÐµÐ¹Ñ fanotify еÑÑÑ ÑолÑко в Linux.

ÐÐÐÐЧÐÐÐЯ
       ÐÑогÑаммнÑй инÑеÑÑÐµÐ¹Ñ fanotify доÑÑÑпен ÑолÑко,
       еÑли ÑдÑо ÑобÑано Ñ Ð²ÐºÐ»ÑÑÑннÑм паÑамеÑÑом
       наÑÑÑойки CONFIG_FANOTIFY. Также, ÑабоÑа Ñ Ð´Ð¾ÑÑÑпом
       в fanotify доÑÑÑпна ÑолÑко, еÑли вклÑÑÑн паÑамеÑÑ
       наÑÑÑойки CONFIG_FANOTIFY_ACCESS_PERMISSIONS.

   ÐгÑаниÑÐµÐ½Ð¸Ñ Ð¸ подводнÑе камни
       Fanotify ÑообÑÐ°ÐµÑ ÑолÑко о ÑобÑÑиÑÑ, коÑоÑÑе
       возникли пÑи иÑполÑзовании
       полÑзоваÑелÑÑкими пÑогÑаммами
       пÑогÑаммного инÑеÑÑейÑа Ñайловой ÑиÑÑемÑ.
       ÐоÑÑÐ¾Ð¼Ñ ÑобÑÑÐ¸Ñ Ð¾Ð± обÑаÑении к Ñайлам в
       ÑеÑевÑÑ ÑайловÑÑ ÑиÑÑÐµÐ¼Ð°Ñ Ð½Ðµ оÑлавливаÑÑÑÑ.

       ÐÑогÑаммнÑй инÑеÑÑÐµÐ¹Ñ fanotify не ÑообÑÐ°ÐµÑ Ð¾
       доÑÑÑпе и изменениÑÑ, коÑоÑÑе могÑÑ
       пÑоизойÑи из-за mmap(2), msync(2) и munmap(2).

       СобÑÑÐ¸Ñ Ð´Ð»Ñ ÐºÐ°Ñалогов ÑоздаÑÑÑÑ ÑолÑко, еÑли
       Ñам каÑалог оÑкÑÑваеÑÑÑ, ÑиÑаеÑÑÑ Ð¸ закÑÑваеÑÑÑ.
       Ðобавление, Ñдаление и изменение
       поÑомков оÑÑлеживаемого каÑалога не
       пÑÐ¸Ð²Ð¾Ð´Ð¸Ñ Ðº Ð²Ð¾Ð·Ð½Ð¸ÐºÐ½Ð¾Ð²ÐµÐ½Ð¸Ñ ÑобÑÑий.

       Fanotify не ÑÐ»ÐµÐ´Ð¸Ñ Ð·Ð° каÑалогами ÑекÑÑÑивно:
       ÑÑÐ¾Ð±Ñ ÑледиÑÑ Ð·Ð° подкаÑалогами каÑалога,
       нÑжно Ð¸Ñ Ñвно помеÑиÑÑ (и, замеÑим, ÑÑо
       пÑогÑаммнÑй инÑеÑÑÐµÐ¹Ñ fanotify не позволÑеÑ
       оÑÑлеживаÑÑ Ñоздание подкаÑалога, ÑÑо
       заÑÑÑднÑÐµÑ ÑекÑÑÑивное Ñлежение).
       ÐÑÑлеживание ÑоÑек монÑиÑÐ¾Ð²Ð°Ð½Ð¸Ñ Ð¿Ð¾Ð·Ð²Ð¾Ð»ÑеÑ
       ÑледиÑÑ Ð·Ð° вÑем деÑевом каÑалогов.

       ÐÑеÑÐµÐ´Ñ ÑобÑÑий Ð¼Ð¾Ð¶ÐµÑ Ð¿ÐµÑеполниÑÑÑÑ. Ð ÑÑом
       ÑлÑÑае ÑобÑÑÐ¸Ñ ÑеÑÑÑÑÑÑ.

ÐÐФÐÐТЫ
       Ðо Linux 3.19, fallocate(2) не генеÑиÑовал ÑобÑÑий
       fanotify. ÐаÑÐ¸Ð½Ð°Ñ Ñ Linux 3.19, вÑÐ·Ð¾Ð²Ñ fallocate(2)
       генеÑиÑÑÑÑ ÑобÑÑие FAN_MODIFY.

       Ð Linux 3.17 ÑÑÑеÑÑвÑÑÑ ÑледÑÑÑие деÑекÑÑ:

       *  Ð Linux обÑÐµÐºÑ Ñайловой ÑиÑÑÐµÐ¼Ñ Ð¼Ð¾Ð¶ÐµÑ Ð±ÑÑÑ
          доÑÑÑпен ÑеÑез неÑколÑко пÑÑей, напÑимеÑ,
          ÑаÑÑÑ Ñайловой ÑиÑÑÐµÐ¼Ñ Ð¼Ð¾Ð¶ÐµÑ Ð±ÑÑÑ
          пеÑемонÑиÑована mount(8) Ñ Ð¸ÑполÑзованием
          паÑамеÑÑа --bind. ÐжидаÑÑий ÑлÑÑаÑÐµÐ»Ñ Ð¿Ð¾Ð»ÑÑиÑ
          ÑÐ²ÐµÐ´Ð¾Ð¼Ð»ÐµÐ½Ð¸Ñ Ð¾Ð± обÑекÑе Ñайловой ÑиÑÑемÑ
          ÑолÑко из запÑоÑенной ÑоÑки монÑиÑованиÑ.
          Ð ÑобÑÑиÑÑ Ð¸Ð· дÑÑÐ³Ð¸Ñ ÑоÑек Ñведомлений не
          поÑÑÑпиÑ.

       *  ÐÑи генеÑаÑии ÑобÑÑÐ¸Ñ Ð½Ðµ делаеÑÑÑ Ð¿ÑовеÑка,
          ÑÑо полÑзоваÑелÑÑÐºÐ¾Ð¼Ñ ID полÑÑаÑÑего
          пÑоÑеÑÑа ÑазÑеÑено ÑиÑаÑÑ Ð¸Ð»Ð¸ пиÑаÑÑ Ð² Ñайл
          пеÑед пеÑедаÑей Ñайлового деÑкÑипÑоÑа на
          ÑÑÐ¾Ñ Ñайл. ÐÑо пÑедÑÑавлÑÐµÑ Ð½ÐµÐºÐ¾ÑоÑÑй ÑиÑк
          безопаÑноÑÑи, когда Ñ Ð¿ÑогÑамм,
          вÑполнÑÑÑиÑÑÑ Ð½ÐµÐ¿ÑивилегиÑованнÑми
          полÑзоваÑелÑми, еÑÑÑ Ð¼Ð°Ð½Ð´Ð°Ñ CAP_SYS_ADMIN.

       *  ÐÑли вÑзов read(2) полÑÑÐ°ÐµÑ Ð½ÐµÑколÑко ÑобÑÑий
          из оÑеÑеди fanotify и Ð²Ð¾Ð·Ð½Ð¸ÐºÐ°ÐµÑ Ð¾Ñибка,
          бÑÐ´ÐµÑ Ð²Ð¾Ð·Ð²ÑаÑена Ð¿Ð¾Ð»Ð½Ð°Ñ Ð´Ð»Ð¸Ð½Ð° ÑобÑÑий,
          коÑоÑÑе бÑли ÑÑпеÑно ÑкопиÑÐ¾Ð²Ð°Ð½Ñ Ð² бÑÑеÑ
          полÑзоваÑелÑÑкого пÑоÑÑÑанÑÑва до оÑибки.
          ÐозвÑаÑаемое знаÑение не бÑÐ´ÐµÑ Ñавно -1, и
          в errno не запиÑÑваеÑÑÑ ÐºÐ¾Ð´ оÑибки. То еÑÑÑ
          ÑиÑаÑÑее пÑиложение не Ð¼Ð¾Ð¶ÐµÑ Ð¾Ð±Ð½Ð°ÑÑжиÑÑ
          оÑибкÑ.

ÐÐ ÐÐÐÐ
       СледÑÑÑÐ°Ñ Ð¿ÑогÑамма демонÑÑÑиÑÑеÑ
       иÑполÑзование пÑогÑаммного инÑеÑÑейÑа
       fanotify. Ðна ÑÐ»ÐµÐ´Ð¸Ñ Ð·Ð° ÑоÑкой монÑиÑованиÑ,
       пеÑеданной в аÑгÑменÑе командной ÑÑÑоки, и
       ждÑÑ ÑобÑÑий Ñ Ñипом FAN_PERM_OPEN и FAN_CLOSE_WRITE. ÐÑи
       возникновении ÑобÑÑий доÑÑÑпа вÑдаÑÑ Ð¾ÑвеÑ
       FAN_ALLOW.

       СледÑÑÑий вÑвод запиÑан пÑи ÑедакÑиÑовании
       Ñайла /home/user/temp/notes. ÐеÑед оÑкÑÑÑием Ñайла
       пÑоизоÑло ÑобÑÑие FAN_OPEN_PERM. ÐоÑле закÑÑÑиÑ
       Ñайла пÑоизоÑло ÑобÑÑие FAN_CLOSE_WRITE.
       ÐÑполнение пÑогÑÐ°Ð¼Ð¼Ñ Ð·Ð°ÐºÐ¾Ð½ÑилоÑÑ Ð¿Ð¾Ñле
       нажаÑÐ¸Ñ Ð¿Ð¾Ð»ÑзоваÑелем клавиÑи ENTER.

   ÐÑÐ¸Ð¼ÐµÑ Ð²Ñвода
           # ./fanotify_example /home
           ÐажмиÑе enter Ð´Ð»Ñ Ð·Ð°Ð²ÐµÑÑÐµÐ½Ð¸Ñ ÑабоÑÑ.
           Ðжидание ÑобÑÑий.
           FAN_OPEN_PERM: Ñайл /home/user/temp/notes
           FAN_CLOSE_WRITE: Ñайл /home/user/temp/notes

           Ðжидание ÑобÑÑий пÑекÑаÑено.

   ÐÑÑоднÑй код пÑогÑаммÑ
       #define _GNU_SOURCE     /* ÑÑебÑеÑÑÑ Ð´Ð»Ñ Ð¿Ð¾Ð»ÑÑÐµÐ½Ð¸Ñ O_LARGEFILE */
       #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>

       /* ÑиÑаем вÑе доÑÑÑпнÑе ÑобÑÑÐ¸Ñ fanotify из Ñайлового деÑкÑипÑоÑа «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;

           /* пÑоÑодим по вÑем ÑобÑÑиÑм, коÑоÑÑе можем пÑоÑиÑаÑÑ
              из Ñайлового деÑкÑипÑоÑа fanotify */

           for(;;) {

               /* ÑиÑаем неÑколÑко ÑобÑÑий */

               len = read(fd, (void *) &buf, sizeof(buf));
               if (len == -1 && errno != EAGAIN) {
                   perror("read");
                   exit(EXIT_FAILURE);
               }

               /* пÑовеÑÑем, доÑÑигнÑÑ Ð»Ð¸ ÐºÐ¾Ð½ÐµÑ Ð´Ð¾ÑÑÑпнÑÑ Ð´Ð°Ð½Ð½ÑÑ */

               if (len <= 0)
                   break;

               /* вÑбиÑаем пеÑвое ÑобÑÑие в бÑÑеÑе */

               metadata = buf;

               /* пÑоÑодим по вÑем ÑобÑÑиÑм в бÑÑеÑе */

               while (FAN_EVENT_OK(metadata, len)) {

                   /* пÑовеÑÑем, ÑÑо ÑÑÑÑкÑÑÑÑ, иÑполÑзовавÑиеÑÑ Ð¿Ñи ÑбоÑке,
                      иденÑиÑÐ½Ñ ÑÑÑÑкÑÑÑам пÑи вÑполнении */

                   if (metadata->vers != FANOTIFY_METADATA_VERSION) {
                       fprintf(stderr,
                               "ÐеÑÑÐ¸Ñ Ð¼ÐµÑаданнÑÑ fanotify не ÑовпадаеÑ.\n");
                       exit(EXIT_FAILURE);
                   }

                   /* metadata->fd ÑодеÑÐ¶Ð¸Ñ Ð¸Ð»Ð¸ FAN_NOFD, ÑказÑваÑÑее
                      на пеÑеполнение оÑеÑеди, или ÑайловÑй деÑкÑипÑоÑ
                      (неоÑÑиÑаÑелÑное Ñелое). ÐдеÑÑ Ð¼Ñ Ð¿ÑоÑÑо игноÑиÑÑем
                      пеÑеполнение оÑеÑеди. */

                   if (metadata->fd >= 0) {

                       /* обÑабаÑÑваем ÑобÑÑие на пÑаво оÑкÑÑÑÐ¸Ñ */

                       if (metadata->mask & FAN_OPEN_PERM) {
                           printf("FAN_OPEN_PERM: ");

                           /* ÑазÑеÑаем оÑкÑÑÑÑ Ñайл */

                           response.fd = metadata->fd;
                           response.response = FAN_ALLOW;
                           write(fd, &response,
                                 sizeof(struct fanotify_response));
                       }

                       /* обÑабаÑÑваем ÑобÑÑие закÑÑÑÐ¸Ñ Ð·Ð°Ð¿Ð¸ÑÑваемого Ñайла */

                       if (metadata->mask & FAN_CLOSE_WRITE)
                           printf("FAN_CLOSE_WRITE: ");

                       /* полÑÑаем и вÑводим Ð¸Ð¼Ñ Ñайла, к коÑоÑомÑ
                          оÑÑлеживаеÑÑÑ Ð´Ð¾ÑÑÑп */

                       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("Ñайл %s\n", path);

                       /* закÑÑваем ÑайловÑй деÑкÑипÑÐ¾Ñ Ð¸Ð· ÑобÑÑÐ¸Ñ */

                       close(metadata->fd);
                   }

                   /* пеÑеÑодим на ÑледÑÑÑее ÑобÑÑие */

                   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];

           /* пÑовеÑÑем заданнÑÑ ÑоÑÐºÑ Ð¼Ð¾Ð½ÑиÑÐ¾Ð²Ð°Ð½Ð¸Ñ */

           if (argc != 2) {
               fprintf(stderr, "ÐÑполÑзование: %s ТÐЧÐÐ_ÐÐÐТÐÐ ÐÐÐÐÐЯ\n",
                                               argv[0]);
               exit(EXIT_FAILURE);
           }

           printf("ÐажмиÑе enter Ð´Ð»Ñ Ð·Ð°Ð²ÐµÑÑÐµÐ½Ð¸Ñ ÑабоÑÑ.\n");

           /* СоздаÑм ÑайловÑй деÑкÑипÑÐ¾Ñ Ð´Ð»Ñ Ð´Ð¾ÑÑÑпа к 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);
           }

           /* ÐомеÑаем ÑоÑÐºÑ Ð¼Ð¾Ð½ÑиÑÐ¾Ð²Ð°Ð½Ð¸Ñ Ð´Ð»Ñ:
              - ÑобÑÑий доÑÑÑпа пеÑед оÑкÑÑÑием Ñайлов
              - ÑобÑÑий ÑÐ²ÐµÐ´Ð¾Ð¼Ð»ÐµÐ½Ð¸Ñ Ð¿Ð¾Ñле закÑÑÑÐ¸Ñ Ñайлового деÑкÑипÑоÑа
                Ð´Ð»Ñ Ñайла оÑкÑÑÑого Ð´Ð»Ñ Ð·Ð°Ð¿Ð¸Ñи */

           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);
           }

           /* подгоÑовка к опÑоÑÑ */

           nfds = 2;

           /* ввод Ñ ÐºÐ¾Ð½Ñоли  */

           fds[0].fd = STDIN_FILENO;
           fds[0].events = POLLIN;

           /* ввод из fanotify */

           fds[1].fd = fd;
           fds[1].events = POLLIN;

           /* Ñикл Ð¾Ð¶Ð¸Ð´Ð°Ð½Ð¸Ñ Ð²ÑодÑÑÐ¸Ñ ÑобÑÑий */

           printf("Ðжидание ÑобÑÑий.\n");

           while (1) {
               poll_num = poll(fds, nfds, -1);
               if (poll_num == -1) {
                   if (errno == EINTR)     /* пÑеÑвано Ñигналом */
                       continue;           /* пеÑезапÑÑк poll() */

                   perror("poll");         /* Ð½ÐµÐ¾Ð¶Ð¸Ð´Ð°Ð½Ð½Ð°Ñ Ð¾Ñибка */
                   exit(EXIT_FAILURE);
               }

               if (poll_num > 0) {
                   if (fds[0].revents & POLLIN) {

                       /* доÑÑÑпен ввод Ñ ÐºÐ¾Ð½Ñоли: опÑÑÑоÑаем stdin и вÑÑодим */

                       while (read(STDIN_FILENO, &buf, 1) > 0 && buf != '\n')
                           continue;
                       break;
                   }

                   if (fds[1].revents & POLLIN) {

                       /* доÑÑÑÐ¿Ð½Ñ ÑобÑÑÐ¸Ñ fanotify */

                       handle_events(fd);
                   }
               }
           }

           printf("Ðжидание ÑобÑÑий пÑекÑаÑено.\n");
           exit(EXIT_SUCCESS);
       }

СÐÐТРÐТРТÐÐÐÐ
       fanotify_init(2), fanotify_mark(2), inotify(7)



Linux                             2016-03-15                       FANOTIFY(7)