Provided by: manpages-fr_4.18.1-1_all bug

NOM

       inotify - Surveiller les événements des systèmes de fichiers

DESCRIPTION

       L'API  inotify  fournit un mécanisme pour surveiller les événements au niveau des systèmes
       de fichiers. Inotify peut être utilisé pour surveiller des  fichiers  individuels  ou  des
       répertoires. Quand un répertoire est surveillé, inotify va signaler des événements pour le
       répertoire lui-même et pour les fichiers de ce répertoire.

       Les appels système suivants sont utilisés avec cette interface de programmation :

       •  inotify_init(2) crée une instance inotify et  renvoie  un  descripteur  de  fichier  se
          référant  à  cette  instance  inotify. L'appel système plus récent inotify_init1(2) est
          comme  inotify_init(2),  mais  a  un  argument  flags  qui  fournit  un  accès  à   des
          fonctionnalités supplémentaires.

       •  inotify_add_watch(2)  manipule  la  « liste  de  surveillance » associée à une instance
          inotify. Chaque élément (« watch ») de la liste de surveillance indique le chemin  d'un
          fichier  ou d'un répertoire, avec un ensemble d'événements que le noyau doit surveiller
          pour le fichier indiqué par ce chemin. inotify_add_watch(2) crée un nouvel  élément  de
          surveillance  ou  modifie un élément existant. Chaque élément a un unique « descripteur
          de surveillance », un entier renvoyé par inotify_add_watch(2) lorsque cet  élément  est
          créé.

       •  Quand  les  événements  ont  lieu  pour  des  fichiers  et  répertoires surveillés, ces
          événements sont rendus disponibles à l’application comme des  données  structurées  qui
          peuvent  être  lues depuis le descripteur de fichier inotify en utilisant read(2) (voir
          plus bas).

       •  inotify_rm_watch(2) retire un élément d'une liste de surveillance inotify.

       •  Quand tous les descripteurs de fichier se référant  à  une  instance  inotify  ont  été
          fermés (en utilisant close(2)), l'objet sous-jacent et ses ressources sont libérés pour
          être réutilisés par  le  noyau ;  tous  les  éléments  de  surveillance  associés  sont
          automatiquement libérés.

       Avec  une programmation prudente, une application peut utiliser inotify pour surveiller et
       mettre en cache efficacement  l’état  d’un  ensemble  d’objets  de  système  de  fichiers.
       Cependant,  les  applications  robustes devraient prendre en compte que des bogues dans la
       logique de surveillance ou  des  situations  de  compétition  du  type  décrit  ci-dessous
       pourraient  laisser  le  cache incohérent avec l’état du système de fichiers. Réaliser des
       vérifications de cohérence et reconstruire le cache en  cas  de  détection  d’incohérences
       serait sans doute sage.

   Lecture d’événements d’un descripteur de fichier inotify
       Pour  déterminer  quels  événements  ont  eu lieu, une application va lire avec read(2) le
       descripteur de fichier inotify. Si aucun événement n'a eu lieu, alors, en supposant  qu'il
       s'agisse  d'un descripteur de fichier bloquant, read(2) se bloquera jusqu'à ce qu'au moins
       un événement ait lieu (à moins qu'elle ne soit  interrompue  par  un  signal,  auquel  cas
       l'appel échouera avec l'erreur EINTR ; consultez signal(7)).

       Chaque  lecture  (avec  read(2))  réussie renvoie un tampon contenant une ou plusieurs des
       structures suivantes :

           struct inotify_event {
               int      wd;       /* Descripteur de surveillance */
               uint32_t mask;     /* Masque décrivant l’événement */
               uint32_t cookie;   /* Cookie unique d'association des
                                     événements (pour rename(2)) */
               uint32_t len;      /* Taille du champ name */
               char     name[];   /* Nom optionnel terminé par un nul */
           };

       wd identifie l'élément de surveillance pour lequel cet événement a lieu. Il s'agit de l'un
       des descripteurs de surveillance renvoyés par un précédent appel à inotify_add_watch(2).

       mask contient des bits qui décrivent l'événement qui a eu lieu (voir ci-dessous).

       cookie  est  un  entier unique qui relie les événements. Ce n'est actuellement utilisé que
       pour les événements de renommage, et permet  à  la  paire  d'événements  IN_MOVED_FROM  et
       IN_MOVED_TO  en  résultant  d'être  associée par l'application. Pour tous les autres types
       d'événements, cookie est mis à 0.

       The name field is present only when an event is returned  for  a  file  inside  a  watched
       directory;  it  identifies  the  filename  within  the watched directory. This filename is
       null-terminated, and may include further null bytes ('\0') to align subsequent reads to  a
       suitable address boundary.

       Le  champ len compte tous les octets de name, incluant les caractères nuls. La longueur de
       chaque structure inotify_event vaut donc sizeof(structinotify_event)+len.

       The behavior when the buffer given to read(2)  is too small to  return  information  about
       the  next  event  depends  on the kernel version: before Linux 2.6.21, read(2)  returns 0;
       since Linux 2.6.21, read(2)  fails with the error EINVAL. Specifying a buffer of size

           sizeof(struct inotify_event) + NAME_MAX + 1

       est suffisant pour lire au moins un événement.

   Événements inotify
       L'argument  mask  passé  à  inotify_add_watch(2)  et  le  champ  mask  de   la   structure
       inotify_event renvoyés lors de la lecture avec read(2) d'un descripteur de fichier inotify
       sont tous deux des masques binaires identifiant les événements inotify. Les bits  suivants
       peuvent  être  définis  dans  l'argument  mask  lors  de l'appel à inotify_add_watch(2) et
       peuvent être renvoyés dans le champ mask renvoyé par read(2).

           IN_ACCESS (+)
                  Accès au fichier (par exemple read(2), execve(2)).

           IN_ATTRIB (*)
                  Metadata changed—for example, permissions (e.g., chmod(2)),  timestamps  (e.g.,
                  utimensat(2)),  extended  attributes  (setxattr(2)),  link  count  (since Linux
                  2.6.25; e.g., for the target of link(2)  and for unlink(2)), and user/group  ID
                  (e.g., chown(2)).

           IN_CLOSE_WRITE (+)
                  Fichier ouvert en écriture fermé.

           IN_CLOSE_NOWRITE (*)
                  Fichier ou répertoire non ouverts en écriture fermés.

           IN_CREATE (+)
                  Fichier  ou  répertoire créés dans le répertoire surveillé (par exemple open(2)
                  O_CREAT, mkdir(2), link(2), symlink(2),  bind(2)  sur  une  socket  de  domaine
                  UNIX).

           IN_DELETE (+)
                  Fichier ou répertoire supprimés dans le répertoire surveillé.

           IN_DELETE_SELF
                  Fichier  ou répertoire surveillés supprimés (cet événement se produit également
                  si un objet est déplacé vers un autre système de fichiers, puisque mv(1)  copie
                  effectivement  le  fichier vers l’autre système de fichiers puis le supprime du
                  système de fichiers d’origine). De plus, un événement IN_IGNORED  sera  ensuite
                  généré pour le descripteur de surveillance.

           IN_MODIFY (+)
                  Fichier modifié (par exemple write(2), truncate(2)).

           IN_MOVE_SELF
                  Fichier ou répertoire surveillés déplacés.

           IN_MOVED_FROM (+)
                  Généré pour le répertoire contenant l'ancien nom quand un fichier est renommé.

           IN_MOVED_TO (+)
                  Généré  pour  le  répertoire  contenant  le  nouveau  nom  quand un fichier est
                  renommé.

           IN_OPEN (*)
                  Fichier ou répertoire ouvert.

       La surveillance par Inotify est basée sur les inodes :  lorsqu'un  fichier  est  surveillé
       (mais pas lors de la surveillance d'un répertoire contenant un fichier), un événement peut
       être créé sur tout lien vers le fichier (dans le même répertoire  ou  dans  un  répertoire
       différent).

       Lors de la surveillance d'un répertoire :

       •  les  événements marqués précédemment par un astérisque (*) peuvent avoir lieu à la fois
          pour le répertoire et pour les objets à l’intérieur du répertoire ;

       •  les événements marqués par un  signe  plus  (+)  n’ont  lieu  que  pour  les  objets  à
          l’intérieur du répertoire (et non pour le répertoire lui-même).

       Note :  lorsqu'un  répertoire  est  surveillé,  les  événements ne sont pas créés pour les
       fichiers contenus dans le répertoire quand des événements sont exécutés  avec  un  nom  de
       chemin (par exemple, un lien) qui se trouve hors du répertoire surveillé.

       Lorsque  les  événements sont créés pour les objets dans un répertoire surveillé, le champ
       name dans la structure  inotify_event  renvoyée  identifie  le  nom  du  fichier  dans  ce
       répertoire.

       La  macro IN_ALL_EVENTS est définie comme un masque binaire de tous les événements décrits
       ci-dessus. Cette macro peut  être  utilisée  comme  l'argument  mask  lors  de  l'appel  à
       inotify_add_watch(2).

       Deux macros supplémentaires de convenance sont définies :

           IN_MOVE
                  Équivalent à IN_MOVED_FROM | IN_MOVED_TO.

           IN_CLOSE
                  Équivalent à IN_CLOSE_WRITE | IN_CLOSE_NOWRITE.

       Les  bits  supplémentaires  suivants  peuvent  être  indiqués dans l'argument mask lors de
       l'appel à inotify_add_watch(2) :

           IN_DONT_FOLLOW (depuis Linux 2.6.15)
                  Ne pas déréférencer pathname s'il s'agit d'un lien symbolique.

           IN_EXCL_UNLINK (depuis Linux 2.6.36)
                  Par  défaut,  lors  de  la  surveillance  d'événements  sur  les  entrées  d'un
                  répertoire,  des  événements  sont  créés  pour  ces  entrées  même  après leur
                  suppression du répertoire. De nombreux événements inintéressants pour certaines
                  applications  peuvent ainsi être créés (par exemple, lors de la surveillance de
                  /tmp, où de nombreuses applications créent des fichiers  temporaires  donc  les
                  noms   sont   immédiatement  supprimés).  Indiquer  IN_EXCL_UNLINK  modifie  le
                  comportement par défaut, de telle sorte qu'aucun événement n'est créé pour  ces
                  entrées après leur suppression du répertoire surveillé.

           IN_MASK_ADD
                  If  a  watch instance already exists for the filesystem object corresponding to
                  pathname, add (OR) the events in mask to the watch mask (instead  of  replacing
                  the mask); the error EINVAL results if IN_MASK_CREATE is also specified.

           IN_ONESHOT
                  Surveiller  l’objet  de  système  de fichiers correspondant à pathname jusqu'au
                  premier événement, puis le supprimer de la liste de surveillance.

           IN_ONLYDIR (depuis Linux 2.6.15)
                  Watch pathname only if it is a directory; the error ENOTDIR results if pathname
                  is  not  a  directory. Using this flag provides an application with a race-free
                  way of ensuring that the monitored object is a directory.

           IN_MASK_CREATE (since Linux 4.18)
                  Watch pathname only if it does not already have a watch associated with it; the
                  error EEXIST results if pathname is already being watched.

                  Using this flag provides an application with a way of ensuring that new watches
                  do not modify existing ones. This is useful because multiple paths may refer to
                  the  same  inode,  and multiple calls to inotify_add_watch(2) without this flag
                  may clobber existing watch masks.

       Les bits suivants peuvent avoir été définis dans le champ mask renvoyé par read(2) :

           IN_IGNORED
                  Le  surveillant   a   été   retiré   explicitement   (inotify_rm_watch(2))   ou
                  automatiquement  (le  fichier  a  été  effacé,  ou le système de fichiers a été
                  démonté). Consultez également BOGUES.

           IN_ISDIR
                  Le sujet de cet événement est un répertoire.

           IN_Q_OVERFLOW
                  Queue des événements surchargée (wd vaut alors -1).

           IN_UNMOUNT
                  Le système de fichiers contenant l'objet surveillé a été démonté. De  plus,  un
                  événement IN_IGNORED sera ensuite généré pour le descripteur de surveillance.

   Exemples
       Soit  une application surveillant le répertoire rép et le fichier rép/monfichier pour tous
       les événements. Les exemples ci-dessous montrent quelques événements  qui  seront  générés
       pour ces deux objets.

           fd = open("rép/monfichier", O_RDWR);
                  Génère des événements IN_OPEN à la fois pour rép et rép/monfichier.

           read(fd, buf, count);
                  Génère des événements IN_ACCESS à la fois pour rép et rép/monfichier.

           write(fd, buf, count);
                  Génère des événements IN_MODIFY à la fois pour rép et rép/monfichier.

           fchmod(fd, mode);
                  Génère des événements IN_ATTRIB à la fois pour rép et rép/monfichier.

           close(fd);
                  Génère des événements IN_CLOSE_WRITE à la fois pour rép et rép/monfichier.

       Soit   une   application   surveillant  les  répertoires  rép1  et  rép2,  et  le  fichier
       rép1/monfichier. Les exemples suivants montrent quelques événements  qui  pourraient  être
       générés.

           link("rép1/monfichier", "rép2/nouveau");
                  Génère  un  événement  IN_ATTRIB pour monfichier et un événement IN_CREATE pour
                  rép2.

           rename("rép1/monfichier", "rép2/monfichier");
                  Génère un événement IN_MOVED_FROM pour dir1, un événement IN_MOVED_TO pour rép2
                  et  un  événement IN_MOVE_SELF pour monfichier. Les événements IN_MOVED_FROM et
                  IN_MOVED_TO auront la même valeur cookie.

       Soient rép1/xx et rép2/yy les (seuls) liens  vers  le  même  ficher,  et  une  application
       surveillant  rép1,  rép2, rép1/xx et rép2/yy. L’exécution des appels suivants dans l’ordre
       donné ci-dessous générera les événements suivants :

           unlink("rép2/yy");
                  Génère un événement IN_ATTRIB pour xx (à cause du changement de son compteur de
                  liens) et un événement IN_DELETE pour rép2.

           unlink("rép1/xx");
                  Génère  des  événements  IN_ATTRIB,  IN_DELETE_SELF et IN_IGNORED pour xx et un
                  événement IN_DELETE pour rép1.

       Soit une application surveillant le répertoire rép et le  répertoire  (vide)  rép/sousrép.
       Les exemples suivants montrent quelques événements qui pourraient être générés.

           mkdir("rép/nouveau", mode);
                  Génère un événement IN_CREATE | IN_ISDIR pour rép.

           rmdir("rép/sousrép");
                  Génère des événements IN_DELETE_SELF et IN_IGNORED pour sousrép et un événement
                  IN_DELETE | IN_ISDIR pour rép.

   Interfaces /proc
       Les interfaces suivantes peuvent être utilisées pour limiter la  quantité  de  mémoire  du
       noyau utilisée par inotify :

       /proc/sys/fs/inotify/max_queued_events
              La   valeur   dans   ce   fichier   est  utilisée  lorsqu'une  application  appelle
              inotify_init(2) pour définir la  limite  maximale  du  nombre  des  événements  qui
              peuvent  entrer  dans  la  file d'attente de l'instance inotify correspondante. Les
              événements au-delà de cette limite sont annulés, mais  un  événement  IN_Q_OVERFLOW
              est systématiquement généré.

       /proc/sys/fs/inotify/max_user_instances
              Cela  indique  la  limite  maximale  du nombre d'instances inotify qui peuvent être
              créées par identifiant utilisateur réel.

       /proc/sys/fs/inotify/max_user_watches
              Cela indique la limite maximale du nombre de « watch » qui peuvent être  créés  par
              identifiant utilisateur réel.

VERSIONS

       Inotify  was merged into Linux 2.6.13. The required library interfaces were added in glibc
       2.4. (IN_DONT_FOLLOW, IN_MASK_ADD, and IN_ONLYDIR were added in glibc 2.5.)

STANDARDS

       L’interface de programmation inotify est spécifique à Linux.

NOTES

       Les descripteurs de fichier  inotify  peuvent  être  surveillés  en  utilisant  select(2),
       poll(2) et epoll(7). Lorsqu'un événement est disponible, le descripteur de fichier indique
       qu'il est accessible en lecture.

       Depuis  Linux 2.6.25,  il  est  possible  d'être  notifié  par  des   signaux   pour   des
       entrées-sorties  des  descripteurs de fichier inotify ; consultez la discussion de F_SETFL
       (pour la configuration de l'attribut O_ASYNC), F_SETOWN, et  F_SETSIG  dans  fcntl(2).  La
       structure siginfo_t (décrite dans sigaction(2)) qui est passée au gestionnaire de signal a
       les champs suivants définis : si_fd est défini avec le numéro de descripteur  de  fichiers
       inotify ; si_signo est défini avec le numéro du signal ; si_code est défini avec POLL_IN ;
       et si_band est défini avec POLLIN.

       Si deux événements inotify de sortie successifs produits sur  le  descripteur  de  fichier
       inotify  sont  identiques (wd, mask, cookie, et name identiques), alors ils sont fusionnés
       en un seul événement si l'événement le plus ancien n'a toujours pas été lu (mais consultez
       la  section  BOGUES).  Cela  permet  de  réduire  la  quantité  de mémoire en espace noyau
       nécessaire à la file d'événements, mais signifie  également  qu'une  application  ne  peut
       utiliser inotify pour compter de manière fiable les événements liés à un fichier.

       Les événements renvoyés lors de la lecture d'un descripteur de fichier inotify forment une
       file ordonnée. Ainsi, par exemple, il est garanti que lors du renommage  d'un  répertoire,
       les  événements  seront  produits  dans  l'ordre  convenable sur le descripteur de fichier
       inotify.

       The set of watch descriptors that is being monitored via an inotify file descriptor can be
       viewed  via  the  entry  for the inotify file descriptor in the process's /proc/pid/fdinfo
       directory. See proc(5)  for further details. The FIONREAD ioctl(2)  returns the number  of
       bytes available to read from an inotify file descriptor.

   Limites et réserves
       L'interface inotify ne fournit aucun renseignement sur l'utilisateur ou le processus qui a
       déclenché l'événement inotify. En particulier, un processus en  train  de  surveiller  des
       événements  à  l'aide  d'inotify  ne  dispose  d'aucun  moyen  facile  pour distinguer les
       événements qu'il déclenche lui-même de ceux qui ont été déclenchés par d'autres processus.

       Inotify ne signale que les événements déclenchés par un programme en espace utilisateur  à
       l’aide  de  l’interface  de  programmation  de  système  de fichiers. Par conséquent, elle
       n’intercepte pas les événements qui surviennent sur les systèmes  de  fichiers  en  réseau
       (les applications doivent avoir recours à la scrutation (polling) pour intercepter ce type
       d’événements). De plus, divers pseudo-systèmes de fichiers comme /proc, /sys  et  /dev/pts
       ne sont pas surveillables avec inotify.

       L'interface  inotify  ne  signale  pas  les  accès  ni  les  modifications  de fichier qui
       pourraient survenir à cause de mmap(2), msync(2) ou munmap(2).

       L'interface inotify identifie les fichiers affectés par leur nom. Cependant, au moment  où
       l'application  traite un événement inotify, ce nom de fichier peut avoir déjà été supprimé
       ou renommé.

       L’interface inotify identifie les événements à l’aide  de  descripteurs  de  surveillance.
       L’application  est responsable de mettre en cache une correspondance (si nécessaire) entre
       les descripteurs de fichier et les chemins. Soyez vigilants aux renommages  de  répertoire
       qui pourraient affecter plusieurs chemins en cache.

       La  surveillance  inotify  des  répertoires  n'est  pas  récursive :  pour  surveiller les
       sous-répertoires, des éléments de surveillance supplémentaires doivent  être  créés.  Cela
       peut être assez long pour les répertoires contenant une grande arborescence.

       Si  la  surveillance  concerne  une  arborescence  dans  son intégralité, et si un nouveau
       sous-répertoire est créé dans ce répertoire ou si un répertoire existant est renommé  dans
       cette  arborescence, soyez conscient qu'au moment où vous créez un élément de surveillance
       pour le nouveau sous-répertoire, de nouveaux fichiers (et sous-répertoires)  peuvent  déjà
       exister   dans   le   sous-répertoire.   Ainsi,   vous  devriez  analyser  le  contenu  du
       sous-répertoire immédiatement  après  avoir  ajouté  l'élément  de  surveillance  (et,  si
       nécessaire,  ajouter  des  éléments  de  surveillance pour tous les sous-répertoires qu’il
       contient).

       Remarquez que la file d'événements peut déborder. Dans ce cas, des événements sont perdus.
       Les  applications  robustes  devraient  gérer  correctement  la  possibilité de perdre des
       événements. Par exemple, la reconstruction de tout ou partie  du  cache  de  l’application
       pourrait être nécessaire (une approche simple, mais éventuellement coûteuse, est de fermer
       le descripteur de fichier inotify, vider le cache, créer un nouveau descripteur de fichier
       inotify  et recréer les éléments de surveillance et les entrées du cache pour les objets à
       surveiller).

       Si un système de fichiers est monté par dessus un répertoire  surveillé,  aucun  événement
       n'est  généré,  pas plus que pour les objets se trouvant directement sous le nouveau point
       de montage. Si le système de fichiers est par la  suite  démonté,  les  événements  seront
       créés pour le répertoire et les objets qu'il contient.

   Traitement des événements rename()
       Comme  noté  précédemment,  la paire d’événements IN_MOVED_FROM et IN_MOVED_TO générée par
       rename(2) peut être assemblée à l’aide de la valeur de cookie partagé. Cependant, la tâche
       d’assemblage peut poser quelques problèmes.

       Ces  deux  événements  sont  normalement consécutifs dans le flux d’événements disponibles
       lors de la lecture depuis le descripteur de fichiers  inotify.  Cependant,  ce  n’est  pas
       garanti.  Si  plusieurs  processus  déclenchent des événements pour des objets surveillés,
       alors (rarement) un nombre arbitraire d’autres événements pourrait  apparaître  entre  les
       événements  IN_MOVED_FROM  et  IN_MOVED_TO.  De  plus,  il  n'est pas garanti que la paire
       d'événements soit insérée de façon atomique dans la file : il pourrait  y  avoir  un  bref
       intervalle au cours duquel IN_MOVED_FROM est apparu, mais pas IN_MOVED_TO.

       L’assemblage  de  la paire d’événements IN_MOVED_FROM et IN_MOVED_TO générés par rename(2)
       pose donc intrinsèquement un risque de situation de compétition (n’oubliez pas que  si  un
       objet  est  renommé en dehors d’un répertoire surveillé, un événement IN_MOVED_TO pourrait
       ne même pas être envoyé).  Des  approches  heuristiques  (par  exemple  supposer  que  les
       événements  sont  toujours consécutifs) permettent d’assurer un assemblage dans la plupart
       des cas, mais manqueront forcément certains cas, forçant  l’application  à  percevoir  les
       événements  IN_MOVED_FROM  et  IN_MOVED_TO  comme  indépendants.  Si  les  descripteurs de
       surveillance  sont  détruits  et  recréés  par  conséquent,  alors  ces  descripteurs   de
       surveillance  seront  incohérents  avec  les  descripteurs  de  surveillance dans tous les
       événements  en  attente  (la  recréation  du  descripteur  de  fichier   inotify   et   la
       reconstruction du cache pourrait être utile dans ce cas).

       Applications  should  also  allow for the possibility that the IN_MOVED_FROM event was the
       last event that could fit in the buffer returned by the current call to read(2),  and  the
       accompanying  IN_MOVED_TO event might be fetched only on the next read(2), which should be
       done  with  a  (small)  timeout  to  allow  for   the   fact   that   insertion   of   the
       IN_MOVED_FROM+IN_MOVED_TO  event  pair  is not atomic, and also the possibility that there
       may not be any IN_MOVED_TO event.

BOGUES

       Avant Linux 3.19, fallocate(2) ne créait pas d'événements inotify. Depuis Linux 3.19,  les
       appels à fallocate(2) créent des événements IN_MODIFY.

       Before Linux 2.6.16, the IN_ONESHOT mask flag does not work.

       Tel que conçu et implémenté à l’origine, l’attribut IN_ONESHOT ne forçait pas à générer un
       appel IN_IGNORED lorsque la surveillance était supprimée après un événement. Cependant, en
       conséquence   involontaire  d’autres  modifications,  depuis  Linux 2.6.36,  un  événement
       IN_IGNORED est généré dans ce cas.

       Before Linux 2.6.25, the kernel code that was intended to  coalesce  successive  identical
       events  (i.e.,  the two most recent events could potentially be coalesced if the older had
       not yet been read)  instead checked if the most recent event could be coalesced  with  the
       oldest unread event.

       Quand  un  descripteur  de  surveillance  est supprimé en appelant inotify_rm_watch(2) (ou
       parce qu’un fichier de surveillance est supprimé ou que le  système  de  fichiers  qui  le
       contient  est  démonté),  tous  les  événements  non lus en attente pour ce descripteur de
       fichier restent disponibles en  lecture.  Comme  les  descripteurs  de  surveillance  sont
       ensuite   alloués   avec  inotify_add_watch(2),  le  noyau  boucle  sur  l’intervalle  des
       descripteurs de surveillance possibles (O à INT_MAX)  de  façon  incrémentielle.  Lors  de
       l’allocation  d’un  descripteur de surveillance libre, aucune vérification n’est effectuée
       pour voir si ce numéro de descripteur de surveillance a des événements non lus en  attente
       dans  la  file  inotify. Ainsi, un descripteur de surveillance pourrait être réalloué même
       quand des événements non lus en attente existent pour une  incarnation  précédente  de  ce
       numéro  de  descripteur  de  surveillance,  avec comme résultat que l’application pourrait
       alors lire ces événements et les interpréter  comme  appartenant  au  fichier  associé  au
       descripteur  de  surveillance  nouvellement  recyclé.  En  pratique, la probabilité d’être
       victime de ce bogue devrait être extrêmement basse, puisqu’il nécessite qu’une application
       boucle  sur  INT_MAX descripteurs  de surveillance, relâche un descripteur de surveillance
       tout en laissant des événements non lus pour ce descripteur de fichier  dans  la  file  et
       ensuite recycle ce descripteur de surveillance. Pour cette raison, et parce qu’il n’y a eu
       aucun rapports de  bogue  à  propos  de  réelles  applications,  dans  Linux 3.15,  aucune
       modification de noyau n’a encore été faite pour éliminer ce bogue éventuel.

EXEMPLES

       The  following program demonstrates the usage of the inotify API. It marks the directories
       passed as a command-line arguments and waits for events of type IN_OPEN, IN_CLOSE_NOWRITE,
       and IN_CLOSE_WRITE.

       La   sortie   suivante   a   été   enregistrée   lors   de   la  modification  du  fichier
       /home/utilisateur/temp/toto et  de  l’affichage  du  contenu  du  répertoire  /tmp.  Avant
       d’ouvrir le fichier et le répertoire, un événement IN_OPEN est survenu. Après la fermeture
       du fichier, un événement IN_CLOSE_WRITE est survenu. Après la fermeture du répertoire,  un
       événement  IN_CLOSE_NOWRITE  est  survenu.  L’exécution  du programme s’est terminée quand
       l’utilisateur a appuyé sur la touche Entrée.

   Sortie de l’exemple
           $ ./a.out /tmp /home/utilisateur/temp
           Appuyer sur la touche Entrée pour quitter.
           En écoute d’événements.
           IN_OPEN : /home/utilisateur/temp/toto [fichier]
           IN_CLOSE_WRITE : /home/utilisateur/temp/toto [fichier]
           IN_OPEN : /tmp/ [répertoire]
           IN_CLOSE_NOWRITE : /tmp/ [répertoire]

           Arrêt de l’écoute d’événements.

   Source du programme

       #include <errno.h>
       #include <poll.h>
       #include <stdio.h>
       #include <stdlib.h>
       #include <sys/inotify.h>
       #include <unistd.h>
       #include <string.h>

       /* Read all available inotify events from the file descriptor 'fd'.
          wd is the table of watch descriptors for the directories in argv.
          argc is the length of wd and argv.
          argv is the list of watched directories.
          Entry 0 of wd and argv is unused. */

       static void
       handle_events(int fd, int *wd, int argc, char* argv[])
       {
           /* Certains systèmes ne peuvent pas lire de variables entières
              si elles ne sont pas alignées correctement. Sur d’autres
              systèmes, un alignement incorrect pourrait diminuer les
              performances. Par conséquent, le tampon utilisé pour lire
              le descripteur de fichier inotify devrait avoir le même
              alignement que struct inotify_event. */

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

           /* Boucler tant que les événements peuvent être lus à partir du
              descripteur de fichier inotify */

           for (;;) {

               /* Lire certains événements. */

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

               /* If the nonblocking read() found no events to read, then
                  it returns -1 with errno set to EAGAIN. In that case,
                  we exit the loop. */

               if (len <= 0)
                   break;

               /* Loop over all events in the buffer. */

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

                   event = (const struct inotify_event *) ptr;

                   /* Print event type. */

                   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 : ");

                   /* Print the name of the watched directory. */

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

                   /* Print the name of the file. */

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

                   /* Print type of filesystem object. */

                   if (event->mask & IN_ISDIR)
                       printf(" [répertoire]\n");
                   else
                       printf(" [fichier]\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("Utilisation : %s CHEMIN [CHEMIN ...]\n", argv[0]);
               exit(EXIT_FAILURE);
           }

           printf("Appuyer sur la touche Entrée pour quitter.\n");

           /* Create the file descriptor for accessing the inotify API. */

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

           /* Allocate memory for watch descriptors. */

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

           /* Marquer les répertoires pour les événements :
              - un fichier a été ouvert ;
              - un fichier a été fermé

           for (i = 1; i < argc; i++) {
               wd[i] = inotify_add_watch(fd, argv[i],
                                         IN_OPEN | IN_CLOSE);
               if (wd[i] == -1) {
                   fprintf(stderr, "Cannot watch '%s': %s\n",
                           argv[i], strerror(errno));
                   exit(EXIT_FAILURE);
               }
           }

           /* Prepare for polling. */

           nfds = 2;

           fds[0].fd = STDIN_FILENO;       /* Console input */
           fds[0].events = POLLIN;

           fds[1].fd = fd;                 /* Inotify input */
           fds[1].events = POLLIN;

           /* Wait for events and/or terminal input. */

           printf("En écoute d’événements.\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) {

                       /* Console input is available. Empty stdin and quit. */

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

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

                       /* Inotify events are available. */

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

           printf("Arrêt de l’écoute d’événements.\n");

           /* Close inotify file descriptor. */

           close(fd);

           free(wd);
           exit(EXIT_SUCCESS);
       }

VOIR AUSSI

       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 dans les sources du noyau Linux

TRADUCTION

       La  traduction  française  de  cette  page  de  manuel  a  été créée par Christophe Blaess
       <https://www.blaess.fr/christophe/>, Stéphan  Rafin  <stephan.rafin@laposte.net>,  Thierry
       Vignaud  <tvignaud@mandriva.com>,  François Micaux, Alain Portal <aportal@univ-montp2.fr>,
       Jean-Philippe   Guérard   <fevrier@tigreraye.org>,   Jean-Luc   Coulon   (f5ibh)    <jean-
       luc.coulon@wanadoo.fr>,    Julien    Cristau    <jcristau@debian.org>,    Thomas   Huriaux
       <thomas.huriaux@gmail.com>, Nicolas François <nicolas.francois@centraliens.net>, Florentin
       Duneau  <fduneau@gmail.com>, Simon Paillard <simon.paillard@resel.enst-bretagne.fr>, Denis
       Barbier <barbier@debian.org> et David Prévot <david@tilapin.org>

       Cette traduction est une documentation libre ; veuillez vous reporter  à  la  GNU  General
       Public   License   version 3  ⟨https://www.gnu.org/licenses/gpl-3.0.html⟩  concernant  les
       conditions de copie et de distribution. Il n'y a aucune RESPONSABILITÉ LÉGALE.

       Si vous découvrez un bogue dans la traduction de cette page de manuel, veuillez envoyer un
       message à ⟨debian-l10n-french@lists.debian.org⟩.