Man page - fanotify(7)

Packages contains this manual

Available languages:

en fr ja

Manual

fanotify

NOM
DESCRIPTION
fanotify_init(), fanotify_mark() et groupes de notification
La file d’évĂ©nements
Lecture d’évĂ©nements fanotify
Surveiller un descripteur de fichier fanotify pour les événements
Traitement des événements de permission
Supervision des erreurs des systĂšmes de fichiers
Fermeture du descripteur de fichier fanotify
/proc interfaces
ERREURS
STANDARDS
HISTORIQUE
NOTES
Limites et réserves
BOGUES
EXEMPLES
Exemple de programme : fanotify_example.c
Source du programme : fanotify_example.c
Exemple de programme : fanotify_fid.c
Source du programme : fanotify_fid.c
VOIR AUSSI
TRADUCTION

NOM

fanotify – Surveiller les Ă©vĂ©nements des systĂšmes de fichiers

DESCRIPTION

L’interface de programmation fanotify permet la notification et l’interception des Ă©vĂ©nements du systĂšme de fichiers. La recherche de virus et la gestion de stockage hiĂ©rarchisĂ© font partie des cas d’utilisation. Dans l’interface originelle seul un ensemble limitĂ© d’évĂ©nements Ă©tait pris en charge. En particulier, les Ă©vĂ©nements de crĂ©ation, de suppression ou de dĂ©placement n’étaient pas pris en charge. La prise en charge de ces Ă©vĂšnements a Ă©tĂ© ajoutĂ©e dans Linux 5.1. Consultez inotify (7) pour plus de prĂ©cisions sur l’interface qui ne notifiait pas ces Ă©vĂšnements avant Linux 5.1.

La capacitĂ© de surveiller tous les objets d’un systĂšme de fichiers montĂ©, la capacitĂ© de dĂ©cider des droits d’accĂšs et la possibilitĂ© de lire ou modifier les fichiers avant qu’ils ne soient accĂ©dĂ©s par d’autres applications font partie des capacitĂ©s supplĂ©mentaires Ă  celles de l’interface de programmation inotify (7).

Les appels systÚme suivants sont utilisés avec cette interface de programmation : fanotify_init (2), fanotify_mark (2), read (2), write (2) et close (2).

fanotify_init(), fanotify_mark() et groupes de notification

L’appel systĂšme fanotify_init (2) crĂ©e et initialise un groupe de notifications fanotify et renvoie un descripteur de fichier le rĂ©fĂ©rençant.

Un groupe de notifications fanotify est un objet interne au noyau qui contient une liste de fichiers, répertoires et points de montage pour lesquels des événements seront créés.

Pour chaque entrĂ©e dans un groupe de notifications fanotify, deux masques binaires sont prĂ©sents : le masque mark et le masque ignore . Le masque mark dĂ©finit les activitĂ©s de fichier pour lesquelles un Ă©vĂ©nement doit ĂȘtre créé. Le masque ignore dĂ©finit les activitĂ©s pour lesquelles aucun Ă©vĂ©nement ne doit ĂȘtre créé. Avoir ces deux types de masque permet Ă  un point de montage ou Ă  un rĂ©pertoire d’ĂȘtre marquĂ© pour recevoir des Ă©vĂ©nements, tout en ignorant en mĂȘme temps les Ă©vĂ©nements pour des objets spĂ©cifiques dans ce point de montage ou rĂ©pertoire.

L’appel systĂšme fanotify_mark (2) ajoute un fichier, rĂ©pertoire ou point de montage Ă  un groupe de notifications et indique les Ă©vĂ©nements qui doivent ĂȘtre signalĂ©s (ou ignorĂ©s), ou supprime ou modifie une telle entrĂ©e.

Le masque ignore peut servir pour un cache de fichier. Les Ă©vĂ©nements intĂ©ressants pour un cache de fichier sont la modification et la fermeture d’un fichier. Ainsi, le rĂ©pertoire ou point de montage en cache va ĂȘtre marquĂ© pour recevoir ces Ă©vĂ©nements. AprĂšs la rĂ©ception du premier Ă©vĂ©nement informant qu’un fichier a Ă©tĂ© modifiĂ©, l’entrĂ©e correspondante du cache sera dĂ©sactivĂ©e. Aucun autre Ă©vĂ©nement de modification pour ce fichier ne sera utile jusqu’à sa fermeture. Ainsi, l’évĂ©nement de modification peut ĂȘtre ajoutĂ© au masque ignore. Lors de la rĂ©ception d’un Ă©vĂ©nement de fermeture, l’évĂ©nement de modification peut ĂȘtre supprimĂ© du masque ignore et l’entrĂ©e de cache de fichier peut ĂȘtre mise Ă  jour.

Les entrĂ©es des groupes de notification fanotify font rĂ©fĂ©rence aux fichiers et rĂ©pertoires Ă  l’aide de leur numĂ©ro d’inƓud et aux montages Ă  l’aide de leur identifiant de montage. Si les fichiers ou rĂ©pertoires sont renommĂ©s ou dĂ©placĂ©s dans le mĂȘme montage, les entrĂ©es correspondantes survivent. Si les fichiers ou rĂ©pertoires sont supprimĂ©s ou dĂ©placĂ©s dans un autre montage ou si les montages sont dĂ©montĂ©s, les entrĂ©es correspondantes sont supprimĂ©es.

La file d’évĂ©nements

Comme les Ă©vĂ©nements surviennent sur les objets de systĂšme de fichiers surveillĂ©s par un groupe de notifications, le systĂšme fanotify gĂ©nĂšre les Ă©vĂ©nements qui sont collectĂ©s dans une file. Ces Ă©vĂ©nements peuvent ĂȘtre lus (en utilisant read (2) ou similaire) Ă  partir du descripteur de fichier fanotify renvoyĂ© par fanotify_init (2).

Deux types d’évĂ©nements sont créés : les Ă©vĂ©nements de notification et les Ă©vĂ©nements de permission . Les Ă©vĂ©nements de notification sont surtout informatifs et ne nĂ©cessitent pas d’action Ă  prendre par l’application qui les reçoit Ă  part pour la fermeture du descripteur de fichier valable passĂ© dans l’évĂ©nement (voir ci-dessous). Les Ă©vĂ©nements de permission sont des demandes Ă  l’application qui les reçoit pour dĂ©cider si les droits d’accĂšs Ă  un fichier doivent ĂȘtre attribuĂ©s. Pour ces Ă©vĂ©nements, le destinataire doit Ă©crire une rĂ©ponse qui dĂ©cide d’attribuer l’accĂšs ou non.

Un Ă©vĂ©nement est supprimĂ© de la file d’évĂ©nements du groupe fanotify quand il a Ă©tĂ© lu. Les Ă©vĂ©nements de permission qui ont Ă©tĂ© lus sont gardĂ©s dans une liste interne du groupe fanotify jusqu’à ce qu’une dĂ©cision d’attribution de droits ait Ă©tĂ© prise en Ă©crivant dans le descripteur de fichier fanotify ou que le descripteur de fichier fanotify soit fermĂ©.

