Man page - inotify(7)
Packages contains this manual
- shm_overview(7)
- nss(5)
- proc_mtrr(5)
- intro(7)
- tcp(7)
- iso_8859-9(7)
- armscii-8(7)
- proc_kpagecount(5)
- initrd(4)
- mouse(4)
- proc_stat(5)
- x25(7)
- proc_interrupts(5)
- fifo(7)
- repertoiremap(5)
- icmp(7)
- futex(7)
- feature_test_macros(7)
- lp(4)
- bpf-helpers(7)
- epoll(7)
- proc_sys_dev(5)
- namespaces(7)
- proc_sysrq-trigger(5)
- proc_bus(5)
- cp1251(7)
- proc_pid_maps(5)
- proc_sys_vm(5)
- proc_pid_projid_map(5)
- st(4)
- proc_pid(5)
- issue(5)
- pid_namespaces(7)
- unicode(7)
- inode(7)
- hosts.equiv(5)
- iso-8859-13(7)
- proc_fb(5)
- proc_modules(5)
- proc_pid_autogroup(5)
- keyrings(7)
- sysvipc(7)
- proc_kmsg(5)
- cgroups(7)
- latin6(7)
- proc_pid_uid_map(5)
- unix(7)
- proc_pid_io(5)
- pts(4)
- packet(7)
- ld-linux.so(8)
- tzselect(8)
- iconv(1)
- proc_pid_syscall(5)
- proc_pid_net(5)
- proc_pid_pagemap(5)
- tty(4)
- proc_profile(5)
- standards(7)
- proc_pid_mounts(5)
- filesystems(5)
- iso-8859-15(7)
- locale(5)
- iso_8859_3(7)
- xattr(7)
- iso-8859-2(7)
- proc_uptime(5)
- persistent-keyring(7)
- credentials(7)
- proc_pid_timers(5)
- utmpx(5)
- vcsa(4)
- proc_pid_exe(5)
- proc_net(5)
- proc_timer_stats(5)
- ip(7)
- proc_pid_fd(5)
- ptmx(4)
- user_namespaces(7)
- resolv.conf(5)
- url(7)
- iso_8859_5(7)
- iso_8859-8(7)
- urn(7)
- process-keyring(7)
- proc_pid_auxv(5)
- proc_ksyms(5)
- proc_ide(5)
- veth(4)
- ldd(1)
- proc_swaps(5)
- landlock(7)
- proc_vmstat(5)
- system_data_types(7)
- cp1252(7)
- lirc(4)
- proc_kpageflags(5)
- random(7)
- precedence(7)
- cpuset(7)
- proc_pid_ns(5)
- acct(5)
- latin4(7)
- proc_pid_cgroup(5)
- proc_cpuinfo(5)
- iso_8859-2(7)
- proc_keys(5)
- charsets(7)
- pldd(1)
- proc_pid_stat(5)
- rtnetlink(7)
- netlink(7)
- ram(4)
- mem(4)
- iso-8859-6(7)
- proc_key-users(5)
- iso_8859_15(7)
- fanotify(7)
- proc_sys_net(5)
- sysfs(5)
- math_error(7)
- latin1(7)
- proc_pid_root(5)
- nptl(7)
- proc_cgroups(5)
- proc_iomem(5)
- proc_pid_statm(5)
- sem_overview(7)
- hier(7)
- full(4)
- proc_pid_status(5)
- proc_pid_cwd(5)
- proc_pid_cpuset(5)
- proc_scsi(5)
- uri(7)
- proc_diskstats(5)
- iso_8859_6(7)
- latin2(7)
- latin5(7)
- man-pages(7)
- ld.so(8)
- uts_namespaces(7)
- proc_pid_mountstats(5)
- intro(3)
- proc_pid_seccomp(5)
- proc_pid_wchan(5)
- attributes(7)
- symlink(7)
- mount_namespaces(7)
- charmap(5)
- tis-620(7)
- iso-8859-10(7)
- getent(1)
- proc_buddyinfo(5)
- ttytype(5)
- rtc(4)
- proc_malloc(5)
- suffixes(7)
- sln(8)
- signal(7)
- proc_sys_abi(5)
- signal-safety(7)
- time_namespaces(7)
- proc_pid_comm(5)
- raw(7)
- gai.conf(5)
- proc_crypto(5)
- locale(1)
- iso-8859-3(7)
- motd(5)
- proc_meminfo(5)
- iso-8859-8(7)
- protocols(5)
- proc_pid_map_files(5)
- pthreads(7)
- null(4)
- proc(5)
- zdump(8)
- socket(7)
- proc_sys_kernel(5)
- ddp(7)
- memusagestat(1)
- hd(4)
- iso-8859-14(7)
- shells(5)
- pipe(7)
- glob(7)
- proc_self(5)
- network_namespaces(7)
- utmp(5)
- proc_kcore(5)
- nsswitch.conf(5)
- sd(4)
- iso-8859-5(7)
- iso_8859_16(7)
- man(7)
- iso_8859-6(7)
- dir_colors(5)
- mq_overview(7)
- vsock(7)
- ascii(7)
- thread-keyring(7)
- fs(5)
- proc_pid_attr(5)
- proc_sys_debug(5)
- proc_sys(5)
- proc_pid_cmdline(5)
- pty(7)
- services(5)
- cgroup_namespaces(7)
- securetty(5)
- netdevice(7)
- iso_8859_13(7)
- host.conf(5)
- proc_pid_setgroups(5)
- proc_slabinfo(5)
- sock_diag(7)
- iso_8859-14(7)
- iso-8859-11(7)
- iso_8859_11(7)
- operator(7)
- regex(7)
- wavelan(4)
- proc_sys_fs(5)
- nologin(5)
- proc_pci(5)
- koi8-r(7)
- erofs(5)
- intro(2)
- utf8(7)
- proc_kallsyms(5)
- proc_sysvipc(5)
- queue(7)
- proc_sys_sunrpc(5)
- intro(5)
- latin8(7)
- mtrace(1)
- ipc_namespaces(7)
- dsp56k(4)
- iso_8859_4(7)
- proc_pid_smaps(5)
- proc_cmdline(5)
- rpc(5)
- proc_tty(5)
- proc_version(5)
- smartpqi(4)
- proc_pid_timerslack_ns(5)
- aio(7)
- session-keyring(7)
- resolver(5)
- slabinfo(5)
- wtmp(5)
- iso_8859_9(7)
- proc_locks(5)
- mailaddr(7)
- proc_pid_oom_score(5)
- kmem(4)
- iconvconfig(8)
- iso_8859-7(7)
- glibc(7)
- hostname(7)
- proc_thread-self(5)
- ipv6(7)
- iso_8859_7(7)
- proc_kpagecgroup(5)
- core(5)
- time(7)
- units(7)
- proc_dma(5)
- loop(4)
- address_families(7)
- zero(4)
- intro(4)
- procfs(5)
- iso_8859-4(7)
- vdso(7)
- tmpfs(5)
- iso-8859-16(7)
- iso_8859_10(7)
- user-session-keyring(7)
- libc(7)
- proc_fs(5)
- koi8-u(7)
- latin3(7)
- proc_tid_children(5)
- proc_pid_limits(5)
- proc_pid_coredump_filter(5)
- iso_8859-15(7)
- arp(7)
- urandom(4)
- iso_8859-10(7)
- hpsa(4)
- proc_pid_environ(5)
- boot(7)
- ftm(7)
- ld-linux(8)
- proc_driver(5)
- loop-control(4)
- iso_8859-16(7)
- proc_filesystems(5)
- tzfile(5)
- sprof(1)
- proc_pid_task(5)
- proc_pid_oom_score_adj(5)
- proc_mounts(5)
- iso-8859-4(7)
- iso_8859-1(7)
- utf-8(7)
- iso_8859-13(7)
- intro(6)
- proc_timer_list(5)
- rtld-audit(7)
- iso_8859-3(7)
- group(5)
- sched(7)
- proc_pid_clear_refs(5)
- hosts(5)
- iso_8859-11(7)
- numa(7)
- iso_8859_2(7)
- locale(7)
- iso-8859-1(7)
- fuse(4)
- proc_tid(5)
- proc_execdomains(5)
- proc_pid_mountinfo(5)
- intro(8)
- iso_8859_8(7)
- proc_loadavg(5)
- proc_pid_oom_adj(5)
- re_format(7)
- iso_8859_14(7)
- zic(8)
- bootparam(7)
- inotify(7)
- posixoptions(7)
- proc_partitions(5)
- iso-8859-9(7)
- proc_pid_mem(5)
- networks(5)
- proc_sys_user(5)
- udp(7)
- proc_zoneinfo(5)
- latin10(7)
- proc_pid_fdinfo(5)
- proc_pid_stack(5)
- memusage(1)
- spufs(7)
- pkeys(7)
- path_resolution(7)
- proc_ioports(5)
- intro(1)
- ldconfig(8)
- msr(4)
- svipc(7)
- port(4)
- proc_pid_personality(5)
- cciss(4)
- latin9(7)
- capabilities(7)
- localedef(1)
- vcs(4)
- iso_8859-5(7)
- elf(5)
- proc_sys_proc(5)
- console_codes(4)
- random(4)
- iso-8859-7(7)
- termcap(5)
- cpuid(4)
- environ(7)
- string_copying(7)
- proc_pid_gid_map(5)
- queue(3)
- termio(7)
- user-keyring(7)
- complex(7)
- latin7(7)
- proc_config.gz(5)
- udplite(7)
- kernel_lockdown(7)
- proc_devices(5)
- proc_apm(5)
- iso_8859_1(7)
- proc_pid_numa_maps(5)
apt-get install manpages
Available languages:
en fr ja ruManual
inotify
NOMDESCRIPTION
Lecture dâĂ©vĂ©nements dâun descripteur de fichier inotify
ĂvĂ©nements inotify
Exemples
/proc interfaces
STANDARDS
HISTORIQUE
NOTES
Limites et réserves
Traitement des événements rename()
BOGUES
EXEMPLES
Sortie de lâexemple
Source du programme
VOIR AUSSI
TRADUCTION
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.
Le champ name nâest prĂ©sent que lorsquâun Ă©vĂ©nement est renvoyĂ© pour un fichier au sein dâun rĂ©pertoire surveillĂ©. Il identifie le chemin du fichier dans le rĂ©pertoire surveillĂ©. Ce chemin est terminĂ© par un caractĂšre NULL et peut inclure dâautres octets nuls (« \0 ») pour ajuster des lectures successives Ă une limite dâadressage convenable.
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 .
Le comportement, lorsque le tampon donnĂ© Ă read (2) est trop petit pour renvoyer lâinformation sur le prochain Ă©vĂ©nement, dĂ©pend de la version du noyau : avant Linux 2.6.21, read (2) renvoie 0 ; depuis Linux 2.6.21, read (2) Ă©choue avec lâerreur EINVAL . Indiquer un tampon de taille
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 (*)
Modification des métadonnées, par exemple, les permissions (par exemple chmod (2)), les horodatages (par exemple utimensat (2)), les attributs étendus ( setxattr (2)), le compteur de liens (depuis Linux 2.6.25 ; par exemple pour la cible de link (2) et unlink (2)) et les UID ou GID (par exemple 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 un 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 chemin 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
Si une instance de surveillance existe dĂ©jĂ pour lâobjet de systĂšme de fichiers correspondant Ă chemin , ajouter (avec un OU binaire) les Ă©vĂ©nements de mask au masque de surveillance (au lieu de remplacer le masque) ; il rĂ©sulte une erreur EINVAL si IN_MASK_CREATE est aussi spĂ©cifiĂ©.
IN_ONESHOT
Surveiller lâobjet de systĂšme de fichiers correspondant Ă chemin jusquâau premier Ă©vĂ©nement, puis le supprimer de la liste de surveillance.
IN_ONLYDIR (depuis Linux 2.6.15)
Surveiller chemin seulement sâil sâagit dâun rĂ©pertoire ; il rĂ©sulte une erreur ENOTDIR si chemin nâest pas un rĂ©pertoire. Utiliser cet attribut fournit Ă une application un moyen sans problĂšme de concurrence de sâassurer quâun objet surveillĂ© est un rĂ©pertoire.
IN_MASK_CREATE (depuis Linux 4.18)
Surveiller chemin seulement sâil nây a pas dĂ©jĂ une surveillance qui lui est associĂ©e ; il rĂ©sulte une erreur EEXIST si chemin est dĂ©jĂ surveillĂ©.
Utiliser cet attribut fournit Ă une application un moyen de sâassurer que de nouveaux Ă©lĂ©ments de surveillance ne modifient pas ceux qui existent dĂ©jĂ . Câest utile parce que plusieurs chemins peuvent faire rĂ©fĂ©rence au mĂȘme inĆud et plusieurs appels Ă inotify_add_watch (2) sans cet attribut peuvent Ă©craser des masques de surveillance existants.
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 .
/proc interfaces
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.
STANDARDS
Linux.
HISTORIQUE
Inotify a été inclus dans Linux 2.6.13. Les interfaces bibliothÚque nécessaires ont été ajoutées dans la glibc 2.4 ( IN_DONT_FOLLOW , IN_MASK_ADD et IN_ONLYDIR ont été ajoutées dans la glibc 2.5).
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.
Lâensemble des descripteurs surveillĂ©s grĂące Ă un descripteur de fichier inotify peut ĂȘtre vu dans lâentrĂ©e du descripteur de fichier inotify dans le rĂ©pertoire /proc/ pid /fdinfo du processus. Consultez proc (5) pour de plus amples dĂ©tails. FIONREAD ioctl (2) renvoie le nombre dâoctets disponibles Ă la lecture dans un descripteur de fichier inotify.
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).
Les applications devraient aussi considĂ©rer la possibilitĂ© que lâĂ©vĂ©nement IN_MOVED_FROM soit le dernier Ă©vĂ©nement ayant pu entrer dans le tampon renvoyĂ© pour lâappel actuel de read (2) et lâĂ©vĂ©nement IN_MOVED_TO accompagnant pourrait nâĂȘtre rĂ©cupĂ©rĂ© que lors de lâappel read (2) suivant, ce qui devrait ĂȘtre fait avec un (lĂ©ger) dĂ©lai pour permettre que lâinsertion de la paire dâĂ©vĂ©nements IN_MOVED_FROM + IN_MOVED_TO ne soit pas atomique et aussi quâil nây ait pas dâĂ©vĂ©nement IN_MOVED_TO .
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 .
Avant Linux 2.6.16, lâattribut IN_ONESHOT de mask ne fonctionne pas.
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.
Avant Linux 2.6.25, le code du noyau qui Ă©tait censĂ© regrouper deux Ă©vĂ©nements successifs (câest-Ă -dire que les deux Ă©vĂ©nements les plus rĂ©cents pouvaient ĂȘtre fusionnĂ©s si le plus ancien des deux nâavait toujours pas Ă©tĂ© lu) vĂ©rifiait Ă la place si lâĂ©vĂ©nement le plus rĂ©cent pouvait ĂȘtre fusionnĂ© Ă lâĂ©vĂ©nement non lu le plus ancien .
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 (1 Ă 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
Le programme suivant montre lâutilisation de lâinterface de programmation inotify. Il marque les rĂ©pertoires passĂ©s en arguments de ligne de commande et attend les Ă©vĂ©nements de type IN_OPEN , IN_CLOSE_NOWRITE et 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>
/* Lire tous les événements inotify
disponibles Ă partir du
descripteur de fichier « fd ».
wd est le tableau des descripteurs de surveillance pour
les répertoires en argv.
argc est la taille de wd et argv.
argv est la liste des répertoires surveillés.
LâentrĂ©e 0 de wd et argv nâest pas
utilisée. */
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);
}
/* Si le read() non bloquant nâa pas trouvĂ©
dâĂ©vĂ©nement Ă
lire, il renvoie -1 avec errno dĂ©fini Ă
EAGAIN. Dans ce
cas, on sort de la boucle. */
if (len <= 0)
break;
/* Boucler sur tous les événements du tampon.
*/
for (char *ptr = buf; ptr < buf + len;
ptr += sizeof(struct inotify_event) + event->len) {
event = (const struct inotify_event *) ptr;
/* Afficher le type dâĂ©vĂ©nement. */
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: ");
/* Afficher le nom du répertoire surveillé. */
for (size_t i = 1; i < argc; ++i) {
if (wd[i] == event->wd) {
printf("%s/", argv[i]);
break;
}
}
/* Afficher le nom du fichier. */
if (event->len)
printf("%s", event->name);
/* Afficher le type dâobjet de systĂšme de
fichiers. */
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");
/* Créer le descripteur de fichier pour
accĂ©der Ă lâinterface de
programmation inotify. */
fd = inotify_init1(IN_NONBLOCK);
if (fd == -1) {
perror("inotify_init1");
exit(EXIT_FAILURE);
}
/* Allouer la mémoire pour les descripteurs de
surveillance. */
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, "Impossible de surveiller
« %s » : %s\n",
argv[i], strerror(errno));
exit(EXIT_FAILURE);
}
}
/* Préparer pour la scrutation (polling). */
nfds = 2;
fds[0].fd = STDIN_FILENO; /* Entrée de console */
fds[0].events = POLLIN;
fds[1].fd = fd; /* EntrĂ©e dâinotify */
fds[1].events = POLLIN;
/* Attendre les événements ou une
entrée du terminal. */
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) {
/* Entrée de console disponible.
Vider lâentrĂ©e standard et quitter. */
while (read(STDIN_FILENO, &buf, 1) > 0 && buf
!= '\n')
continue;
break;
}
if (fds[1].revents & POLLIN) {
/* Des événements inotify sont disponibles. */
handle_events(fd, wd, argc, argv);
}
}
}
printf("ArrĂȘt de lâĂ©coute
dâĂ©vĂ©nements.\n");
/* Fermer le descripteur de fichier inotify. */
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>, David Prévot <david@tilapin.org>, Thomas Vincent <tvincent@debian.org> et Jean-Pierre Giraud <jean-pierregiraud@neuf.fr>
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 .