inotify

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



ÐÐЯ
       inotify - наблÑÐ´Ð°ÐµÑ Ð·Ð° ÑобÑÑиÑми Ñайловой
       ÑиÑÑемÑ

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

       РпÑогÑаммнÑй инÑеÑÑÐµÐ¹Ñ Ð²ÑодÑÑ ÑледÑÑÑие
       ÑиÑÑемнÑе вÑзовÑ:

       *  ÐÑзов inotify_init(2) ÑоздаÑÑ ÑкземплÑÑ inotify и
          возвÑаÑÐ°ÐµÑ ÑайловÑй деÑкÑипÑоÑ, ÑÑÑлаÑÑийÑÑ
          на ÑкземплÑÑ inotify. Ðолее новÑй inotify_init1(2)
          подобен inotify_init(2), но Ð¸Ð¼ÐµÐµÑ Ð°ÑгÑÐ¼ÐµÐ½Ñ flags,
          коÑоÑÑй пÑедоÑÑавлÑÐµÑ Ð´Ð¾ÑÑÑп к некоÑоÑÑм
          дополниÑелÑнÑм возможноÑÑÑм.

       *  ÐÑзов inotify_add_watch(2) изменÑÐµÑ Â«ÑпиÑок
          наблÑдениÑ», ÑвÑзаннÑй Ñ ÑкземплÑÑом inotify.
          ÐаждÑй ÑÐ»ÐµÐ¼ÐµÐ½Ñ (ÑÑоÑожок (watch)) в ÑпиÑке
          задаÑÑ Ð¿ÑÑÑ Ðº ÑÐ°Ð¹Ð»Ñ Ð¸Ð»Ð¸ каÑÐ°Ð»Ð¾Ð³Ñ Ð¸
          некоÑоÑÑй Ð½Ð°Ð±Ð¾Ñ ÑобÑÑий, коÑоÑÑе ÑдÑо
          должно оÑÑлеживаÑÑ Ð´Ð»Ñ Ñайла, на коÑоÑÑй
          ÑказÑÐ²Ð°ÐµÑ ÑÑÐ¾Ñ Ð¿ÑÑÑ. ÐÑзов inotify_add_watch(2) или
          ÑоздаÑÑ Ð½Ð¾Ð²Ñй ÑÑоÑожок, или изменÑеÑ
          ÑÑÑеÑÑвÑÑÑий. ÐаждÑй ÑÑоÑожок имееÑ
          ÑникалÑнÑй «деÑкÑипÑÐ¾Ñ ÑÑоÑожка» â Ñелое
          ÑиÑло, возвÑаÑаемое inotify_add_watch(2) пÑи
          Ñоздании ÑÑоÑожка.

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

       *  ÐÑзов inotify_rm_watch(2) ÑдалÑÐµÑ ÑÐ»ÐµÐ¼ÐµÐ½Ñ Ð¸Ð·
          ÑпиÑка наблÑÐ´ÐµÐ½Ð¸Ñ inotify.

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

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

   ЧÑение ÑобÑÑий из Ñайлового деÑкÑипÑоÑа inotify
       ЧÑÐ¾Ð±Ñ Ð¾Ð¿ÑеделиÑÑ, ÑÑо ÑобÑÑÐ¸Ñ Ð¿ÑоизоÑли,
       пÑиложение должно пÑоÑиÑаÑÑ (read(2)) ÑайловÑй
       деÑкÑипÑÐ¾Ñ inotify. ÐÑли ÑобÑÑий не бÑло, Ñо
       пÑедполагаÑ, ÑÑо ÑÑо блокиÑÑÑÑий ÑайловÑй
       деÑкÑипÑоÑ, вÑзов read(2) заблокиÑÑÐµÑ ÑабоÑÑ Ð´Ð¾
       возникновениÑ, по кÑайней меÑе, одного
       ÑобÑÑÐ¸Ñ (еÑли не бÑÐ´ÐµÑ Ð¿ÑеÑван Ñигналом; в
       ÑÑом ÑлÑÑае вÑзов завеÑÑаеÑÑÑ Ñ Ð¾Ñибкой EINTR,
       ÑмоÑÑиÑе signal(7)).

       ÐÑи ÑÑпеÑном вÑполнении read(2) возвÑаÑаеÑ
       бÑÑÐµÑ Ñ Ð¾Ð´Ð½Ð¾Ð¹ или более ÑÑÑÑкÑÑÑами ÑледÑÑÑего
       вида:

           struct inotify_event {
               int      wd;       /* деÑкÑипÑÐ¾Ñ Ð½Ð°Ð±Ð»Ñдаемого */
               uint32_t mask;     /* маÑка, опиÑÑваÑÑÐ°Ñ ÑобÑÑие */
               uint32_t cookie;   /* ÑникалÑнÑй cookie, ÑвÑзÑваÑÑий оÑноÑÑÑиеÑÑ
                                     дÑÑг к дÑÑÐ³Ñ ÑобÑÑÐ¸Ñ (Ð´Ð»Ñ rename(2)) */
               uint32_t len;      /* ÑÐ°Ð·Ð¼ÐµÑ Ð¿Ð¾Ð»Ñ name */
               char     name[];   /* необÑзаÑелÑное имÑ, завеÑÑаÑÑееÑÑ null */
           };

       Ð wd ÑказÑваеÑÑÑ ÑÑоÑожок, к коÑоÑÐ¾Ð¼Ñ Ð¾ÑноÑиÑÑÑ
       ÑобÑÑие. ÐÑо один из деÑкÑипÑоÑов ÑÑоÑожка,
       полÑÑеннÑй из вÑзова inotify_add_watch(2).

       Ð mask ÑодеÑжаÑÑÑ Ð±Ð¸ÑÑ, опиÑÑваÑÑие возникÑее
       ÑобÑÑие (ÑмоÑÑиÑе ниже).

       ÐнаÑение cookie â ÑÑо ÑникалÑное Ñелое, коÑоÑое
       обÑединÑÐµÑ ÑвÑзаннÑе ÑобÑÑиÑ. РнаÑÑоÑÑее вÑемÑ
       иÑполÑзÑеÑÑÑ ÑолÑко Ð´Ð»Ñ ÑобÑÑий
       пеÑÐµÐ¸Ð¼ÐµÐ½Ð¾Ð²Ð°Ð½Ð¸Ñ Ð¸ позволÑÐµÑ Ð¿ÑиложениÑ
       обÑединиÑÑ Ð²Ð¾Ð·Ð²ÑаÑаемÑе IN_MOVED_FROM и IN_MOVED_TO в
       паÑÑ ÑобÑÑий. ÐÐ»Ñ Ð¾ÑÑалÑнÑÑ Ñипов ÑобÑÑий
       знаÑение cookie Ñавно 0.

       Ðоле name ÑÑÑеÑÑвÑÐµÑ ÑолÑко когда ÑобÑÑие
       возвÑаÑаеÑÑÑ Ð´Ð»Ñ Ñайла внÑÑÑи
       оÑÑлеживаемого каÑалога; им опÑеделÑеÑÑÑ
       Ð¸Ð¼Ñ Ñайла внÑÑÑи оÑÑлеживаемого каÑалога.
       ÐÑо Ð¸Ð¼Ñ Ð·Ð°Ð²ÐµÑÑаеÑÑÑ null и Ð¼Ð¾Ð¶ÐµÑ Ð²ÐºÐ»ÑÑаÑÑ
       дополниÑелÑнÑе байÑÑ null («\0») длÑ
       вÑÑÐ°Ð²Ð½Ð¸Ð²Ð°Ð½Ð¸Ñ Ð½Ð° подÑодÑÑÑÑ Ð³ÑаниÑÑ Ð°Ð´ÑеÑа пÑи
       поÑледÑÑÑÐ¸Ñ Ð¾Ð¿ÐµÑаÑий ÑÑениÑ.

       Ðоле len ÑодеÑÐ¶Ð¸Ñ ÐºÐ¾Ð»Ð¸ÑеÑÑво вÑÐµÑ Ð±Ð°Ð¹Ñ Ð² name,
       вклÑÑÐ°Ñ Ð±Ð°Ð¹ÑÑ null; длина каждой ÑÑÑÑкÑÑÑÑ
       inotify_event Ñавна sizeof(struct inotify_event)+len.

       ÐÑли бÑÑеÑ, заданнÑй в read(2), ÑлиÑком мал длÑ
       возвÑаÑа инÑоÑмаÑии о ÑледÑÑÑем ÑобÑÑии, Ñо
       поведение завиÑÐ¸Ñ Ð¾Ñ Ð²ÐµÑÑии ÑдÑа: в ÑдÑÐ°Ñ Ð´Ð¾
       веÑÑии 2.6.21, read(2) возвÑаÑÐ°ÐµÑ 0; наÑÐ¸Ð½Ð°Ñ Ñ
       веÑÑии 2.6.21, read(2) завеÑÑаеÑÑÑ Ñ Ð¾Ñибкой EINVAL.
       Указание ÑазмеÑа бÑÑеÑа

           sizeof(struct inotify_event) + NAME_MAX + 1

       бÑÐ´ÐµÑ Ð´Ð¾ÑÑаÑоÑно Ð´Ð»Ñ ÑÑениÑ, по кÑайней меÑе,
       одного ÑобÑÑиÑ.

   СобÑÑÐ¸Ñ inotify
       РаÑгÑменÑе inotify_add_watch(2) mask и поле mask ÑÑÑÑкÑÑÑÑ
       inotify_event, возвÑаÑаемÑÑ Ð¿Ñи ÑÑении Ñайлового
       деÑкÑипÑоÑа inotify, ÑодеÑжаÑÑÑ Ð±Ð¸ÑовÑе маÑки,
       опÑеделÑÑÑие ÑобÑÑÐ¸Ñ inotify. СледÑÑÑие биÑÑ
       могÑÑ Ð±ÑÑÑ Ð·Ð°Ð´Ð°Ð½Ñ Ð² mask пÑи вÑзове
       inotify_add_watch(2) и возвÑаÑÐµÐ½Ñ Ð² поле mask,
       возвÑаÑаемом read(2):

           IN_ACCESS (+)
                  ÐÑл пÑоизведÑн доÑÑÑп к ÑайлÑ
                  (напÑимеÑ, read(2), execve(2)).

           IN_ATTRIB (*)
                  ÐзменилиÑÑ Ð¼ÐµÑаданнÑе â напÑимеÑ,
                  пÑава доÑÑÑпа (напÑимеÑ, chmod(2)),
                  оÑмеÑки вÑемени (напÑимеÑ, utimensat(2)),
                  ÑаÑÑиÑеннÑе аÑÑибÑÑÑ (setxattr(2)), ÑÑÑÑÑик
                  ÑÑÑлок (наÑÐ¸Ð½Ð°Ñ Ñ Linux 2.6.25; напÑимеÑ,
                  Ð´Ð»Ñ Ð°ÑгÑменÑа назнаÑÐµÐ½Ð¸Ñ link(2) и
                  unlink(2)) и иденÑиÑикаÑоÑ
                  полÑзоваÑелÑ/гÑÑÐ¿Ð¿Ñ (напÑимеÑ, chown(2)).

           IN_CLOSE_WRITE (+)
                  Файл, оÑкÑÑÑÑй Ð´Ð»Ñ Ð·Ð°Ð¿Ð¸Ñи, бÑл закÑÑÑ.

           IN_CLOSE_NOWRITE (*)
                  Файл или каÑалог, не оÑкÑÑÑÑй длÑ
                  запиÑи, бÑл закÑÑÑ.

           IN_CREATE (+)
                  РоÑÑлеживаемом каÑалоге бÑл Ñоздан
                  Ñайл/каÑалог (напÑимеÑ, open(2) O_CREAT,
                  mkdir(2), link(2), symlink(2), bind(2) длÑ
                  доменного ÑокеÑа UNIX).

           IN_DELETE (+)
                  РоÑÑлеживаемом каÑалоге бÑл ÑдалÑн
                  Ñайл/каÑалог.

           IN_DELETE_SELF
                  ÐÑÑлеживаемÑй Ñайл/каÑалог бÑл
                  ÑдалÑн (ÑÑо ÑобÑÑие Ñакже возникаеÑ,
                  еÑли обÑÐµÐºÑ Ð¿ÐµÑемеÑÑн в дÑÑгÑÑ ÑайловÑÑ
                  ÑиÑÑемÑ, Ñак как mv(1), ÑакÑиÑеÑки,
                  копиÑÑÐµÑ Ñайл в дÑÑгÑÑ ÑайловÑÑ ÑиÑÑемÑ
                  и ÑдалÑÐµÑ ÐµÐ³Ð¾ из иÑÑодной). Также
                  заÑем бÑÐ´ÐµÑ Ñоздано ÑобÑÑие IN_IGNORED
                  Ð´Ð»Ñ Ð´ÐµÑкÑипÑоÑа ÑÑоÑожка.

           IN_MODIFY (+)
                  Файл бÑл изменÑн (напÑимеÑ, write(2),
                  truncate(2)).

           IN_MOVE_SELF
                  ÐÑÑлеживаемÑй Ñайл/каÑалог бÑл
                  пеÑемеÑÑн.

           IN_MOVED_FROM (+)
                  ÐÑи пеÑеименовании генеÑиÑÑеÑÑÑ Ð´Ð»Ñ
                  каÑалога, ÑодеÑжаÑего ÑÑаÑое имÑ
                  Ñайла.

           IN_MOVED_TO (+)
                  ÐÑи пеÑеименовании генеÑиÑÑеÑÑÑ Ð´Ð»Ñ
                  каÑалога, ÑодеÑжаÑего новое имÑ
                  Ñайла.

           IN_OPEN (*)
                  Файл или каÑалог бÑл оÑкÑÑÑ.

       ÐÑи наблÑдении за каÑалогом:

       *  ÑобÑÑиÑ, помеÑеннÑе звÑздоÑкой (*), могÑÑ
          возникаÑÑ ÐºÐ°Ðº Ð´Ð»Ñ Ñамого каÑалога, Ñак и
          Ð´Ð»Ñ Ñайлов в каÑалоге; и

       *  ÑобÑÑиÑ, помеÑеннÑе знаком плÑÑ (+), могÑÑ
          возникаÑÑ ÑолÑко Ð´Ð»Ñ Ð¾Ð±ÑекÑов внÑÑÑи
          каÑалога (но не Ñамого каÑалога).

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

       ÐакÑÐ¾Ñ IN_ALL_EVENTS опÑеделÑн как биÑÐ¾Ð²Ð°Ñ Ð¼Ð°Ñка
       вÑÐµÑ Ð¿ÐµÑеÑиÑленнÑÑ Ð²ÑÑе ÑобÑÑий. ÐаннÑй макÑоÑ
       можно иÑполÑзоваÑÑ Ð² каÑеÑÑве аÑгÑменÑа mask
       в вÑзове inotify_add_watch(2).

       ÐополниÑелÑно, два ÑдобнÑÑ Ð¼Ð°ÐºÑоÑа:

           IN_MOVE
                  То же, ÑÑо и IN_MOVED_FROM | IN_MOVED_TO.

           IN_CLOSE
                  То же, ÑÑо и IN_CLOSE_WRITE | IN_CLOSE_NOWRITE.

       Также, пÑи вÑзове inotify_add_watch(2) в mask могÑÑ
       бÑÑÑ ÑÐºÐ°Ð·Ð°Ð½Ñ ÑледÑÑÑие биÑÑ:

           IN_DONT_FOLLOW (наÑÐ¸Ð½Ð°Ñ Ñ Linux 2.6.15)
                  Ðе ÑазÑменовÑваÑÑ pathname, еÑли ÑÑо
                  ÑимволиÑеÑÐºÐ°Ñ ÑÑÑлка.

           IN_EXCL_UNLINK (наÑÐ¸Ð½Ð°Ñ Ñ Linux 2.6.36)
                  Ðо ÑмолÑаниÑ, пÑи Ñлежении за
                  ÑобÑÑиÑми Ð´Ð»Ñ Ð¿Ð¾Ñомков каÑалога,
                  ÑобÑÑÐ¸Ñ Ð³ÐµÐ½ÐµÑиÑÑÑÑÑÑ Ð´Ð»Ñ Ð¿Ð¾Ñомков даже
                  поÑле Ñого, как они бÑдÑÑ ÑÐ´Ð°Ð»ÐµÐ½Ñ Ð¸Ð·
                  каÑалога. ÐÑо Ð¼Ð¾Ð¶ÐµÑ Ð¿ÑивеÑÑи к
                  болÑÑÐ¾Ð¼Ñ ÐºÐ¾Ð»Ð¸ÑеÑÑÐ²Ñ Ð½ÐµÐ½ÑжнÑÑ Ð´Ð»Ñ
                  пÑÐ¸Ð»Ð¾Ð¶ÐµÐ½Ð¸Ñ ÑобÑÑий (напÑимеÑ, еÑли
                  ÑледиÑÑ Ð·Ð° /tmp, в коÑоÑом многие
                  пÑÐ¸Ð»Ð¾Ð¶ÐµÐ½Ð¸Ñ ÑоздаÑÑ Ð¸ ÑÑÐ°Ð·Ñ ÑдалÑÑÑ
                  вÑеменнÑе ÑайлÑ). Указание IN_EXCL_UNLINK
                  изменÑÐµÑ Ð¿Ð¾Ð²ÐµÐ´ÐµÐ½Ð¸Ðµ по ÑмолÑаниÑ, и
                  Ñакие ÑобÑÑÐ¸Ñ Ð½Ðµ генеÑиÑÑÑÑÑÑ Ð´Ð»Ñ
                  поÑомков поÑле ÑÐ´Ð°Ð»ÐµÐ½Ð¸Ñ Ð¸Ð·
                  оÑÑлеживаемого каÑалога.

           IN_MASK_ADD
                  ÐÑли ÑкземплÑÑ ÑÐ»ÐµÐ¶ÐµÐ½Ð¸Ñ Ñже ÑÑÑеÑÑвÑеÑ
                  Ð´Ð»Ñ Ð¾Ð±ÑекÑа Ñайловой ÑиÑÑемÑ
                  ÑооÑвеÑÑÑвÑÑÑего pathname, Ñо вÑполнÑÑÑ
                  добавление (OR) ÑобÑÑий в mask к маÑке
                  ÑÐ»ÐµÐ¶ÐµÐ½Ð¸Ñ (вмеÑÑо Ð·Ð°Ð¼ÐµÐ½Ñ Ð¼Ð°Ñки).

           IN_ONESHOT
                  ÐÑÑлеживаÑÑ Ð¾Ð±ÑÐµÐºÑ Ñайловой ÑиÑÑемÑ,
                  ÑооÑвеÑÑÑвÑÑÑий pathname до одного
                  ÑобÑÑиÑ, заÑем ÑдалиÑÑ Ð¾Ð±ÑÐµÐºÑ Ð¸Ð· ÑпиÑка
                  ÑлежениÑ.

           IN_ONLYDIR (наÑÐ¸Ð½Ð°Ñ Ñ Linux 2.6.15)
                  СледиÑÑ Ð·Ð° pathname, ÑолÑко еÑли ÑÑо
                  каÑалог. ÐÑÐ¾Ñ Ñлаг пÑедоÑÑавлÑеÑ
                  пÑÐ¸Ð»Ð¾Ð¶ÐµÐ½Ð¸Ñ Ð±ÐµÑÑоÑÑÑзаÑелÑнÑй ÑпоÑоб
                  ÑбедиÑÑÑÑ, ÑÑо оÑÑлеживаемÑй обÑÐµÐºÑ â
                  каÑалог.

       СледÑÑÑие биÑÑ Ð¼Ð¾Ð³ÑÑ Ð±ÑÑÑ ÑÑÑÐ°Ð½Ð¾Ð²Ð»ÐµÐ½Ñ Ð² поле
       mask пÑи возвÑаÑе из read(2):

           IN_IGNORED
                  Слежение бÑло ÑнÑÑо Ñвно
                  (inotify_rm_watch(2)) или авÑомаÑиÑеÑки (Ñайл
                  бÑл ÑдалÑн или ÑазмонÑиÑована
                  ÑÐ°Ð¹Ð»Ð¾Ð²Ð°Ñ ÑиÑÑема). Также ÑмоÑÑиÑе
                  ÐÐФÐÐТЫ.

           IN_ISDIR
                  ÐбÑÐµÐºÑ ÑÑого ÑобÑÑÐ¸Ñ â каÑалог.

           IN_Q_OVERFLOW
                  ÐеÑеполнена оÑеÑÐµÐ´Ñ ÑобÑÑий (Ð´Ð»Ñ ÑÑого
                  ÑобÑÑÐ¸Ñ Ð·Ð½Ð°Ñение wd Ñавно -1).

           IN_UNMOUNT
                  Ð¤Ð°Ð¹Ð»Ð¾Ð²Ð°Ñ ÑиÑÑема, ÑодеÑжаÑаÑ
                  оÑÑлеживаемÑй обÑекÑ, бÑла
                  ÑазмонÑиÑована. Также, бÑдеÑ
                  ÑгенеÑиÑовано ÑобÑÑие IN_IGNORED длÑ
                  деÑкÑипÑоÑа ÑÑоÑожка.

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

           fd = open("dir/myfile", O_RDWR);
                  ÐенеÑиÑÑеÑÑÑ ÑобÑÑие IN_OPEN и Ð´Ð»Ñ dir, и длÑ
                  dir/myfile.

           read(fd, buf, count);
                  ÐенеÑиÑÑеÑÑÑ ÑобÑÑие IN_ACCESS и Ð´Ð»Ñ dir, и
                  Ð´Ð»Ñ dir/myfile.

           write(fd, buf, count);
                  ÐенеÑиÑÑеÑÑÑ ÑобÑÑие IN_MODIFY и Ð´Ð»Ñ dir, и
                  Ð´Ð»Ñ dir/myfile.

           fchmod(fd, mode);
                  ÐенеÑиÑÑеÑÑÑ ÑобÑÑие IN_ATTRIB и Ð´Ð»Ñ dir, и
                  Ð´Ð»Ñ dir/myfile.

           close(fd);
                  ÐенеÑиÑÑеÑÑÑ ÑобÑÑие IN_CLOSE_WRITE и Ð´Ð»Ñ dir,
                  и Ð´Ð»Ñ dir/myfile.

       ÐÑедположим, пÑиложение ÑÐ»ÐµÐ´Ð¸Ñ Ð·Ð° вÑеми
       ÑобÑÑиÑми Ð´Ð»Ñ ÐºÐ°Ñалогов dir1 и dir2 и Ñайла
       dir1/myfile. РпÑимеÑе ниже Ð¿Ð¾ÐºÐ°Ð·Ð°Ð½Ñ Ð½ÐµÐºÐ¾ÑоÑÑе
       ÑобÑÑиÑ, коÑоÑÑе могÑÑ Ð±ÑÑÑ ÑгенеÑиÑованÑ.

           link("dir1/myfile", "dir2/new");
                  ÐенеÑиÑÑеÑÑÑ ÑобÑÑие IN_ATTRIB Ð´Ð»Ñ myfile и
                  ÑобÑÑие IN_CREATE Ð´Ð»Ñ dir2.

           rename("dir1/myfile", "dir2/myfile");
                  ÐенеÑиÑÑеÑÑÑ ÑобÑÑие IN_MOVED_FROM Ð´Ð»Ñ dir1,
                  ÑобÑÑие IN_MOVED_TO Ð´Ð»Ñ dir2 и ÑобÑÑие
                  IN_MOVE_SELF Ð´Ð»Ñ myfile. СобÑÑÐ¸Ñ IN_MOVED_FROM и
                  IN_MOVED_TO бÑдÑÑ ÑодеÑжаÑÑ Ð¾Ð´Ð¸Ð½Ð°ÐºÐ¾Ð²Ð¾Ðµ
                  знаÑение cookie.

       ÐÑедположим, ÑÑо dir1/xx и dir2/yy ÑолÑко ÑÑÑлки на
       один Ñайл и пÑиложение ÑÐ»ÐµÐ´Ð¸Ñ Ð·Ð° dir1, dir2,
       dir1/xx и dir2/yy. ÐÑи вÑполнение ÑледÑÑÑиÑ
       вÑзовов в поÑÑдке, Ñказанном ниже, бÑдÑÑ
       ÑгенеÑиÑÐ¾Ð²Ð°Ð½Ñ ÑледÑÑÑие ÑобÑÑиÑ:

           unlink("dir2/yy");
                  ÐенеÑиÑÑеÑÑÑ ÑобÑÑие IN_ATTRIB Ð´Ð»Ñ xx (Ñак
                  как изменилÑÑ ÐµÐ³Ð¾ ÑÑÑÑÑик ÑÑÑлок) и
                  ÑобÑÑие IN_DELETE Ð´Ð»Ñ dir2.

           unlink("dir1/xx");
                  ÐенеÑиÑÑеÑÑÑ ÑобÑÑие IN_ATTRIB, IN_DELETE_SELF и
                  IN_IGNORED Ð´Ð»Ñ xx и ÑобÑÑие IN_DELETE Ð´Ð»Ñ dir1.

       ÐÑедположим, пÑиложение ÑÐ»ÐµÐ´Ð¸Ñ Ð·Ð°
       каÑалогом dir и пÑÑÑÑм каÑалогом dir/subdir. Ð
       пÑимеÑе ниже Ð¿Ð¾ÐºÐ°Ð·Ð°Ð½Ñ Ð½ÐµÐºÐ¾ÑоÑÑе ÑобÑÑиÑ,
       коÑоÑÑе могÑÑ Ð±ÑÑÑ ÑгенеÑиÑованÑ.

           mkdir("dir/new", mode);
                  ÐенеÑиÑÑеÑÑÑ ÑобÑÑие IN_CREATE | IN_ISDIR длÑ
                  dir.

           rmdir("dir/subdir");
                  ÐенеÑиÑÑÑÑÑÑ ÑобÑÑÐ¸Ñ IN_DELETE_SELF и IN_IGNORED
                  Ð´Ð»Ñ subdir и ÑобÑÑие IN_DELETE | IN_ISDIR Ð´Ð»Ñ dir.

   ÐнÑеÑÑейÑÑ Ð² /proc
       ÐÐ»Ñ Ð¾Ð³ÑаниÑÐµÐ½Ð¸Ñ Ð¿Ð¾ÑÑÐµÐ±Ð»ÐµÐ½Ð¸Ñ inotify памÑÑи ÑдÑа,
       можно иÑполÑзоваÑÑ ÑледÑÑÑие инÑеÑÑейÑÑ:

       /proc/sys/fs/inotify/max_queued_events
              ÐнаÑение в ÑÑом Ñайле иÑполÑзÑеÑÑÑ ÐºÐ¾Ð³Ð´Ð°
              пÑиложение вÑзÑÐ²Ð°ÐµÑ inotify_init(2) длÑ
              ÑÑÑановки веÑÑнего поÑога колиÑеÑÑва
              ÑобÑÑий, коÑоÑÑе могÑÑ Ð¿Ð¾Ð¼ÐµÑÑиÑÑÑÑ Ð²
              оÑеÑÐµÐ´Ñ ÑооÑвеÑÑÑвÑÑÑего ÑкземплÑÑа inotify.
              СобÑÑиÑ, пÑевÑÑивÑие ÑÑо огÑаниÑение,
              оÑбÑаÑÑваÑÑÑÑ, но ÑобÑÑие IN_Q_OVERFLOW
              генеÑиÑÑеÑÑÑ Ð²Ñегда.

       /proc/sys/fs/inotify/max_user_instances
              Ð ÑÑом Ñайле задаÑÑÑÑ Ð¾Ð³ÑаниÑение на
              колиÑеÑÑво ÑкземплÑÑов inotify, коÑоÑÑе
              могÑÑ Ð±ÑÑÑ ÑÐ¾Ð·Ð´Ð°Ð½Ñ Ð´Ð»Ñ Ð¾Ð´Ð½Ð¾Ð³Ð¾ ÑеалÑного
              иденÑиÑикаÑоÑа полÑзоваÑелÑ.

       /proc/sys/fs/inotify/max_user_watches
              Ð ÑÑом Ñайле задаÑÑÑÑ Ð¾Ð³ÑаниÑение на
              колиÑеÑÑво ÑÑоÑожков, коÑоÑÑе могÑÑ Ð±ÑÑÑ
              ÑÐ¾Ð·Ð´Ð°Ð½Ñ Ð´Ð»Ñ Ð¾Ð´Ð½Ð¾Ð³Ð¾ ÑеалÑного
              иденÑиÑикаÑоÑа полÑзоваÑелÑ.