Lecture d’évĂ©nements fanotify

Appeler read (2) pour le descripteur de fichier renvoyĂ© par fanotify_init (2) bloque (si l’attribut FAN_NONBLOCK n’est pas indiquĂ© dans l’appel de fanotify_init (2)) jusqu’à ce qu’un Ă©vĂ©nement de fichier survienne ou que l’appel soit interrompu par un signal (consultez signal (7)).

AprÚs un read (2) réussi, le tampon de lecture contient une ou plus des structures suivantes :

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

Les enregistrements d’information sont des piĂšces d’information supplĂ©mentaires qui peuvent ĂȘtre fournies en mĂȘme temps que la structure gĂ©nĂ©rique, fanotify_event_metadata . Les flag passĂ©s Ă  fanotify_init (2) ont une influence sur le type d’enregistrement d’information qui peut ĂȘtre renvoyĂ© pour l’évĂšnement. Par exemple, si un groupe de notifications est initialisĂ© avec FAN_REPORT_FID ou FAN_REPORT_DIR_FID , les Ă©couteurs d’évĂšnement pourront s’attendre aussi Ă  recevoir une structure fanotify_event_info_fid en mĂȘme temps que la structure fanotify_event_metadata par laquelle les gestionnaires de fichier sont utilisĂ©s pour identifier des objets de systĂšme de fichiers plutĂŽt que des descripteurs de fichier. Les enregistrements d’information peuvent ĂȘtre aussi empilĂ©s, signifiant qu’utiliser les divers flag FAN_REPORT_* en mĂȘme temps que l’un ou l’autre est pris en charge. Dans de tels cas, plusieurs enregistrements d’information peuvent ĂȘtre renvoyĂ©s pour un Ă©vĂšnement en mĂȘme temps que la structure gĂ©nĂ©rique fanotify_event_metadata . Par exemple, si un groupe de notifications est initialisĂ© avec FAN_REPORT_TARGET_FID et FAN_REPORT_PIDFD , un Ă©couteur d’évĂšnement peut s’attendre Ă  recevoir jusqu’à deux enregistrements d’information fanotify_event_info_fid et un enregistrement d’information fanotify_event_info_pidfd en mĂȘme temps que la structure gĂ©nĂ©rique fanotify_event_metadata . Notablement, fanotify ne fournit aucune garantie sur l’ordre des enregistrements d’information quand un groupe de notifications est initialisĂ© avec une configuration basĂ©e sur l’empilage. Chaque enregistrement d’information a une structure imbriquĂ©e de type fanotify_event_info_header . Il est impĂ©ratif pour les Ă©couteurs d’évĂšnement d’inspecter le champ info_type de cette structure pour dĂ©terminer le type d’enregistrement d’information qui a Ă©tĂ© reçu pour un Ă©vĂšnement donnĂ©.

Dans le cas d’un groupe fanotify qui identifie des objets de systĂšme de fichiers par des gestionnaires de fichiers, les Ă©couteurs d’évĂ©nement espĂšrent recevoir un ou plusieurs objets d’enregistrement d’informations ci-dessous en mĂȘme temps que la structure gĂ©nĂ©rique fanotify_event_metadata dans le tampon de lecture :

struct fanotify_event_info_fid {
struct fanotify_event_info_header hdr;
__kernel_fsid_t fsid;
unsigned char handle[];
};

Dans le cas oĂč un groupe fanotify est initialisĂ© avec FAN_REPORT_PIDFD , les Ă©couteurs d’évĂšnement doivent s’attendre Ă  recevoir l’objet d’enregistrement d’information ci-dessous en mĂȘme temps que la structure fanotify_event_metadata dans le tampon de lecture :

struct fanotify_event_info_pidfd {
struct fanotify_event_info_header hdr;
__s32 pidfd;
};

Dans le cas d’un Ă©vĂšnement FAN_FS_ERROR , un enregistrement supplĂ©mentaire d’information dĂ©crivant l’erreur qui s’est produite est renvoyĂ© en mĂȘme temps que la structure fanotify_event_metadata gĂ©nĂ©rique dans le tampon de lecture. Cette structure est dĂ©finie comme suit :

struct fanotify_event_info_error {
struct fanotify_event_info_header hdr;
__s32 error;
__u32 error_count;
};

Tous les enregistrements d’information contiennent une structure imbriquĂ©e de type fanotify_event_info_header . Cette structure contient des mĂ©ta-informations sur l’enregistrement d’information qui a pu ĂȘtre renvoyĂ© en mĂȘme temps que la structure fanotify_event_metadata gĂ©nĂ©rique. Cette structure est dĂ©finie comme suit :

struct fanotify_event_info_header {

__u8 info_type;

__u8 pad;

__u16 len;

};

Pour des raisons de performances, une grande taille de tampon (par exemple 4096 octets) est conseillĂ©e pour que plusieurs Ă©vĂ©nements puissent ĂȘtre rĂ©cupĂ©rĂ©s en une seule lecture.

La valeur de retour de read (2) est le nombre d’octets placĂ©s dans le tampon, ou -1 en cas d’erreur (mais consultez BOGUES ).

Les membres de la structure fanotify_event_metadata sont les suivants.
event_len

C’est la taille des donnĂ©es pour l’évĂ©nement actuel et la position du prochain Ă©vĂ©nement dans le tampon. À moins que le groupe identifie des objets du systĂšme de fichiers par des gestionnaires de fichiers, la valeur d’ event_len est toujours FAN_EVENT_METADATA_LEN . Pour un groupe qui identifie les objets du systĂšme de fichiers par des gestionnaires de fichiers, event_len inclut aussi des enregistrements d’identificateur de fichier de taille variable.

vers

Ce champ contient un numĂ©ro de version pour la structure. Il doit ĂȘtre comparĂ© Ă  FANOTIFY_METADATA_VERSION pour vĂ©rifier que les structures renvoyĂ©es pendant l’exĂ©cution correspondent aux structures dĂ©finies Ă  la compilation. En cas d’erreur de correspondance, l’application devrait arrĂȘter d’essayer d’utiliser le descripteur de fichier fanotify.

reserved

Ce champ n’est pas utilisĂ©.

metadata_len

C’est la taille de la structure. Le champ a Ă©tĂ© introduit pour faciliter l’implĂ©mentation d’en-tĂȘtes facultatifs par type d’évĂ©nement. Aucun en-tĂȘte facultatif n’existe dans l’implĂ©mentation actuelle.

mask

C’est un masque binaire dĂ©crivant l’évĂ©nement (voir ci-dessous).

fd

