Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

inotify sur un repertoire: le champs inotify_event.len semble rester=0 pour un repertoire

82 réponses
Avatar
Zeyes
J'ai poste ca aussi sur fr.comp.os.linux.debats parceque ca bouge pas
mal la-bas..
;-)

Bonour,
j"ai regarde
http://www.linuxjournal.com/node/8478/print
Extrait:
"
The name field contains the name of the object to which the event
occurred, relative to wd, if applicable. For example, if a watch for
writes in /etc triggers an event on the writing to /etc/vimrc, the name
field will contain vimrc, and the wd field will link back to the /etc watch
"
Mais ca marche pas chez moi: le champs inotify_event.len reste a 0,
alors qu'il semble rester des octets a lire...
quelqu'un a une idee?
Est-ce normal? Pas encore implemente?
Merci

10 réponses

1 2 3 4 5
Avatar
Luc.Habert.00__arjf
Zeyes :

Mais ca marche pas chez moi: le champs inotify_event.len reste a 0,
alors qu'il semble rester des octets a lire...


On peut voir ton code?

Avatar
Zeyes
Zeyes :

Mais ca marche pas chez moi: le champs inotify_event.len reste a 0,
alors qu'il semble rester des octets a lire...


On peut voir ton code?
Heu.. ben... si t'y tiens vraiment.... c'est possible....

Mais les critiques devraient etre constructives...
J'ai pas encore envie de me faire traiter d'incompetent ou de tordu....
T'es sur?


Avatar
Luc.Habert.00__arjf
Zeyes :

T'es sur?


Bein c'est toi qui vois, mais pour ma part, je ne saurai pas te donner de
réponse sans voir le code.

Avatar
Zeyes
Zeyes :

T'es sur?


Bein c'est toi qui vois, mais pour ma part, je ne saurai pas te donner de
réponse sans voir le code.
Ok c parti........... (j'ai pas "coller" tout court, alors c'est comme

une "citation")


#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>

#include <unistd.h>
#include <linux/inotify.h>
#include <sys/poll.h>

// Gestion des erreurs
#include <errno.h>
#include <string.h>

// pour exit()
#include <stdlib.h>

int main(int argc, char* argv[])
{
int code_de_retour=0;
const char *nom_de_fichier_a_surveiller = argv[1];
char* commande_en_cas_de_modif = argv[2];
int fichier_a_ete_modifie;

int notificateur = 0;
int observation = 0;
struct pollfd descripteur_poll;
size_t longueur_lue_du_notificateur;
struct inotify_event notification;
char nom[1000];
__int32_t longueur_nom;

char* message_erreur=NULL;

printf ("surveille %sn",nom_de_fichier_a_surveiller);

notificateur = inotify_init ();
if (notificateur < 0)
{
code_de_retour=errno;
}

if (code_de_retour==0)
{
observation = inotify_add_watch (notificateur , nom_de_fichier_a_surveiller, IN_MODIFY);

descripteur_poll.fd = notificateur;
descripteur_poll.events=POLLIN;

fichier_a_ete_modifie = 1;
while ( (fichier_a_ete_modifie==1) && (code_de_retour==0) )
{
code_de_retour = poll(&descripteur_poll, 1, -1);
if (code_de_retour==-1)
{
code_de_retour=errno;
fichier_a_ete_modifie = 0;
}
else
{
code_de_retour=0;
fichier_a_ete_modifie = 1;
}

if (code_de_retour==0)
{
longueur_lue_du_notificateur =
read (
notificateur,
&notification,
sizeof(notification)
);
if(longueur_lue_du_notificateur==-1)
{
code_de_retour=errno;
}
else
{
code_de_retour=0;
}
}

if (code_de_retour==0)
{
nom[0]=notification.name[0];
longueur_nom=notification.len;
printf("lg nom: %dn", longueur_nom);
if (longueur_nom>0)
{
nom[0]=notification.name[0];
longueur_lue_du_notificateur > read (
notificateur,
&nom[1],
longueur_nom-1
);
code_de_retour=errno;
printf("vu: %sn", nom);
}
system(commande_en_cas_de_modif);
}
}
}

if (code_de_retour!=0)
{
message_erreur=strerror (code_de_retour);
printf ("Erreur %d:%sn",code_de_retour, message_erreur);
}
exit (code_de_retour);
}




Avatar
Zeyes
Zeyes :

T'es sur?


Bein c'est toi qui vois, mais pour ma part, je ne saurai pas te donner de
réponse sans voir le code.
Ah pis je compile avec:


gcc -D_GNU_SOURCE -Wall inot.c
inot.c est le nom du fichier.... voila, je suis tout nu!


