Oui! L'astuce consiste à accéder au fichier supprimé via /proc/self/fd/n
. C'est une astuce Linux uniquement, pour autant que je sache.
Exécutez ce programme :
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int main() {
FILE* out_file;
FILE* in_file;
char* dev_fd_path;
char buffer[128];
/* Write “hi!” to test.txt */
out_file = fopen("test.txt", "w");
fputs("hi!\n", out_file);
fflush(out_file);
/* Delete the file */
unlink("test.txt");
/* Verify that the file is gone */
system("ls test.txt");
/* Reopen the filehandle in read-mode from /proc */
asprintf(&dev_fd_path, "/proc/self/fd/%d", fileno(out_file));
in_file = fopen(dev_fd_path, "r");
if (!in_file) {
perror("in_file is NULL");
exit(1);
}
printf("%s", fgets(buffer, sizeof(buffer), in_file));
return 0;
}
Il écrit du texte dans un fichier, le supprime, mais garde le descripteur de fichier ouvert, puis le rouvre via une route différente. Les fichiers ne sont pas réellement supprimés jusqu'à ce que le dernier processus contenant le dernier descripteur de fichier le ferme, et jusque-là, vous pouvez accéder au contenu du fichier via /proc
.
Merci à mon ancien patron Anatoly de m'avoir appris cette astuce lorsque j'ai supprimé des fichiers importants qui, heureusement, étaient encore ajoutés par un autre processus !
Non, l'appel fcntl ne vous permettra pas de définir les bits de lecture/écriture sur un descripteur de fichier ouvert et la seule façon d'obtenir un nouveau descripteur de fichier à partir d'un existant est d'utiliser la fonctionnalité de duplication. Les appels à dup/dup2/dup3 (et fcntl
) ne vous permettent pas de changer le mode d'accès aux fichiers.
REMARQUE :ceci est vrai pour Linux, mais pas vrai pour les autres Unix en général. Dans HP-UX, par exemple, [voir (1) et (2)] vous pouvez modifier les bits de lecture/écriture avec fcntl
en utilisant F_SETFL sur un descripteur de fichier ouvert. Depuis les descripteurs de fichiers créés par dup
partagent les mêmes drapeaux de statut, cependant, changer le mode d'accès pour l'un le changera nécessairement pour l'autre.