C’est un descripteur de fichier ouvert pour l’objet actuellement accĂ©dĂ© ou FAN_NOFD si un dĂ©passement de file est survenu. Avec un groupe fanotify qui identifie les objets de systĂšme d’exploitation par des gestionnaires de fichiers, les applications doivent escompter que cette valeur soit FAN_NOFD pour chaque Ă©vĂšnement qu’elles reçoivent. Le descripteur de fichier peut ĂȘtre utilisĂ© pour accĂ©der au contenu du fichier ou rĂ©pertoire surveillĂ©. L’application qui lit est responsable de la fermeture de ce descripteur de fichier.

Lors d’un appel de fanotify_init (2), l’appelant pourrait indiquer (Ă  l’aide de l’argument event_f_flags ) plusieurs attributs d’état de fichier Ă  dĂ©finir dans la description de fichier ouverte qui correspond Ă  ce descripteur de fichier. De plus, l’attribut d’état de fichier FMODE_NONOTIFY (interne au noyau) est dĂ©fini dans la description de fichier ouverte. L’attribut supprime la crĂ©ation d’évĂ©nement fanotify. Ainsi, quand le destinataire de l’évĂ©nement fanotify accĂšde au fichier ou rĂ©pertoire notifiĂ© en utilisant ce descripteur de fichier, aucun Ă©vĂ©nement supplĂ©mentaire n’est créé.

pid

Si l’attribut FAN_REPORT_TID Ă©tait rĂ©glĂ© dans fanotify_init (2), c’est l’identifiant (TID) du thread qui a provoquĂ© cet Ă©vĂšnement. Sinon, c’est le PID du processus qui a provoquĂ© cet Ă©vĂšnement.

Un programme Ă©coutant les Ă©vĂ©nements fanotify peut comparer ce PID au PID renvoyĂ© par getpid (2) pour dĂ©terminer si l’évĂ©nement est provoquĂ© par l’écoutant lui-mĂȘme ou par un autre processus accĂ©dant au fichier.

Le masque binaire mask indique les Ă©vĂ©nements survenus pour un seul objet de systĂšme de fichiers. Plusieurs bits pourraient ĂȘtre dĂ©finis dans ce masque si plus d’un Ă©vĂ©nement est survenu pour l’objet de systĂšme de fichiers surveillĂ©. En particulier, les Ă©vĂ©nements consĂ©cutifs pour le mĂȘme objet de systĂšme de fichiers et originaires du mĂȘme processus pourraient ĂȘtre fusionnĂ©s dans un seul Ă©vĂ©nement, mais deux Ă©vĂ©nements de permission ne sont jamais fusionnĂ©s dans une entrĂ©e de file.

Les bits pouvant apparaĂźtre dans mask sont les suivants.
FAN_ACCESS

Un fichier ou un répertoire (mais consultez BOGUES ) a été accédé (en lecture).

FAN_OPEN

Un fichier ou un répertoire a été ouvert.

FAN_OPEN_EXEC

Un fichier a Ă©tĂ© ouvert dans le but d’ĂȘtre exĂ©cutĂ©. Consultez NOTES dans fanotify_mark (2) pour plus de dĂ©tails.

FAN_ATTRIB

Une mĂ©tadonnĂ©e de fichier ou d’un rĂ©pertoire a Ă©tĂ© modifiĂ©e.

FAN_CREATE

Un fichier enfant ou un répertoire a été créé dans le répertoire surveillé.

FAN_DELETE

Un fichier enfant ou un répertoire a été supprimé dans le répertoire surveillé.

FAN_DELETE_SELF

Un fichier ou un répertoire a été supprimé.

FAN_FS_ERROR

Une erreur de systÚme de fichiers a été détectée.

FAN_RENAME

Un fichier ou un répertoire a été déplacé de ou vers un répertoire parent surveillé.

FAN_MOVED_FROM

Un fichier ou un répertoire a été déplacé du répertoire surveillé.

FAN_MOVED_TO

Un fichier ou un répertoire a été déplacé vers un répertoire parent surveillé.

IN_MOVE_SELF

Un fichier ou un répertoire surveillé a été déplacé.

FAN_MODIFY

Un fichier a été modifié.

FAN_CLOSE_WRITE

Un fichier qui était ouvert en écriture ( O_WRONLY ou O_RDWR ) a été fermé.

FAN_CLOSE_NOWRITE

Un fichier ou un répertoire, qui était ouvert en lecture seule ( O_RDONLY ), a été fermé.

FAN_Q_OVERFLOW

La file d’évĂ©nements a dĂ©passĂ© la limite du nombre d’évĂšnements. Cette limite peut ĂȘtre Ă©crasĂ©e en indiquant l’attribut FAN_UNLIMITED_QUEUE lors de l’appel de fanotify_init (2).

FAN_ACCESS_PERM

Une application veut lire un fichier ou rĂ©pertoire, par exemple en utilisant read (2) ou readdir (2). Le lecteur doit Ă©crire une rĂ©ponse (telle que dĂ©crite ci-dessous) qui dĂ©termine si le droit d’accĂšs Ă  l’objet de systĂšme de fichiers sera attribuĂ©.

FAN_OPEN_PERM

Une application veut ouvrir un fichier ou un rĂ©pertoire. Le lecteur doit Ă©crire une rĂ©ponse qui dĂ©termine si le droit d’ouvrir l’objet de systĂšme de fichiers sera attribuĂ©.

FAN_OPEN_EXEC_PERM

Une application veut ouvrir un fichier pour une exĂ©cution. Le lecteur doit Ă©crire une rĂ©ponse qui dĂ©termine si le droit d’ouvrir l’objet de systĂšme de fichiers sera attribuĂ©. Consultez NOTES dans fanotify_mark (2) pour plus de dĂ©tails.

Pour vĂ©rifier tous les Ă©vĂ©nements fermĂ©s, le masque binaire suivant pourrait ĂȘtre utilisé :
FAN_CLOSE

Un fichier a Ă©tĂ© fermĂ©. C’est un synonyme de :

FAN_CLOSE_WRITE | FAN_CLOSE_NOWRITE

Pour vĂ©rifier tous les Ă©vĂ©nements de dĂ©placement, le masque binaire suivant pourrait ĂȘtre utilisé :
FAN_MOVE

Un fichier ou un rĂ©pertoire a Ă©tĂ© dĂ©placĂ©. C’est un synonyme de :

FAN_MOVED_FROM | FAN_MOVED_TO

Les bits suivants peuvent apparaĂźtre dans mask seulement conjointement avec d’autres bits de type d’évĂšnement :
FAN_ONDIR

Les Ă©vĂšnements dĂ©crits dans le mask se sont dĂ©roulĂ©s dans un objet de rĂ©pertoire. Le rapport d’évĂšnements dans des rĂ©pertoires requiert le rĂ©glage de cet attribut dans le masque mark . Consultez fanotify_mark (2) pour plus de dĂ©tails. L’attribut FAN_ONDIR est rapportĂ© dans un masque d’évĂšnement seulement si le groupe fanotify identifie les objets de systĂšme d’exploitation avec des gestionnaires de fichiers.