ÐÐРСÐÐ
       ÐÑогÑаммнÑй инÑеÑÑÐµÐ¹Ñ inotify бÑл добавлен в
       ÑдÑо Linux веÑÑии 2.6.13. ÐеобÑодимÑе
       библиоÑеÑнÑе инÑеÑÑейÑÑ Ð´Ð¾Ð±Ð°Ð²Ð»ÐµÐ½Ñ Ð² glibc
       веÑÑии 2.4 (IN_DONT_FOLLOW, IN_MASK_ADD и IN_ONLYDIR
       Ð´Ð¾Ð±Ð°Ð²Ð»ÐµÐ½Ñ Ð² glibc веÑÑии 2.5).

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

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

       ÐаÑÐ¸Ð½Ð°Ñ Ñ Linux 2.6.25, Ð´Ð»Ñ ÑайловÑÑ Ð´ÐµÑкÑипÑоÑов
       inotify ÑÑали доÑÑÑÐ¿Ð½Ñ ÑведомлениÑ
       ввода-вÑвода поÑÑедÑÑвом Ñигналов; ÑмоÑÑиÑе
       обÑÑждение F_SETFL (Ð´Ð»Ñ ÑÑÑановки Ñлага O_ASYNC),
       F_SETOWN и F_SETSIG в fcntl(2). СÑÑÑкÑÑÑа siginfo_t (опиÑана
       в sigaction(2)), пеÑÐµÐ´Ð°Ð²Ð°ÐµÐ¼Ð°Ñ Ð¾Ð±ÑабоÑÑикÑ
       Ñигнала, ÑодеÑÐ¶Ð¸Ñ ÑледÑÑÑие наÑÑÑойки полей:
       в si_fd ÑказÑваеÑÑÑ Ð½Ð¾Ð¼ÐµÑ Ñайлового
       деÑкÑипÑоÑа inotify; в si_signo ÑказÑваеÑÑÑ Ð½Ð¾Ð¼ÐµÑ
       Ñигнала; в si_code ÑказÑваеÑÑÑ POLL_IN; в si_band
       ÑказÑваеÑÑÑ POLLIN.

       ÐÑли поÑледÑÑÑие ÑобÑÑÐ¸Ñ inotify, вÑводимÑе в
       ÑайловÑй деÑкÑипÑÐ¾Ñ inotify, одинаковÑ
       (ÑодеÑÐ¶Ð°Ñ Ð¾Ð´Ð¸Ð½Ð°ÐºÐ¾Ð²Ñе знаÑÐµÐ½Ð¸Ñ wd, mask, cookie и
       name), Ñо они ÑливаÑÑÑÑ Ð² одно ÑобÑÑие, еÑли
       Ñамое ÑÑаÑое ÑобÑÑие еÑÑ Ð½Ðµ пÑоÑиÑано (но
       ÑмоÑÑиÑе ÐÐФÐÐТЫ). ÐÑо ÑокÑаÑÐ°ÐµÑ ÑÑебÑемое
       колиÑеÑÑво памÑÑи ÑдÑа Ð´Ð»Ñ Ð¾ÑеÑеди ÑобÑÑий,
       но Ñакже ознаÑаеÑ, ÑÑо пÑиложение не можеÑ
       иÑполÑзоваÑÑ inotify Ð´Ð»Ñ Ð½Ð°Ð´Ñжного подÑÑÑÑа
       ÑайловÑÑ ÑобÑÑий.

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

       ÐÐ°Ð±Ð¾Ñ Ð½Ð°Ð±Ð»ÑдаемÑÑ Ð´ÐµÑкÑипÑоÑов, коÑоÑÑе
       оÑÑлеживаÑÑÑÑ ÑеÑез ÑайловÑй деÑкÑипÑÐ¾Ñ inotify,
       можно ÑвидеÑÑ Ð¸Ð· запиÑи Ð´Ð»Ñ Ñайлового
       деÑкÑипÑоÑа inotify в каÑалоге пÑоÑеÑÑа
       /proc/[pid]/fdinfo. ÐополниÑелÑнÑÑ Ð¸Ð½ÑоÑмаÑиÑ
       ÑмоÑÑиÑе в proc(5). ÐÑзов FIONREAD ioctl(2) возвÑаÑаеÑ
       колиÑеÑÑво байÑ, доÑÑÑпнÑÑ Ð´Ð»Ñ ÑÑÐµÐ½Ð¸Ñ Ð¸Ð·
       Ñайлового деÑкÑипÑоÑа inotify.

   ÐгÑаниÑÐµÐ½Ð¸Ñ Ð¸ подводнÑе камни
       ÐÑогÑаммнÑй инÑеÑÑÐµÐ¹Ñ inotify не пÑедоÑÑавлÑеÑ
       инÑоÑмаÑÐ¸Ñ Ð¾ полÑзоваÑеле или пÑоÑеÑÑе,
       из-за коÑоÑого возникло ÑобÑÑие. Ð ÑаÑÑноÑÑи,
       Ð´Ð»Ñ Ð¿ÑоÑеÑÑа, оÑÑлеживаÑÑего ÑобÑÑÐ¸Ñ ÑеÑез
       inotify, Ð½ÐµÑ Ð¿ÑоÑÑого ÑпоÑоба опÑеделиÑÑ,
       возникли ÑобÑÑÐ¸Ñ Ð¸Ð·-за его дейÑÑвий или
       из-за дейÑÑвий дÑÑÐ³Ð¸Ñ Ð¿ÑоÑеÑÑов.

       Inotify ÑообÑÐ°ÐµÑ ÑолÑко о ÑобÑÑиÑÑ, коÑоÑÑе
       возникли из-за полÑзоваÑелÑÑÐºÐ¸Ñ Ð¿ÑогÑамм,
       иÑполÑзовавÑÐ¸Ñ Ð¿ÑогÑаммнÑй инÑеÑÑейÑ
       Ñайловой ÑиÑÑемÑ. То еÑÑÑ, не возникаеÑ
       ÑобÑÑий Ð´Ð»Ñ ÑайловÑÑ ÑиÑÑем, доÑÑÑпнÑÑ Ð¿Ð¾ ÑеÑи
       (пÑÐ¸Ð»Ð¾Ð¶ÐµÐ½Ð¸Ñ Ð´Ð¾Ð»Ð¶Ð½Ñ Ð¸ÑполÑзоваÑÑ ÑÑаÑÑй меÑод
       опÑоÑа Ñайловой ÑиÑÑÐµÐ¼Ñ Ð´Ð»Ñ ÑÐ»ÐµÐ¶ÐµÐ½Ð¸Ñ Ð·Ð°
       Ñакими ÑобÑÑиÑми). ÐÑоме Ñого, ÑазлиÑнÑе
       пÑевдо-ÑайловÑй ÑиÑÑемÑ, Ñакие как /proc, /sys и
       /dev/pts, не оÑÑлеживаÑÑÑÑ ÑеÑез inotify.

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

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

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

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

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

       ÐамеÑим, ÑÑо оÑеÑÐµÐ´Ñ ÑобÑÑий можеÑ
       пеÑеполниÑÑÑÑ. Ð ÑÑом ÑлÑÑае ÑобÑÑÐ¸Ñ ÑеÑÑÑÑÑÑ.
       ÐоÑÑекÑнÑе пÑÐ¸Ð»Ð¾Ð¶ÐµÐ½Ð¸Ñ Ð´Ð¾Ð»Ð¶Ð½Ñ ÑÑиÑÑваÑÑ
       возможноÑÑÑ Ð¿Ñопажи ÑобÑÑий. ÐапÑимеÑ, можеÑ
       поÑÑебоваÑÑÑÑ Ð¿ÐµÑеÑÑÑоиÑÑ ÑаÑÑÑ Ð¸Ð»Ð¸ веÑÑ ÐºÑÑ
       пÑÐ¸Ð»Ð¾Ð¶ÐµÐ½Ð¸Ñ (один пÑоÑÑой, но, возможно,
       заÑÑаÑнÑй ÑпоÑоб, ÑÑо закÑÑÑÑ ÑайловÑй
       деÑкÑипÑÐ¾Ñ inotify, опÑÑÑоÑиÑÑ ÐºÑÑ, ÑоздаÑÑ Ð½Ð¾Ð²Ñй
       ÑайловÑй деÑкÑипÑÐ¾Ñ inotify и заÑем пеÑеÑоздаÑÑ
       ÑÑоÑожки и запиÑи в кÑÑе Ð´Ð»Ñ Ð¾ÑÑлеживаемÑÑ
       обÑекÑов).

   РабоÑа Ñ ÑобÑÑиÑми rename()
       Ðак ÑказÑвалоÑÑ Ð²ÑÑе, из ÑобÑÑий IN_MOVED_FROM и
       IN_MOVED_TO, генеÑиÑÑемÑÑ rename(2), можно
       опÑеделиÑÑ Ð¿Ð°ÑÑ Ð¿Ð¾ Ð¸Ñ Ð¾Ð´Ð¸Ð½Ð°ÐºÐ¾Ð²Ð¾Ð¼Ñ Ð·Ð½Ð°ÑениÑ
       cookie. Ðднако, Ñ ÑÑой задаÑей еÑÑÑ Ð½ÐµÑколÑко
       пÑоблем.

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

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

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

