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

[ à cheval sur fclc et fcou ] fopen w+ et flock

6 réponses
Avatar
cedric
Bonjour à tous.

J'ai un soucis amusant : je veux ouvrir un fichier avec fopen en mode
"w+' mais je ne veut pas toucher le fichier si je n'arrive pas à obtenir
un lock dessus.

Or pour obtenir un lock dessus il faut déjà que je l'ai ouvert
(flock(fileno(file))). Et si je l'ouvre avec "w+" avant d'avoir le lock,
je vide le fichier ce que je n'ai pas le droit de faire.

Si j'ouvre d'abord par exemple en "r+" et si je fait un freopen une fois
le lock acquit, j'ai l'impression que le freopen va me lâcher le lock
(équivalent à un fclose + fopen ?).

Pile tu gagnes, face je perd...

Y a t-il un truc ?

Amicalement,

6 réponses

Avatar
Charlie Gordon
"cedric" wrote in message
news:419931db$0$30303$
Bonjour à tous.

J'ai un soucis amusant : je veux ouvrir un fichier avec fopen en mode
"w+' mais je ne veut pas toucher le fichier si je n'arrive pas à obtenir
un lock dessus.

Or pour obtenir un lock dessus il faut déjà que je l'ai ouvert
(flock(fileno(file))). Et si je l'ouvre avec "w+" avant d'avoir le lock,
je vide le fichier ce que je n'ai pas le droit de faire.

Si j'ouvre d'abord par exemple en "r+" et si je fait un freopen une fois
le lock acquit, j'ai l'impression que le freopen va me lâcher le lock
(équivalent à un fclose + fopen ?).

Pile tu gagnes, face je perd...

Y a t-il un truc ?


Utilise un autre fichier pour le locking, sans necessairement utiliser flock()
d'ailleurs, qui pose probleme sous NFS.
Une fois que tu t'es assuré le controle, utilise fopen() pour faire ce que tu
veux sur ton fichier de données.
Ceci suppose que tous les process concernés coopèrent et utilisent la même
méthode de synchronisation, mais tu fais presque la même supposition avec ton
approche à base de flock() sur le même fichier.

Par exemple, CVS protège les accès concurrents sur les fichiers RCS du reposoir
en créant des fichiers temporaires dans le même répertoire, ce qui nécessite que
le process cvs ait le droit d'y écrire même pour ne faire que des lectures.

Il me semble que l'on peut utiliser open() avec O_CREAT et O_EXCL pour créer ces
fichiers de synchronisation sans autre appel spécifique de locking : si on
arrive a créer le fichier, on est le seul à avoir pu le faire et aucun autre
process ne peut y parvenir tant que le fichier existe. Un process pourrait
éventuellement supprimer le fichier explicitement, mais ce serait un manque
flagrant de coopérativité (ou un besoin de déblocage manuel de deadlock en cas
de plantage ;-)

Chqrlie.

Avatar
Fabien
Il me semble que l'on peut utiliser open() avec O_CREAT et O_EXCL pour créer ces
fichiers de synchronisation sans autre appel spécifique de locking


Tout à fait mais open() est POSIX.1 mais pas ANSI...

Avatar
cedric
Charlie Gordon wrote:
Utilise un autre fichier pour le locking, sans necessairement utiliser flock()
d'ailleurs, qui pose probleme sous NFS.


Moui. J'y avait pensé mais je n'aime pas beaucoup les fichier
temporaires... Bon, ca ferait au moins un endroit pour écrire le pid du
process (rend détectable les locks restés en l'air).

Ceci suppose que tous les process concernés coopèrent et utilisent la même
méthode de synchronisation, mais tu fais presque la même supposition avec ton
approche à base de flock() sur le même fichier.


Oui, c'est le cas de toute facon.


Il me semble que l'on peut utiliser open() avec O_CREAT et O_EXCL pour créer ces
fichiers de synchronisation sans autre appel spécifique de locking : si on
arrive a créer le fichier, on est le seul à avoir pu le faire et aucun autre
process ne peut y parvenir tant que le fichier existe.


Vendu !

Merci bien.

Avatar
cedric
Fabien wrote:
Tout à fait mais open() est POSIX.1 mais pas ANSI...


De toute facon flock n'était pas très ANSI non plus... :)

Avatar
Nicolas George
cedric wrote in message <419931db$0$30303$:
Si j'ouvre d'abord par exemple en "r+" et si je fait un freopen une fois
le lock acquit, j'ai l'impression que le freopen va me lâcher le lock
(équivalent à un fclose + fopen ?).


Effectivement.

Y a t-il un truc ?


Hum, le passage de r+ à w+, il me semble, ce n'est qu'une troncature du
fichier. Unix propose la fonction ftruncate qui permet de faire ça.

Une autre possibilité, préférable à mon avis, est de faire toute la phase de
verrouillage avec les fonctions Unix (open, flock, ftruncate), et ensuite
utiliser fdopen pour confier le reste à stdio.

Avatar
cedric
Nicolas George wrote:

Une autre possibilité, préférable à mon avis, est de faire toute la phase de
verrouillage avec les fonctions Unix (open, flock, ftruncate), et ensuite
utiliser fdopen pour confier le reste à stdio.


Je préférerai minimiser la partie non-standard et conserver mon fopen
dans la partie "standard" (c'est l'aspect "fclc" du problème :p)