Les enregistrements d’information qui sont fournis en mĂȘme temps que la structure fanotify_event_metadata gĂ©nĂ©rique contiendront toujours une structure imbriquĂ©e de type fanotify_event_info_header . Les membres de fanotify_event_info_header sont les suivants :
info_type

Valeur entiĂšre unique reprĂ©sentant le type d’objet d’enregistrement d’information reçu pour un Ă©vĂšnement. Ce champ peut ĂȘtre dĂ©fini Ă  une des valeurs suivantes : FAN_EVENT_INFO_TYPE_FID , FAN_EVENT_INFO_TYPE_DFID , FAN_EVENT_INFO_TYPE_DFID_NAME ou FAN_EVENT_INFO_TYPE_PIDFD . L’ensemble des valeurs pour ce champ est dĂ©pendant des drapeaux qui ont Ă©tĂ© fournis Ă  fanotify_init (2). Se rĂ©fĂ©rer aux dĂ©tails des champs pour chaque type d’objet d’enregistrement d’information ci-dessous pour apprĂ©hender les diffĂ©rents cas dans lesquels les valeurs info_type peuvent ĂȘtre dĂ©finies.

pad

Ce champ n’est actuellement utilisĂ© par aucun type d’objet d’enregistrement d’information et, par consĂ©quent, est dĂ©fini Ă  zĂ©ro.

len

La valeur de len est dĂ©finie Ă  la taille de l’objet d’enregistrement d’information, incluant le fanotify_event_info_header . La taille totale de tous les enregistrements d’information supplĂ©mentaires ne peut ĂȘtre supĂ©rieure Ă  ( event_len - metadata_len ).

Les membres de la structure fanotify_event_info_fid sont les suivants.

hdr

C’est une structure de type fanotify_event_info_header . Par exemple, quand un descripteur de fichier fanotify est créé en utilisant FAN_REPORT_FID , un enregistrement unique est supposĂ© ĂȘtre attachĂ© Ă  l’évĂšnement avec la valeur de champ info_type de FAN_EVENT_INFO_TYPE_FID . Quand un descripteur de fichier fanotify est créé en utilisant la combinaison de FAN_REPORT_FID et FAN_REPORT_DIR_FID , il peut y avoir deux enregistrements d’informations attachĂ©s Ă  l’évĂšnement : un avec une valeur de champ info_type de FAN_EVENT_INFO_TYPE_DFID , identifiant un objet de rĂ©pertoire parent, et un avec une valeur de champ info_type de FAN_EVENT_INFO_TYPE_FID , identifiant un objet enfant. Il est Ă  remarquer que pour des Ă©vĂšnements de modification d’entrĂ©e de rĂ©pertoire FAN_CREATE , FAN_DELETE , FAN_MOVE et FAN_RENAME , un enregistrement d’information identifiant l’objet enfant créé, supprimĂ© ou dĂ©placĂ© est rapportĂ© seulement si un groupe fanotify a Ă©tĂ© initialisĂ© avec le drapeau FAN_REPORT_TARGET_FID .

fsid

C’est un identifiant unique du systĂšme de fichiers contenant l’objet associĂ© avec l’évĂšnement. C’est une structure de type __kernel_fsid_t et elle contient la mĂȘme valeur que f_fsid lors de l’appel statfs (2).

handle

Ce champ contient une structure de taille variable de type struct file_handle . C’est un gestionnaire opaque qui correspond Ă  un objet prĂ©cis de systĂšme de fichiers comme renvoyĂ© par name_to_handle_at (2). Il peut ĂȘtre utilisĂ© uniquement pour identifier un fichier d’un systĂšme de fichiers et peut ĂȘtre passĂ© comme argument Ă  open_by_handle_at (2). Si la valeur du champ info_type est FAN_EVENT_INFO_TYPE_DFID_NAME , le gestionnaire de fichiers est suivi d’un octet NULL final qui identifie le nom d’entrĂ©e de rĂ©pertoire créée/supprimĂ©e/dĂ©placĂ©e. Pour les autres Ă©vĂšnements tels que FAN_OPEN , FAN_ATTRIB , FAN_DELETE_SELF et FAN_MOVE_SELF , si la valeur du champ info_type est FAN_EVENT_INFO_TYPE_FID , le handle identifie l’objet corrĂ©lĂ© Ă  l’évĂšnement. Si la valeur du champ info_type est FAN_EVENT_INFO_TYPE_DFID , le handle identifie l’objet de rĂ©pertoire corrĂ©lĂ© Ă  l’évĂšnement ou le rĂ©pertoire parent d’un objet non-rĂ©pertoire corrĂ©lĂ© Ă  l’évĂšnement. Si la valeur du champ info_type est FAN_EVENT_INFO_TYPE_DFID_NAME , le handle identifie le mĂȘme objet de rĂ©pertoire qui aurait Ă©tĂ© rapportĂ© avec FAN_EVENT_INFO_TYPE_DFID et le gestionnaire de fichier est suivi d’un octet NULL final qui identifie le nom de l’entrĂ©e de rĂ©pertoire dans ce rĂ©pertoire ou « . » pour identifier l’objet du rĂ©pertoire.

Les membres de la structure fanotify_event_info_pidfd sont les suivants.

hdr

C’est une structure de type fanotify_event_info_header . Quand un groupe fanotify est initialisĂ© avec FAN_REPORT_PIDFD , le champ info_type de fanotify_event_info_header est dĂ©fini Ă  FAN_EVENT_INFO_TYPE_PIDFD .

pidfd

C’est un descripteur de fichier de processus qui fait rĂ©fĂ©rence au processus responsable de la gĂ©nĂ©ration de l’évĂšnement. Le descripteur de fichier de processus n’est pas diffĂ©rent de celui qui pourrait ĂȘtre obtenu manuellement si pidfd_open (2) Ă©tait appelĂ© sur fanotify_event_metadata.pid . Dans cette instance oĂč une erreur pourrait se produire lors de la crĂ©ation de pidfd, un des deux types d’erreur possibles reprĂ©sentĂ©s par un entier nĂ©gatif pourrait ĂȘtre renvoyĂ© dans ce champ pidfd . Dans le cas oĂč le processus responsable de la crĂ©ation de l’évĂšnement s’est terminĂ© avant que l’écouteur d’évĂšnement soit capable de lire des Ă©vĂšnements dans la file de notifications, FAN_NOPIDFD est renvoyĂ©. La crĂ©ation de pidfd pour un Ă©vĂšnement est seulement faite au moment oĂč les Ă©vĂšnements sont lus Ă  partir de la file de notifications. Tous les autres Ă©checs possibles de crĂ©ation de pidfd sont reprĂ©sentĂ©s par FAN_EPIDFD . Une fois que l’écouteur d’évĂšnement a traitĂ© un Ă©vĂšnement et que le pidfd n’est plus nĂ©cessaire, celui-ci sera fermĂ© Ă  l’aide de close (2).

