Re: Fichier immortel

Top Page

Reply to this message
Author: Edgar Bonet
Date:  
To: Liste Guilde
Subject: Re: Fichier immortel
Le mercredi 22 septembre, Jean-Marc Coursimault a écrit :
> Je suppose donc que le fichier initial est conservé par un processus qui
> tourne : si j'ai bien compris, si un process Unix a ouvert un fichier, et
> que qqn le modifie, le pgm continue de voir l'ancienne version. Ou qqchose
> comme ça.


Ce à qui j'ai répondu :
> Non, dans ce cas il voit les modifications. En revanche, si quelqu'un
> efface (unlink()e en fait) le fichier et recrée un autre de même nom,
> alors le programme qui a ouvert l'ancien continue à voir l'ancien.


Jean-Marc :
> Comment voir quel +@$*^ù de process a ouvert mon fichier ?


Edgar :
> Dans /proc/*/fd ?


Voici le résultat d'un essai. Le programme ci-dessous crée un fichier,
l'efface, en crée un deuxième de même nom et fait un « ls -l » de
/proc/<pid>/fd. Le résultat :

$ ./testfd 
total 0
lrwx------    1 edgar    edgar          64 Sep 23 16:22 0 -> /dev/pts/1
lrwx------    1 edgar    edgar          64 Sep 23 16:22 1 -> /dev/pts/1
lrwx------    1 edgar    edgar          64 Sep 23 16:22 2 -> /dev/pts/1
lrwx------    1 edgar    edgar          64 Sep 23 16:22 3 -> /tmp/testfd-ANdyNF (deleted)
lrwx------    1 edgar    edgar          64 Sep 23 16:22 4 -> /tmp/testfd-ANdyNF


Comme tu vois, les descripteurs 3 et 4 pointent vers des fichiers
différents (« /tmp/testfd-ANdyNF (deleted) » et « /tmp/testfd-ANdyNF »).

Le programme :

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>

char filename[] = "/tmp/testfd-XXXXXX";

int main(void)
{
    char command[64];
    int fd1, fd2, ret;


    /* Open a file for writing and delete it. */
    fd1 = mkstemp(filename);
    if (fd1 == -1) { perror(filename); return EXIT_FAILURE; }
    ret = unlink(filename);
    if (ret == -1) { perror(filename); return EXIT_FAILURE; }


    /* Open another one with the same name. */
    fd2 = open(filename, O_RDWR | O_CREAT | O_EXCL, 0600);
    if (fd2 == -1) { perror(filename); return EXIT_FAILURE; }


    /* List open files via /proc. */
    snprintf(command, sizeof command, "ls -l /proc/%d/fd", getpid());
    system(command);


    if (close(fd1) == -1) { perror(filename); return EXIT_FAILURE; }
    if (close(fd2) == -1) { perror(filename); return EXIT_FAILURE; }
    return EXIT_SUCCESS;
}


-- 
Edgar Bonet           Maison : 04 76 21 29 16    Bureau : 04 76 88 10 96
3 rue Jean Prévost    Mobile : 06 77 19 79 39    Fax    : 04 76 88 11 91
38000 Grenoble        guilde@???     www.edgar-bonet.org