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

Avatar
Zeyes
Zeyes :

Tu penses que je peux utiliser realloc() pour gagner du temps?
C'est politiquement correct?


Bah oui...

Autre solution : utiliser un tableau dynamique. Attention à ne pas le
définir comme un tableau de char, car il ne sera pas forcément bien aligné
pour contenir un struct inotify_event à sa première case. Je ne vois pas
comment faire autrement qu'un tableau de struct inotify_event, de taille
« ln/sizeof(struct inotify_event)+1 ».


Mais la place pour les noms?
Et si j'utilise un pointeur mobile qui avance dans mon buffer?
en iterant:

ptr+=sizeof(struct inotify_event);
ptr_nom= ptr;
ptr+=( (struct inotify_event*) ptr)->len;
et ptr est sur la struct suivante
Non?

Parceque si je comprends, dans le "flux" y'a une structure, un nom, une
structure, un nom, etc.....


Avatar
Luc.Habert.00__arjf
Nicolas George :

union {
struct inotify_event;
char dummy[ln];
}


Ah oui, bien sur!

Avatar
Luc.Habert.00__arjf
Zeyes :

Et si j'utilise un pointeur mobile qui avance dans mon buffer?


Je disais ça juste pour l'allocation. Ensuite, il faut caster vers char *,
faire des décalages, et recaser vers struct inotify_event. Mais la solution
de Nicolas est bien meilleure (enfin, ça n'épargne que le premier cast).

Avatar
Michel Tatoute
Zeyes wrote:

Zeyes wrote in message <4622b877$0$27414$:
J'ai cru comprendre que poll() ne polait pas, mais restait en attente
sur un evenemnet, d'apres le man... ca me semblait bien.


Il reste en attente sur plusieurs événements avec une limite de temps. Si
tu n'as qu'un seul événement et pas de limite de temps, ça ne sert à
rien.
Ben si: a attendre le seul evenement qui m'interesse!

Developpe!


Il veux dire par là que faire un poll pour un seul evenement sans timeout
est fait optimalement par un read (ou un autre appel system de la famille)
bloquant. Comme tu as de toute façon le read, le poll est inutile.

Aussi d'un point de vue portabilité , utiliser le caractere bloquant du read
te permet d'être compatible avec une plus large famille d'architecture
cible (POSIX ?), tant dis qu'utiliser poll (ou select, c'est pareil), te
restreint et ajoute des possibilités d'erreurs inutiles.

Michel.



Avatar
Luc.Habert.00__arjf
Michel Tatoute :

Aussi d'un point de vue portabilité


Oui, enfin bon, là il était question d'utiliser un truc qui n'existe que
sous linux...

Avatar
Zeyes
Zeyes :

Et si j'utilise un pointeur mobile qui avance dans mon buffer?


Je disais ça juste pour l'allocation. Ensuite, il faut caster vers char *,
faire des décalages, et recaser vers struct inotify_event. Mais la solution
de Nicolas est bien meilleure (enfin, ça n'épargne que le premier cast).
Mais la longueur totale n'est pas fixe.

L'allocation doit etre refaite a chaque fois (m'enfin presque)
Alors je peux pas utiliser un type defini statique
Bon ok, les casts, c'est pas beau
Mais pour me promener, je vois ne vois pas bien ce qu'apporte l'union....


Avatar
Zeyes
Zeyes wrote:

Zeyes wrote in message <4622b877$0$27414$:
J'ai cru comprendre que poll() ne polait pas, mais restait en attente
sur un evenemnet, d'apres le man... ca me semblait bien.
Il reste en attente sur plusieurs événements avec une limite de temps. Si

tu n'as qu'un seul événement et pas de limite de temps, ça ne sert à
rien.
Ben si: a attendre le seul evenement qui m'interesse!

Developpe!


Il veux dire par là que faire un poll pour un seul evenement sans timeout
est fait optimalement par un read (ou un autre appel system de la famille)
bloquant. Comme tu as de toute façon le read, le poll est inutile.

Aussi d'un point de vue portabilité , utiliser le caractere bloquant du read
te permet d'être compatible avec une plus large famille d'architecture
cible (POSIX ?), tant dis qu'utiliser poll (ou select, c'est pareil), te
restreint et ajoute des possibilités d'erreurs inutiles.

Michel.
Merci!

J"avais pris ca parce que c'etait dans la doc de inotify: ca avait l'air
important que ce soit "pollable"... et comme je connaisais pas.
D'ailleurs, je ne sais pas non plus faire de read bloquant!




Avatar
Zeyes
Zeyes :

Et si j'utilise un pointeur mobile qui avance dans mon buffer?


Je disais ça juste pour l'allocation. Ensuite, il faut caster vers char *,
faire des décalages, et recaser vers struct inotify_event. Mais la solution
de Nicolas est bien meilleure (enfin, ça n'épargne que le premier cast).


Ou alors

inotify_event * ptr;

realloc(ptr,ln)

et j'itere avec

ptr_nom=ptr->name;
(char*)ptr += ptr->len;
ptr++;


Ca marche?


Avatar
Luc.Habert.00__arjf
Zeyes :

Mais la longueur totale n'est pas fixe.
L'allocation doit etre refaite a chaque fois (m'enfin presque)
Alors je peux pas utiliser un type defini statique


C'est pour ça que je parlais de tableaux dynamiques. Si je ne me plante pas,
ça donne quelque chose comme :


while (...) {
poll(...);
ioctl(...);
union {char buf[ln]; struct inotify_event blah;} x;
read(jesaispluscommentsappelletonfd,x.buf,ln);
void * i; struct inotify_event * j;
for (i=x.buf,j=&x.blah;x!=(void *)x.buf+ln;
i+=sizeof(struct inotify_event)+j->len,j=i) {
// traiter l'évènement pointé par j
}
}

.

Avatar
Zeyes
Zeyes :

Mais la longueur totale n'est pas fixe.
L'allocation doit etre refaite a chaque fois (m'enfin presque)
Alors je peux pas utiliser un type defini statique


C'est pour ça que je parlais de tableaux dynamiques. Si je ne me plante pas,
ça donne quelque chose comme :


while (...) {
poll(...);
ioctl(...);
union {char buf[ln]; struct inotify_event blah;} x;
read(jesaispluscommentsappelletonfd,x.buf,ln);
void * i; struct inotify_event * j;
for (i=x.buf,j=&x.blah;x!=(void *)x.buf+ln;
i+=sizeof(struct inotify_event)+j->len,j=i) {
// traiter l'évènement pointé par j
}
}

.
Ben tu realloue x a chaque read ?

C'est pas plus lent qu'un realloc? (qui, si je me rappelle, ne change de
bloc que s'il est trop petit) D'un autre cote, tu me diras que ce ne
sont qus des mouvement de pointeur de pile peut-etre?
Oh je dois m'absenter qq heures....
Merci en tout cas de ton aide et de tes suggestions.