Les membres de la structure fanotify_event_info_error sont les suivants.

hdr

C’est une structure de type fanotify_event_info_header . Le champ info_type est dĂ©fini Ă  FAN_EVENT_INFO_TYPE_ERROR .

error

Ce champ identifie le type d’erreur qui s’est produite.

error_count

C’est un compteur du nombre d’erreurs supprimĂ©es depuis que la derniĂšre erreur a Ă©tĂ© lue.

Les macros suivantes sont fournies pour itĂ©rer sur un tampon contenant les mĂ©tadonnĂ©es d’évĂ©nement fanotify renvoyĂ©es par read (2) Ă  partir d’un descripteur de fichier fanotify.
FAN_EVENT_OK(meta, len)

Cette macro compare la taille restante len du tampon meta à la taille de la structure de métadonnées et au champ event_len de la premiÚre structure de métadonnées du tampon.

FAN_EVENT_NEXT(meta, len)

Cette macro utilise la taille indiquĂ©e dans le champ event_len de la structure de mĂ©tadonnĂ©es pointĂ©e par meta pour calculer l’adresse de la prochaine structure de mĂ©tadonnĂ©es qui suit meta . len est le nombre d’octets de mĂ©tadonnĂ©es qui restent actuellement dans le tampon. La macro renvoie un pointeur vers la prochaine structure de mĂ©tadonnĂ©es qui suit meta et rĂ©duit len du nombre d’octets dans la structure de mĂ©tadonnĂ©es qui a Ă©tĂ© sautĂ©e (c’est-Ă -dire qu’elle soustrait meta->event_len de len ).

De plus, il existe :
FAN_EVENT_METADATA_LEN

Cette macro renvoie la taille (en octet) de la structure fanotify_event_metadata . C’est la taille minimale (et actuellement la seule taille) de mĂ©tadonnĂ©es d’évĂ©nements.

Surveiller un descripteur de fichier fanotify pour les événements

Quand un événement fanotify survient, le descripteur de fichier fanotify est indiqué comme lisible lorsque passé à epoll (7), poll (2) ou select (2).

Traitement des événements de permission

Pour les Ă©vĂ©nements de permission, l’application doit Ă©crire (avec write (2)) une structure de la forme suivante sur le descripteur de fichier fanotify :

struct fanotify_response {
__s32 fd;
__u32 response;
};

Les membres de cette structure sont les suivants :

fd

C’est le descripteur de fichier de la structure fanotify_event_metadata .

response

Ce champ indique si les droits doivent ĂȘtre attribuĂ©s ou non. Cette valeur doit ĂȘtre soit FAN_ALLOW pour permettre l’opĂ©ration de fichier, soit FAN_DENY pour refuser l’opĂ©ration de fichier.

Si l’accĂšs est refusĂ©, l’appel de l’application requĂ©rante recevra une erreur EPERM . De plus, si le groupe de notifications a Ă©tĂ© créé avec l’attribut FAN_ENABLE_AUDIT , alors l’attribut FAN_AUDIT peut ĂȘtre dĂ©fini dans le champ response . Dans ce cas, le sous-systĂšme d’audit journalisera l’information Ă  propos de la dĂ©cision d’accĂšs aux journaux d’audit.

Supervision des erreurs des systĂšmes de fichiers

Un seul Ă©vĂšnement FAN_FS_ERROR Ă  la fois est stockĂ© par systĂšme de fichiers. Les messages d’erreur supplĂ©mentaires sont supprimĂ©s et comptĂ©s dans le champ error_count dans l’enregistrement existant d’évĂšnement FAN_FS_ERROR , mais les dĂ©tails Ă  propos des erreurs sont perdus.

Les erreurs rapportĂ©es par FAN_FS_ERROR sont des erreurs gĂ©nĂ©riques errno , mais tous les types d’erreur ne sont pas rapportĂ©s par tous les systĂšmes de fichiers.

Les erreurs ne concernant pas directement un fichier (c’est-Ă -dire des corruptions de superbloc) sont rapportĂ©es avec un handle non valable. Pour ces erreurs, le handle aura le champ handle_type dĂ©fini Ă  FILEID_INVALID et la taille de tampon de handle dĂ©finie Ă  0 .

Fermeture du descripteur de fichier fanotify

Quand tous les descripteurs de fichier se rĂ©fĂ©rant au groupe de notifications fanotify sont fermĂ©s, le groupe fanotify est libĂ©rĂ© et ses ressources sont libĂ©rĂ©es pour ĂȘtre rĂ©utilisĂ©es par le noyau. Lors de l’appel de close (2), les Ă©vĂ©nements de permission restants seront dĂ©finis Ă  permis.

/proc interfaces

Le fichier /proc/ pid /fdinfo/ fd contient des renseignements sur les marques fanotify pour le descripteur de fichier fd du processus pid . Consulter proc (5) pour plus de précisions.

Depuis Linux 5.13, les interfaces suivantes peuvent ĂȘtre utilisĂ©es pour contrĂŽler la quantitĂ© de ressources du noyau utilisĂ©es par fanotify :
/proc/sys/fs/fanotify/max_queued_events

La valeur dans ce fichier est utilisĂ©e quand une application appelle fanotify_init (2) pour dĂ©finir la limite supĂ©rieure du nombre d’évĂšnements qui peuvent ĂȘtre mis dans la file d’attente du groupe fanotify correspondant. Les Ă©vĂšnements qui font que cette limite est dĂ©passĂ©e sont abandonnĂ©s, mais un Ă©vĂšnement FAN_Q_OVERFLOW est toujours gĂ©nĂ©rĂ©. Avant le noyau 5.13 de Linux, la limite codĂ©e en dur Ă©tait de 16384 évĂšnements.

/proc/sys/fs/fanotify/max_user_group

La valeur dans ce fichier dĂ©finit la limite supĂ©rieure du nombre de groupes fanotify pouvant ĂȘtre créés par ID rĂ©el d’utilisateur. Avant le noyau 5.13 de Linux, la limite codĂ©e en dur Ă©tait de 128 groupes par utilisateur.

/proc/sys/fs/fanotify/max_user_marks

La valeur dans ce fichier dĂ©finit la limite supĂ©rieure du nombre de marques fanotify pouvant ĂȘtre créées par ID rĂ©el d’utilisateur. Avant le noyau 5.13 de Linux, la limite codĂ©e en dur Ă©tait de 8192 marques par groupe (pas par utilisateur).

ERREURS

En plus des erreurs habituelles de read (2), les erreurs suivantes peuvent survenir lors de la lecture d’un descripteur de fichier fanotify.

EINVAL

Le tampon est trop petit pour contenir l’évĂ©nement.

EMFILE

La limite par processus du nombre de fichiers ouverts a été atteinte. Consultez la description de RLIMIT_NOFILE dans getrlimit (2).