Avatar
Zeyes
Zeyes :

Mais ca marche pas chez moi: le champs inotify_event.len reste a 0,
alors qu'il semble rester des octets a lire...


On peut voir ton code?
C qd meme un code pondu en regardant la tv, un dimanche am.......

Sois indulgent, stp!
:-(


Avatar
Zeyes
Zeyes :

Mais ca marche pas chez moi: le champs inotify_event.len reste a 0,
alors qu'il semble rester des octets a lire...


On peut voir ton code?
Il est gnu!!!!!

Si ca peut servir (apres tes commentaires) a qq'un: pas de pbs!
Ohlala j'angoisse: tu reponds quand?


Avatar
Luc.Habert.00__arjf
Zeyes :


Quelques remarques sur ton code :

nom[0]=notification.name[0];
longueur_lue_du_notificateur >> read (
notificateur,
&nom[1],
longueur_nom-1
);



La struct inotify_event est définie ainsi (je prend la définition du .h
plutôt que celle de la page de man, car elle n'est pas syntaxiquement
correcte) :

struct inotify_event {
__s32 wd; /* watch descriptor */
__u32 mask; /* watch mask */
__u32 cookie; /* cookie to synchronize two events*/
__u32 len; /* length (including nulls) of name*/
char name[0]; /* stub for possible name */
};

son sizeof vaut la distance entre son début et le début du champ name. Donc
il ne faut pas faire le « nom[0]=notification.name[0] », et faire un read de
tout le nom dans nom.

__int32_t longueur_nom;



Pourquoi pas int? Si tu veux pinailler, c'est « size_t », le bon type.


observation = inotify_add_watch (notificateur , nom_de_fichier_a_surveiller, IN_MODIFY);



Il conviendrait de tester si ça a réussi.

code_de_retour = poll(&descripteur_poll, 1, -1);



Il est inutile de poller, tu pourrais faire un read directement, et laisser
le noyau te bloquer tant qu'il n'y a rien à lire.


longueur_lue_du_notificateur =
read (
notificateur,
&notification,
sizeof(notification)
);
if(longueur_lue_du_notificateur==-1)
{
code_de_retour=errno;
}
else
{
code_de_retour=0;
}



Quand tu fais un read, rien ne te garantie que le noyau va vraiment te lire
autant d'octets d'un coup que tu lui en demande. Il faut faire une boucle
qui compare la valeur de retour à la taille demandée. Sans compter qu'en cas
de réception d'un signal au mauvais moment, ça peut renvoyer -1, avec errno
valant EINTR, auquel cas, il faut juste relancer le read tel quel (ça, c'est
valable avec tous les appels systèmes qui peuvent bloquer). Ça devient vite
très lourd, tu peux vouloir utilise fdopen pour obtenir un FILE * basé sur
le fd, et ensuite lire avec fread qui fait le boulot chiant pour toi.




Bon, maintenant je ne pense pas que tout ça ait quoi que ce soit à voir avec
ton problème. Si j'en crois la doc, le fait d'avoir un évènement avec nom
vide sur un répertoire veut dire que c'est le répertoire lui-même qui a été
modifié (un fichier créé ou supprimé). Tu appelles ce programme avec quels
arguments? Comment le fichier est-il modifié?


Avatar
Zeyes
Zeyes :


Quelques remarques sur ton code :

nom[0]=notification.name[0];
longueur_lue_du_notificateur >>> read (
notificateur,
&nom[1],
longueur_nom-1
);



La struct inotify_event est définie ainsi (je prend la définition du .h
plutôt que celle de la page de man, car elle n'est pas syntaxiquement
correcte) :

struct inotify_event {
__s32 wd; /* watch descriptor */
__u32 mask; /* watch mask */
__u32 cookie; /* cookie to synchronize two events*/
__u32 len; /* length (including nulls) of name*/
char name[0]; /* stub for possible name */
};

son sizeof vaut la distance entre son début et le début du champ name. Donc
il ne faut pas faire le « nom[0]=notification.name[0] », et faire un read de
tout le nom dans nom.

__int32_t longueur_nom;



Pourquoi pas int? Si tu veux pinailler, c'est « size_t », le bon type.


observation = inotify_add_watch (notificateur , nom_de_fichier_a_surveiller, IN_MODIFY);



Il conviendrait de tester si ça a réussi.

code_de_retour = poll(&descripteur_poll, 1, -1);



Il est inutile de poller, tu pourrais faire un read directement, et laisser
le noyau te bloquer tant qu'il n'y a rien à lire.


longueur_lue_du_notificateur =
read (
notificateur,
&notification,
sizeof(notification)
);
if(longueur_lue_du_notificateur==-1)
{
code_de_retour=errno;
}
else
{
code_de_retour=0;
}



Quand tu fais un read, rien ne te garantie que le noyau va vraiment te lire
autant d'octets d'un coup que tu lui en demande. Il faut faire une boucle
qui compare la valeur de retour à la taille demandée. Sans compter qu'en cas
de réception d'un signal au mauvais moment, ça peut renvoyer -1, avec errno
valant EINTR, auquel cas, il faut juste relancer le read tel quel (ça, c'est
valable avec tous les appels systèmes qui peuvent bloquer). Ça devient vite
très lourd, tu peux vouloir utilise fdopen pour obtenir un FILE * basé sur
le fd, et ensuite lire avec fread qui fait le boulot chiant pour toi.




Bon, maintenant je ne pense pas que tout ça ait quoi que ce soit à voir avec
ton problème. Si j'en crois la doc, le fait d'avoir un évènement avec nom
vide sur un répertoire veut dire que c'est le répertoire lui-même qui a été
modifié (un fichier créé ou supprimé). Tu appelles ce programme avec quels
arguments? Comment le fichier est-il modifié?
Merci pour tes remarques.... je reflechis encore!

Pour l'appel:
J'ai cree le dir tata qui contient le fichier cont
Je lance
./a.out tata "echo coucou"
et a cote, je fait
echo hello >> tata/cont
J'ai bien les evenemnts, mais ma trace
printf("lg nom: %dn", longueur_nom);
renvoie 0 !!
Et ca n'arrete plus de boucler (comme s'il y a vait encore des octetes)
plein de

