Provided by: manpages-fr_4.21.0-2_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 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.

Pages du manuel de Linux 6.03                    5 février 2023                                       inotify(7)