ENFILE

La limite du nombre de fichiers ouverts sur le systÚme a été atteinte. Consultez /proc/sys/fs/file-max dans proc (5).

ETXTBSY

Cette erreur est renvoyĂ©e par read (2) si O_RDWR ou O_WRONLY ont Ă©tĂ© indiquĂ©s dans l’argument event_f_flags lors de l’appel fanotify_init (2) et qu’un Ă©vĂ©nement est survenu pour un fichier surveillĂ© actuellement en cours d’exĂ©cution.

En plus des erreurs habituelles de write (2), les erreurs suivantes peuvent survenir lors de l’écriture sur un descripteur de fichier fanotify.

EINVAL

Les droits d’accĂšs fanotify ne sont pas activĂ©s dans la configuration du noyau ou la valeur de response dans la structure de rĂ©ponse n’est pas valable.

ENOENT

Le descripteur de fichier fd dans la structure de rĂ©ponse n’est pas valable. Cela pourrait survenir quand une rĂ©ponse pour l’évĂ©nement de permission a dĂ©jĂ  Ă©tĂ© Ă©crite.

STANDARDS

Linux.

HISTORIQUE

L’interface de programmation fanotify a Ă©tĂ© introduite dans Linux 2.6.36 et activĂ©e dans Linux 2.6.37. La prise en charge de fdinfo a Ă©tĂ© ajoutĂ©e dans Linux 3.8.

NOTES

L’interface de programmation fanotify n’est disponible que si le noyau a Ă©tĂ© construit avec l’option de configuration CONFIG_FANOTIFY activĂ©e. De plus, le traitement de permission fanotify n’est disponible que si l’option de configuration CONFIG_FANOTIFY_ACCESS_PERMISSIONS est activĂ©e.

Limites et réserves

Fanotify ne signale que les Ă©vĂ©nements dĂ©clenchĂ©s par un programme en espace utilisateur Ă  l’aide d’une 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.

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

Les Ă©vĂ©nements pour rĂ©pertoire ne sont créés que si le rĂ©pertoire lui-mĂȘme est ouvert, lu et fermĂ©. Ajouter, supprimer ou modifier les enfants d’un rĂ©pertoire marquĂ© ne crĂ©e pas d’évĂ©nement pour le rĂ©pertoire surveillĂ© lui-mĂȘme.

La surveillance fanotify des rĂ©pertoires n’est pas rĂ©cursive : pour surveiller les sous-rĂ©pertoires, des marques supplĂ©mentaires doivent ĂȘtre créées. L’évĂšnement FAN_CREATE peut ĂȘtre utilisĂ© pour dĂ©tecter quand un sous-rĂ©pertoire a Ă©tĂ© créé dans un rĂ©pertoire marquĂ©. Une marque supplĂ©mentaire doit ĂȘtre dĂ©finie dans le sous-rĂ©pertoire nouvellement créé. Cette approche crĂ©e une situation de compĂ©tition, parce qu’elle peut perdre les Ă©vĂšnements qui se produisent dans le nouveau sous-rĂ©pertoire avant qu’une marque soit ajoutĂ©e dans ce sous-rĂ©pertoire. La surveillance des montages offre la capacitĂ© de surveiller un arbre entier de rĂ©pertoires sans ce problĂšme de chronologie. La surveillance de systĂšme de fichiers offre la capacitĂ© de surveiller tout montage d’une instance de systĂšme de fichiers sans situation de compĂ©tition.

La file d’évĂ©nements peut dĂ©border. Dans ce cas, les Ă©vĂ©nements sont perdus.

BOGUES

Avant Linux 3.19, fallocate (2) ne crĂ©ait pas d’évĂ©nement fanotify. Depuis Linux 3.19, les appels Ă  fallocate (2) crĂ©ent des Ă©vĂ©nements FAN_MODIFY .

Dans Linux 3.17, les bogues suivants existent :

-

Dans Linux, un objet du systĂšme de fichiers pourrait ĂȘtre accessible par de multiples chemins. Par exemple, une partie d’un systĂšme de fichiers pourrait ĂȘtre remontĂ©e avec l’option --bind de mount (8). Un Ă©coutant ayant marquĂ© un montage ne sera notifiĂ© que des Ă©vĂ©nements dĂ©clenchĂ©s pour un objet du systĂšme de fichiers utilisant le mĂȘme montage. Tout autre Ă©vĂ©nement passera inaperçu.

-

Quand un Ă©vĂ©nement est créé, aucune vĂ©rification n’est effectuĂ©e pour voir si l’identifiant utilisateur du processus recevant a le droit de lire ou Ă©crire le fichier avant de passer un descripteur de fichier pour ce fichier. Cela pose un risque de sĂ©curitĂ© quand la capacitĂ© CAP_SYS_ADMIN est dĂ©finie pour un programme exĂ©cutĂ© par les utilisateurs ordinaires.

-

Si un appel de read (2) traite plusieurs Ă©vĂ©nements de la file fanotify et qu’une erreur survient, la valeur de retour sera la taille totale des Ă©vĂ©nements copiĂ©s correctement dans le tampon d’espace utilisateur avant que l’erreur ne survienne. La valeur de retour ne sera pas -1 et errno ne sera pas dĂ©finie. Ainsi, l’application lisant n’a aucun moyen de dĂ©tecter l’erreur.

EXEMPLES

Les deux programmes ci-dessous montrent l’utilisation de l’API de fanotify.

Exemple de programme : fanotify_example.c

Le programme suivant montre l’utilisation de l’interface de programmation fanotify avec les informations d’évĂšnements d’objet passĂ©es sous la forme d’un descripteur de fichier. Il marque le point de montage passĂ© en argument de ligne de commande et attend les Ă©vĂ©nements de type FAN_OPEN_PERM et FAN_CLOSE_WRITE . Quand un Ă©vĂ©nement de permission survient, une rĂ©ponse FAN_ALLOW est donnĂ©e.

La sortie suivante de session d’interprĂ©teur de commande montre un exemple de l’exĂ©cution de ce programme. Cette session concerne l’édition du fichier /home/utilisateur/temp/notes . Avant d’ouvrir le fichier, un Ă©vĂ©nement FAN_OPEN_PERM est survenu. AprĂšs la fermeture du fichier, un Ă©vĂ©nement FAN_CLOSE_WRITE est survenu. L’exĂ©cution du programme se termine quand l’utilisateur appuie sur la touche EntrĂ©e.

# ./fanotify_exemple /home
Appuyer sur la touche Entrée pour quitter.
En Ă©coute d’évĂ©nements.
FAN_OPEN_PERM : Fichier /home/utilisateur/temp/notes
FAN_CLOSE_WRITE : Fichier /home/utilisateur/temp/notes
Écoute des Ă©vĂšnements arrĂȘtĂ©e.

Source du programme : fanotify_example.c