ÐÐФÐÐТЫ
       Ðо Linux 3.19, fallocate(2) не Ñоздавал ÑобÑÑÐ¸Ñ inotify.
       ÐаÑÐ¸Ð½Ð°Ñ Ñ Linux 3.19, вÑзов fallocate(2) генеÑиÑÑеÑ
       ÑобÑÑие IN_MODIFY.

       Ð ÑдÑÐ°Ñ Ð´Ð¾ 2.6.16 Ñлаг IN_ONESHOT в mask не ÑабоÑаеÑ.

       РпеÑвонаÑалÑной задÑмке и ÑеализаÑии Ñлаг
       IN_ONESHOT не пÑиводил к генеÑаÑии ÑобÑÑиÑ
       IN_IGNORED, еÑли наблÑдение оÑменÑлоÑÑ Ð¿Ð¾Ñле
       одного ÑобÑÑиÑ. Ðднако, как
       непÑеднамеÑеннÑй ÑÑÑÐµÐºÑ Ð´ÑÑÐ³Ð¸Ñ Ð¸Ð·Ð¼ÐµÐ½ÐµÐ½Ð¸Ð¹,
       наÑÐ¸Ð½Ð°Ñ Ñ Linux 2.6.36, ÑобÑÑие IN_IGNORED в ÑÑом ÑлÑÑае
       генеÑиÑÑеÑÑÑ.

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

       Ðогда деÑкÑипÑÐ¾Ñ ÑÑоÑожка ÑдалÑеÑÑÑ Ð²Ñзовом
       inotify_rm_watch(2) (или из-за ÑдалениÑ
       оÑÑлеживаемого Ñайла, или ÑазмонÑиÑованиÑ
       ÑодеÑжаÑей его Ñайловой ÑиÑÑемÑ), вÑе
       ожидаÑÑие непÑоÑиÑаннÑе ÑобÑÑÐ¸Ñ Ð´Ð»Ñ ÑÑого
       деÑкÑипÑоÑа ÑÑоÑожка оÑÑаÑÑÑÑ Ð´Ð¾ÑÑÑпнÑми длÑ
       ÑÑениÑ. Так как деÑкÑипÑоÑÑ ÑÑоÑожков в
       далÑнейÑем ÑиклиÑеÑки вÑделÑÑÑÑÑ
       inotify_add_watch(2), ÑдÑо поÑÑÑпаÑелÑно пÑоÑодиÑ
       ÑеÑез диапазон возможнÑÑ Ð´ÐµÑкÑипÑоÑов
       ÑÑоÑожков (Ð¾Ñ 0 до INT_MAX). ÐÑи вÑделении
       Ñвободного деÑкÑипÑоÑа ÑÑоÑожка длÑ
       вÑбÑанного номеÑа не пÑоизводиÑÑÑ Ð¿ÑовеÑка
       Ñого, еÑÑÑ Ð»Ð¸ какие-Ñо ожидаÑÑие
       непÑоÑиÑаннÑе ÑобÑÑÐ¸Ñ Ð² оÑеÑеди inotify Ñ Ñаким
       номеÑом или неÑ. То еÑÑÑ Ð¼Ð¾Ð¶ÐµÑ ÑлÑÑиÑÑÑÑ Ñак,
       ÑÑо деÑкÑипÑÐ¾Ñ ÑÑоÑожка вÑделÑеÑÑÑ Ð¿Ð¾Ð²ÑоÑно
       даже когда ÑÑÑеÑÑвÑÑÑ Ð¾Ð¶Ð¸Ð´Ð°ÑÑие
       непÑоÑиÑаннÑе ÑобÑÑиÑ, оÑÑавÑиеÑÑ Ð¾Ñ
       пÑедÑдÑÑего вÑÐ´ÐµÐ»ÐµÐ½Ð¸Ñ Ð´ÐµÑкÑипÑоÑа ÑÑоÑожка Ñ
       Ñем же номеÑом; в ÑезÑлÑÑаÑе пÑиложение
       Ð¼Ð¾Ð¶ÐµÑ Ð¿ÑоÑеÑÑÑ ÑÑи ÑобÑÑÐ¸Ñ Ð¸ поÑÑиÑаÑÑ Ð¸Ñ ÐºÐ°Ðº
       пÑинадлежаÑие ÑайлÑ, ÑвÑÐ·Ð°Ð½Ð½Ð¾Ð¼Ñ Ñ Ð½Ð¾Ð²Ñм
       повÑоÑно задейÑÑвованнÑм деÑкÑипÑоÑом
       ÑÑоÑожка. Ðа пÑакÑике, веÑоÑÑноÑÑÑ
       ÑÑÐ¾Ð»ÐºÐ½Ð¾Ð²ÐµÐ½Ð¸Ñ Ñ ÑÑой оÑибкой Ð¼Ð¾Ð¶ÐµÑ Ð±ÑÑÑ
       ÑÑезвÑÑайно низка, Ñак как Ð´Ð»Ñ ÑÑого
       ÑÑебÑеÑÑÑ, ÑÑÐ¾Ð±Ñ Ð¿ÑÐ¸Ð»Ð¾Ð¶ÐµÐ½Ð¸Ñ ÑиклиÑеÑки
       пеÑебÑало вÑе INT_MAX деÑкÑипÑоÑов ÑÑоÑожков,
       оÑвободило деÑкÑипÑÐ¾Ñ ÑÑоÑожка и оÑÑавило
       непÑоÑиÑаннÑе ÑобÑÑÐ¸Ñ ÑÑого деÑкÑипÑоÑа
       ÑÑоÑожка в оÑеÑеди, а заÑем повÑоÑно
       задейÑÑвовало ÑÑÐ¾Ñ Ð´ÐµÑкÑипÑÐ¾Ñ ÑÑоÑожка. Ðо
       ÑÑой пÑиÑине и из-за Ñого, ÑÑо еÑÑ Ð½Ð¸ÐºÑо не
       ÑообÑал об ÑÑой оÑибке в ÑеалÑноÑÑи, на
       Ð¼Ð¾Ð¼ÐµÐ½Ñ Ð°ÐºÑÑалÑноÑÑи Linux 3.15, в ÑдÑе ниÑего не
       бÑло Ñделано Ð´Ð»Ñ Ñого, ÑÑÐ¾Ð±Ñ ÑÑÑÑаниÑÑ ÑÑоÑ
       деÑекÑ.