coucou
lg nom: 0

Strange, non?



Avatar
Zeyes
Zeyes :


Quelques remarques sur ton code :

nom[0]=notification.name[0];
longueur_lue_du_notificateur >>> read (
notificateur,
&nom[1],
longueur_nom-1
);



La struct inotify_event est définie ainsi (je prend la définition du .h
plutôt que celle de la page de man, car elle n'est pas syntaxiquement
correcte) :

struct inotify_event {
__s32 wd; /* watch descriptor */
__u32 mask; /* watch mask */
__u32 cookie; /* cookie to synchronize two events*/
__u32 len; /* length (including nulls) of name*/
char name[0]; /* stub for possible name */
};

son sizeof vaut la distance entre son début et le début du champ name. Donc
il ne faut pas faire le « nom[0]=notification.name[0] », et faire un read de
tout le nom dans nom.

__int32_t longueur_nom;




D'ou le -1... il me semble avoir deja lu le 1 char


Pourquoi pas int? Si tu veux pinailler, c'est « size_t », le bon type.
Voui mais c'est pas celui de inotify_event.. je me suis pite trompe!



observation = inotify_add_watch (notificateur , nom_de_fichier_a_surveiller, IN_MODIFY);



Il conviendrait de tester si ça a réussi.
J'ai pas trouver la bonne doc.....


code_de_retour = poll(&descripteur_poll, 1, -1);



Il est inutile de poller, tu pourrais faire un read directement, et laisser
le noyau te bloquer tant qu'il n'y a rien à lire.
Ah, le noyau peut bloquer un read? Je savais pas... je decouvre!



longueur_lue_du_notificateur =
read (
notificateur,
&notification,
sizeof(notification)
);
if(longueur_lue_du_notificateur==-1)
{
code_de_retour=errno;
}
else
{
code_de_retour=0;
}



Quand tu fais un read, rien ne te garantie que le noyau va vraiment te lire
autant d'octets d'un coup que tu lui en demande. Il faut faire une boucle
qui compare la valeur de retour à la taille demandée. Sans compter qu'en cas
de réception d'un signal au mauvais moment, ça peut renvoyer -1, avec errno
valant EINTR, auquel cas, il faut juste relancer le read tel quel (ça, c'est
valable avec tous les appels systèmes qui peuvent bloquer). Ça devient vite
très lourd, tu peux vouloir utilise fdopen pour obtenir un FILE * basé sur
le fd, et ensuite lire avec fread qui fait le boulot chiant pour toi.
Ah je savais pas... en gros fdopen te transforme un fd en FILE* ?

J'ai pas encore regarde.. il est tard....




Bon, maintenant je ne pense pas que tout ça ait quoi que ce soit à voir avec
ton problème. Si j'en crois la doc, le fait d'avoir un évènement avec nom
vide sur un répertoire veut dire que c'est le répertoire lui-même qui a été
modifié (un fichier créé ou supprimé). Tu appelles ce programme avec quels
arguments? Comment le fichier est-il modifié?
Ben c'est la que ca coince..... c'est bien un fichier du repertoire qui

est modifie....



1 2 3 4 5