2011-08-23 3 views
2

Supposons que je souhaite invoquer une commande sur tous les fichiers d'un répertoire et que vous définissiez une surveillance pour invoquer cette commande sur tous les fichiers créés dans ce répertoire. Si je le fais:Comment éviter cette condition de concurrence avec readdir/inotify?

alors certains fichiers seront potentiellement manqués. Si j'appelle inotify_add_watch() avant le readdir(), les fichiers peuvent être traités deux fois (il faudrait un peu d'infrastructure pour éviter d'agir deux fois, et il semble que les cas de bord seraient difficiles à gérer). Y at-il un moyen simple d'éviter avoir à enregistrer les noms de tous les fichiers travaillés sur la boucle readdir et en les comparant aux noms retournés dans la structure inotify_event? Je peux minimiser la quantité de comparaisons nécessaires avec:

 
while((sdi = readdir(d)) != NULL) { ... } 
inotify_add_watch(...); 
while((sdi = readdir(d)) != NULL) { /* record name */ ... } 
closedir(d); 

Et généralement, la deuxième boucle readdir() ne fera rien, mais cela se sent comme un mauvais hack.

Répondre

1

Vous ne pouvez tout simplement pas. Plus vous bidouillez, plus vous aurez de conditions de course.

La plus simple solution travail fait est de mettre la montre avant d'utiliser opendir() et garder une liste (ensemble) des noms déjà utilisés (ou leurs) hash.

Mais ce n'est pas parfait non plus. L'utilisateur peut ouvrir le fichier dans un éditeur de texte. vous le corrigez, l'utilisateur l'enregistre et le répertoire contient de toute façon un fichier non fixé, bien qu'il soit dans votre liste.

La meilleure méthode serait de permettre au programme de distinguer réellement les fichiers utilisés par leur contenu. En d'autres termes, vous définissez watch, appelez la commande sur les résultats readdir(), puis appelez-le sur les résultats inotify et laissez la commande elle-même savoir si le fichier est déjà bien ou non.

Questions connexes