ÐÐ ÐÐÐÐ
       СледÑÑÑÐ°Ñ Ð¿ÑогÑамма демонÑÑÑиÑÑеÑ
       иÑполÑзование пÑогÑаммного инÑеÑÑейÑа
       inotify. Ðна помеÑÐ°ÐµÑ ÐºÐ°Ñалоги, пеÑеданной в
       аÑгÑменÑÐ°Ñ ÐºÐ¾Ð¼Ð°Ð½Ð´Ð½Ð¾Ð¹ ÑÑÑоки, и ждÑÑ ÑобÑÑий Ñ
       Ñипом IN_OPEN, IN_CLOSE_NOWRITE и IN_CLOSE_WRITE.

       СледÑÑÑий вÑвод бÑл запиÑан пÑи
       ÑедакÑиÑовании Ñайла /home/user/temp/foo и
       пÑоÑмоÑÑа каÑалога /tmp. ÐеÑед оÑкÑÑÑием Ñайла
       и каÑалога пÑоизоÑли ÑобÑÑÐ¸Ñ IN_OPEN. ÐоÑле
       закÑÑÑÐ¸Ñ Ñайла пÑоизоÑло ÑобÑÑие IN_CLOSE_WRITE.
       ÐоÑле закÑÑÑÐ¸Ñ ÐºÐ°Ñалога пÑоизоÑло ÑобÑÑие
       IN_CLOSE_NOWRITE. ÐÑполнение пÑогÑаммÑ
       законÑилоÑÑ Ð¿Ð¾Ñле нажаÑÐ¸Ñ Ð¿Ð¾Ð»ÑзоваÑелем
       клавиÑи ENTER.

   ÐÑÐ¸Ð¼ÐµÑ Ð²Ñвода
           $ ./a.out /tmp /home/user/temp
           ÐажмиÑе ENTER Ð´Ð»Ñ Ð·Ð°Ð²ÐµÑÑÐµÐ½Ð¸Ñ ÑабоÑÑ.
           Ðжидание ÑобÑÑий.
           IN_OPEN: /home/user/temp/foo [Ñайл]
           IN_CLOSE_WRITE: /home/user/temp/foo [Ñайл]
           IN_OPEN: /tmp/ [каÑалог]
           IN_CLOSE_NOWRITE: /tmp/ [каÑалог]

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

   ÐÑÑоднÑй код пÑогÑаммÑ
       #include <errno.h>
       #include <poll.h>
       #include <stdio.h>
       #include <stdlib.h>
       #include <sys/inotify.h>
       #include <unistd.h>

       /* ЧиÑаем вÑе доÑÑÑпнÑе ÑобÑÑÐ¸Ñ Ð¸Ð· Ñайлового деÑкÑипÑоÑа «fd».
          wd â ÑаблиÑа деÑкÑипÑоÑов ÑÑоÑожков Ð´Ð»Ñ ÐºÐ°Ñалогов из argv.
          argc â длина wd и argv.
          argv â ÑпиÑок наблÑдаемÑÑ ÐºÐ°Ñалогов.
          ÐÐ»ÐµÐ¼ÐµÐ½Ñ 0 в wd и argv не иÑполÑзÑеÑÑÑ. */

       static void
       handle_events(int fd, int *wd, int argc, char* argv[])
       {
           /* РнекоÑоÑÑÑ ÑиÑÑÐµÐ¼Ð°Ñ Ð½ÐµÐ²Ð¾Ð·Ð¼Ð¾Ð¶Ð½Ð¾ пÑоÑиÑаÑÑ ÑелÑе пеÑеменнÑе, еÑли
              они непÑавилÑно вÑÑовненÑ. РдÑÑÐ³Ð¸Ñ ÑиÑÑÐµÐ¼Ð°Ñ Ð½ÐµÐºÐ¾ÑÑекÑное
              вÑÑавнивание Ð¼Ð¾Ð¶ÐµÑ ÑнижаÑÑ Ð¿ÑоизводиÑелÑноÑÑÑ. Таким обÑазом, бÑÑеÑ,
              иÑполÑзÑемÑй Ð´Ð»Ñ ÑÑÐµÐ½Ð¸Ñ Ð¸Ð· Ñайлового деÑкÑипÑоÑа inotify, должен бÑÑÑ
              вÑÑовнен Ñакже как ÑÑÑÑкÑÑÑа struct inotify_event. */

           char buf[4096]
               __attribute__ ((aligned(__alignof__(struct inotify_event))));
           const struct inotify_event *event;
           int i;
           ssize_t len;
           char *ptr;

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

           for (;;) {

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

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

               /* ÐÑли неблокиÑÑÑÑий read() не найдÑÑ ÑобÑÑий Ð´Ð»Ñ ÑÑениÑ, Ñо
                  веÑнÑÑ -1 Ñ errno ÑавнÑм EAGAIN. Ð ÑÑом ÑлÑÑае
                  вÑÑодим из Ñикла. */

               if (len <= 0)
                   break;

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

               for (ptr = buf; ptr < buf + len;
                       ptr += sizeof(struct inotify_event) + event->len) {

                   event = (const struct inotify_event *) ptr;

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

                   if (event->mask & IN_OPEN)
                       printf("IN_OPEN: ");
                   if (event->mask & IN_CLOSE_NOWRITE)
                       printf("IN_CLOSE_NOWRITE: ");
                   if (event->mask & IN_CLOSE_WRITE)
                       printf("IN_CLOSE_WRITE: ");

                   /* пеÑаÑаем Ð¸Ð¼Ñ Ð½Ð°Ð±Ð»Ñдаемого каÑалога */

                   for (i = 1; i < argc; ++i) {
                       if (wd[i] == event->wd) {
                           printf("%s/", argv[i]);
                           break;
                       }
                   }

                   /* пеÑаÑаем Ð¸Ð¼Ñ Ñайла */

                   if (event->len)
                       printf("%s", event->name);

                   /* пеÑаÑаем Ñип обÑекÑа Ñайловой ÑиÑÑÐµÐ¼Ñ */

                   if (event->mask & IN_ISDIR)
                       printf(" [каÑалог]\n");
                   else
                       printf(" [Ñайл]\n");
               }
           }
       }

       int
       main(int argc, char* argv[])
       {
           char buf;
           int fd, i, poll_num;
           int *wd;
           nfds_t nfds;
           struct pollfd fds[2];

           if (argc < 2) {
               printf("ÐÑполÑзование: %s ÐУТЬ [ÐУТЬ â¦]\n", argv[0]);
               exit(EXIT_FAILURE);
           }

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

           /* СоздаÑм ÑайловÑй деÑкÑипÑÐ¾Ñ Ð´Ð»Ñ Ð´Ð¾ÑÑÑпа к inotify API */

           fd = inotify_init1(IN_NONBLOCK);
           if (fd == -1) {
               perror("inotify_init1");
               exit(EXIT_FAILURE);
           }

           /* вÑделÑем памÑÑÑ Ð¿Ð¾Ð´ деÑкÑипÑоÑÑ ÑÑоÑожков */

           wd = calloc(argc, sizeof(int));
           if (wd == NULL) {
               perror("calloc");
               exit(EXIT_FAILURE);
           }

           /* помеÑаем каÑалоги Ð´Ð»Ñ ÑобÑÑий
              - Ñайл бÑл оÑкÑÑÑ
              - Ñайл бÑл закÑÑÑ */

           for (i = 1; i < argc; i++) {
               wd[i] = inotify_add_watch(fd, argv[i],
                                         IN_OPEN | IN_CLOSE);
               if (wd[i] == -1) {
                   fprintf(stderr, "Ðевозможно пÑонаблÑдаÑÑ '%s'\n", argv[i]);
                   perror("inotify_add_watch");
                   exit(EXIT_FAILURE);
               }
           }

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

           nfds = 2;

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

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

           /* ввод inotify */

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

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

                       handle_events(fd, wd, argc, argv);
                   }
               }
           }

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

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

           close(fd);

           free(wd);
           exit(EXIT_SUCCESS);
       }

СÐÐТРÐТРТÐÐÐÐ
       inotifywait(1), inotifywatch(1), inotify_add_watch(2), inotify_init(2),
       inotify_init1(2), inotify_rm_watch(2), read(2), stat(2), fanotify(7)

       Файл Documentation/filesystems/inotify.txt в деÑеве
       иÑÑодного кода ÑдÑа Linux



Linux                             2016-03-15                        INOTIFY(7)