#define _GNU_SOURCE /* Nécessaire pour obtenir la définition de O_LARGEFILE */
#include <errno.h>
#include <fcntl.h>
#include <limits.h>
#include <poll.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/fanotify.h>
#include <unistd.h>
/* Lire tous les évÚnements fanotify disponibles du descripteur de fichier « fd ». */
static void
handle_events(int fd)
{
const struct fanotify_event_metadata *metadata;
struct fanotify_event_metadata buf[200];
ssize_t len;
char path[PATH_MAX];
ssize_t path_len;
char procfd_path[PATH_MAX];
struct fanotify_response response;
/* Bouclage tant que des Ă©vĂšnements peuvent ĂȘtre lus du descripteur de fichier. */
for (;;) {
/* Lecture de quelques évÚnements. */
len = read(fd, buf, sizeof(buf));
if (len == -1 && errno != EAGAIN) {
perror("read");
exit(EXIT_FAILURE);
}
/* Vérification que la fin des données disponibles soit atteinte. */
if (len <= 0)
break;
/* Pointage vers le premier évÚnement dans le tampon. */
metadata = buf;
/* Bouclage sur tous les évÚnements du tampon. */
while (FAN_EVENT_OK(metadata, len)) {
/* VĂ©rification que les structures d’exĂ©cution et de compilation correspondent. */
if (metadata->vers != FANOTIFY_METADATA_VERSION) {
fprintf(stderr,
"Mauvaise correspondance des versions de métadonnées de fanotify.\en");
exit(EXIT_FAILURE);
}
/* metadata->fd contient soit FAN_NOFD, indiquant un
débordement de file ou un descripteur de fichier (un entier
non négatif). Ici, le débordement est simplement ignoré. */
if (metadata->fd >= 0) {
/* Gestion de la permission d’ouvrir. */
if (metadata->mask & FAN_OPEN_PERM) {
printf("FAN_OPEN_PERM: ");
/* Autorisation d’ouvrir le fichier. */
response.fd = metadata->fd;
response.response = FAN_ALLOW;
write(fd, &response, sizeof(response));
}
/* Gestion de la fermeture d’évĂšnement de fichier Ă©ditable. */
if (metadata->mask & FAN_CLOSE_WRITE)
printf("FAN_CLOSE_WRITE: ");
/* Récupération et affichage du chemin du fichier accédé. */
snprintf(procfd_path, sizeof(procfd_path),
"/proc/self/fd/%d", metadata->fd);
path_len = readlink(procfd_path, path,
sizeof(path) - 1);
if (path_len == -1) {
perror("readlink");
exit(EXIT_FAILURE);
}
path[path_len] = '\0';
printf("File %s\n", path);
/* Fermeture du descripteur de fichier de l’évĂšnement. */
close(metadata->fd);
}
/* Avance jusqu’au prochain Ă©vĂšnement. */
metadata = FAN_EVENT_NEXT(metadata, len);
}
}
}
int
main(int argc, char *argv[])
{
char buf;
int fd, poll_num;
nfds_t nfds;
struct pollfd fds[2];
/* Vérification que le point de montage soit fourni. */
if (argc != 2) {
fprintf(stderr, "Utilisation : %s MOUNT\n", argv[0]);
exit(EXIT_FAILURE);
}
printf("Presser la touche Entrée pour terminer.\n");
/* CrĂ©ation d’un descripteur de fichier pour accĂ©der Ă  l’API de fanotify. */
fd = fanotify_init(FAN_CLOEXEC | FAN_CLASS_CONTENT | FAN_NONBLOCK,
O_RDONLY | O_LARGEFILE);
if (fd == -1) {
perror("fanotify_init");
exit(EXIT_FAILURE);
}
/* Marque du montage pour :
– Ă©vĂšnements de permission avant ouvertures de fichier
– Ă©vĂšnements de notification aprĂšs la fermeture
d’un descripteur de fichier Ă©ditable. */
if (fanotify_mark(fd, FAN_MARK_ADD | FAN_MARK_MOUNT,
FAN_OPEN_PERM | FAN_CLOSE_WRITE, AT_FDCWD,
argv[1]) == -1) {
perror("fanotify_mark");
exit(EXIT_FAILURE);
}
/* Préparation pour sondage. */
nfds = 2;
fds[0].fd = STDIN_FILENO; /* Entrée de console */
fds[0].events = POLLIN;
fds[1].fd = fd; /* Entrée de fanotify */
fds[1].events = POLLIN;
/* Ceci est une boucle pour attendre de futurs évÚnements. */
printf("Écoute d’évĂšnements.\n");
while (1) {
poll_num = poll(fds, nfds, -1);
if (poll_num == -1) {
if (errno == EINTR) /* Interruption par un signal */
continue; /* Redémarrage de poll() */
perror("poll"); /* Erreur inattendue */
exit(EXIT_FAILURE);
}
if (poll_num > 0) {
if (fds[0].revents & POLLIN) {
/* Entrée de console disponible : stdin vide et quitter. */
while (read(STDIN_FILENO, &buf, 1) > 0 && buf != '\n')
continue;
break;
}
if (fds[1].revents & POLLIN) {
/* Évùnements de fanotify disponibles. */
handle_events(fd);
}
}
}
printf("Écoute d’évĂšnements arrĂȘtĂ©e.\n");
exit(EXIT_SUCCESS);
}

Exemple de programme : fanotify_fid.c

Le second programme est un exemple d’utilisation de fanotify avec un groupe qui identifie des objets avec des gestionnaires de fichier. Le programme marque l’objet de systĂšme de fichiers qui est passĂ© comme argument de ligne de commande et attend jusqu’à ce qu’un Ă©vĂšnement de type FAN_CREATE se produise. Le masque d’évĂšnement indique quel type d’objet de systĂšme de fichiers, soit un fichier ou un rĂ©pertoire, est créé. Une fois que tous les Ă©vĂšnements du tampon ont Ă©tĂ© lus et traitĂ©s de la maniĂšre appropriĂ©e, le programme se termine.

Les sessions d’interprĂ©teur de commande suivantes montrent deux invocations diffĂ©rentes avec des actions diffĂ©rentes rĂ©alisĂ©es sur l’objet dĂ©sirĂ©.

La premiĂšre session montre une marque placĂ©e sur /home/utilisateur . Cela est suivi par la crĂ©ation d’un fichier normal, /home/utilisateur/fichiertest.txt . Cela aboutit Ă  un Ă©vĂšnement FAN_CREATE gĂ©nĂ©rĂ© et rapportĂ© Ă  l’objet de rĂ©pertoire surveillĂ© parent du fichier et Ă  la crĂ©ation du nom de fichier. L’exĂ©cution du programme se termine une fois que tous les Ă©vĂšnements capturĂ©s du tampon ont Ă©tĂ© traitĂ©s.

# ./fanotify_fid /home/user
Écoute de tous les Ă©vĂšnements.
FAN_CREATE (fichier créé) :
Répertoire /home/utilisateur a été modifié.
EntrĂ©e « fichiertest.txt » n’est pas un sous-rĂ©pertoire.
Tous les évÚnements ont été traités avec succÚs. Fin du programme.
$ touch /home/user/fichiertest.txt # Dans un autre terminal

La premiĂšre session montre une marque placĂ©e sur /home/utilisateur . C’est suivi par la crĂ©ation d’un rĂ©pertoire, /home/utilisateur/rĂ©ptest . Cette action spĂ©cifique aboutit Ă  la gĂ©nĂ©ration d’un Ă©vĂšnement FAN_CREATE et est rapportĂ© avec l’attribut FAN_ONDIR dĂ©fini et avec la crĂ©ation du nom de rĂ©pertoire.

# ./fanotify_fid /home/user
Écoute de tous les Ă©vĂšnements.
FAN_CREATE | FAN_ONDIR (sous_répertoire créé) :
Répertoire /home/utilisateur a été modifié.
Entrée « réptest » est un sous-répertoire.
Tous les évÚnements ont été traités avec succÚs. Fin du programme.
$ mkdir -p /home/user/réptest # Dans un autre terminal

Source du programme : fanotify_fid.c

#define _GNU_SOURCE
#include <errno.h>
#include <fcntl.h>
#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/fanotify.h>
#include <unistd.h>
#define BUF_SIZE 256
int
main(int argc, char *argv[])
{
int fd, ret, event_fd, mount_fd;
ssize_t len, path_len;
char path[PATH_MAX];
char procfd_path[PATH_MAX];
char events_buf[BUF_SIZE];
struct file_handle *file_handle;
struct fanotify_event_metadata *metadata;
struct fanotify_event_info_fid *fid;
const char *file_name;
struct stat sb;
if (argc != 2) {
fprintf(stderr, "nombre d’arguments de ligne de commande non valable.\n");
exit(EXIT_FAILURE);
}
mount_fd = open(argv[1], O_DIRECTORY | O_RDONLY);
if (mount_fd == -1) {
perror(argv[1]);
exit(EXIT_FAILURE);
}
/* CrĂ©ation d’un descripteur de fichier avec FAN_REPORT_DFID_NAME
comme drapeau pour que le programme puisse recevoir des évÚnements
fid avec un nom d’entrĂ©e de rĂ©pertoire. */
fd = fanotify_init(FAN_CLASS_NOTIF | FAN_REPORT_DFID_NAME, 0);
if (fd == -1) {
perror("fanotify_init");
exit(EXIT_FAILURE);
}
/* Placement d’une marque sur l’objet de systùme de fichiers fourni dans argv[1]. */
ret = fanotify_mark(fd, FAN_MARK_ADD | FAN_MARK_ONLYDIR,
FAN_CREATE | FAN_ONDIR,
AT_FDCWD, argv[1]);
if (ret == -1) {
perror("fanotify_mark");
exit(EXIT_FAILURE);
}
printf("Écoute d’évĂšnements.\n");
/* Lecture d’évĂšnements de la file d’évĂšnements d’un tampon. */
len = read(fd, events_buf, sizeof(events_buf));
if (len == -1 && errno != EAGAIN) {
perror("read");
exit(EXIT_FAILURE);
}
/* Traitement de tous les évÚnements du tampon. */
for (metadata = (struct fanotify_event_metadata *) events_buf;
FAN_EVENT_OK(metadata, len);
metadata = FAN_EVENT_NEXT(metadata, len)) {
fid = (struct fanotify_event_info_fid *) (metadata + 1);
file_handle = (struct file_handle *) fid->handle;
/* VĂ©rification que l’information d’évĂšnement soit du bon type. */
if (fid->hdr.info_type == FAN_EVENT_INFO_TYPE_FID ||
fid->hdr.info_type == FAN_EVENT_INFO_TYPE_DFID) {
file_name = NULL;
} else if (fid->hdr.info_type == FAN_EVENT_INFO_TYPE_DFID_NAME) {
file_name = file_handle->f_handle +
file_handle->handle_bytes;
} else {
fprintf(stderr, "Type inattendu d’information d’évĂšnement.\n");
exit(EXIT_FAILURE);
}
if (metadata->mask == FAN_CREATE)
printf("FAN_CREATE (fichier créé :\n");
if (metadata->mask == (FAN_CREATE | FAN_ONDIR))
printf("FAN_CREATE | FAN_ONDIR (sous-répertoire créé) :\n");

/* metadata->fd est défini à FAN_NOFD quand le groupe identifie

des objets par des gestionnaires de fichier. Pour obtenir un descripteur

de fichier pour l’objet de fichier correspondant Ă  un Ă©vĂšnement, la structure

file_handle qui est fournie dans fanotify_event_info_fid peut ĂȘtre utilisĂ©e

en conjonction avec l’appel systĂšme open_by_handle_at(2). Une vĂ©rification

pour ESTALE est faite pour rĂ©pondre Ă  la situation oĂč le gestionnaire de

l’objet a Ă©tĂ© supprimĂ© avant cet appel systĂšme. */

event_fd = open_by_handle_at(mount_fd, file_handle, O_RDONLY);
if (event_fd == -1) {
if (errno == ESTALE) {
printf("Gestionnaire de fichier plus valable. "
"Le fichier a été supprimé\n");
continuation;
} else {
perror("open_by_handle_at");
exit(EXIT_FAILURE);
}
}
snprintf(procfd_path, sizeof(procfd_path), "/proc/self/fd/%d",
event_fd);
/* RĂ©cupĂ©ration et affichage du chemin d’entrĂ©e de rĂ©pertoire modifiĂ©e. */
path_len = readlink(procfd_path, path, sizeof(path) - 1);
if (path_len == -1) {
perror("readlink");
exit(EXIT_FAILURE);
}
path[path_len] = '\0';
printf("\tRépertoire « %s » a été modifié.\n", chemin);
if (file_name) {
ret = fstatat(event_fd, file_name, &sb, 0);
if (ret == -1) {
if (errno != ENOENT) {
perror("fstatat");
exit(EXIT_FAILURE);
}
printf("\tEntĂ©e « %s » n’existe pas.\n", fichier);
} else if ((sb.st_mode & S_IFMT) == S_IFDIR) {
printf("\tEntrée « %s » est un sous-répertoire.\n", fichier);
} else {
printf("\tEntrĂ©e « %s » n’est pas un rĂ©pertoire.\n",
fichier);
}
}
/* Fermeture du descripteur de fichier associé à cet évÚnement. */
close(event_fd);
}
printf("Tous les évÚnements ont été traités avec succÚs. Fin du programme.\n");
exit(EXIT_SUCCESS);
}

VOIR AUSSI

fanotify_init (2), fanotify_mark (2), inotify (7)

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> et Jean-Paul Guillonneau <guillonneau.jeanpaul@free.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 .