Est-il possible d’obtenir le nom de fichier d’un descripteur de fichier en C?
Réponses
Trop de publicités?Vous pouvez utiliser readlink
sur /proc/self/fd/NNN
où NNN est le descripteur de fichier. Cela vous donnera le nom du fichier tel qu'il était lorsqu'il a été ouvert - toutefois, si le fichier a été déplacé ou supprimé depuis lors, il peut ne plus être à jour (bien que Linux peut suivre renomme dans certains cas). Pour vérifier, stat
le nom de fichier donné et fstat
la fd vous avez, et assurez - st_dev
et st_ino
sont les mêmes.
Bien sûr, pas tous les descripteurs de fichier se référer à des fichiers, et pour ceux que vous allez voir de drôles de chaînes de texte, telles que l' pipe:[1538488]
. Depuis tous les vrais noms de fichiers seront des chemins absolus, vous pouvez déterminer à qui elles sont assez facilement. En outre, comme d'autres l'ont noté, les fichiers peuvent avoir plusieurs liens pointant vers - ce qui ne rapporte que celui qu'il a été ouvert avec. Si vous voulez trouver tous les noms pour un fichier donné, vous aurez juste à traverser la totalité du système de fichiers.
J'ai eu ce problème sous Mac OS X. Nous n'avons pas de système de fichiers virtuel /proc
, la solution acceptée ne peut donc pas fonctionner.
Nous avons plutôt une commande F_GETPATH
pour fcntl
:
F_GETPATH Get the path of the file descriptor Fildes. The argu-
ment must be a buffer of size MAXPATHLEN or greater.
Donc, pour obtenir le fichier associé à un descripteur de fichier, vous pouvez utiliser cet extrait:
#include <sys/syslimits.h>
#include <fcntl.h>
char filePath[PATH_MAX];
if (fcntl(fd, F_GETPATH, filePath) != -1)
{
// do something with the file path
}
Puisque je ne me souviens jamais où MAXPATHLEN
est défini, je pensais que PATH_MAX
de syslimits irait bien.
Dans Windows, avec GetFileInformationByHandleEx , en passant FileNameInfo , vous pouvez récupérer le nom du fichier.
Tyler points, il n'y a aucun moyen de faire ce que vous avez besoin d' "directement et de manière fiable", depuis un FD peut correspondre à 0 noms de fichiers (dans certains cas) ou > 1 (plusieurs "liens en dur" est de savoir comment cette dernière situation est décrite de façon générale). Si vous n'avez encore besoin de la fonctionnalité, avec toutes les limites (sur la vitesse ET sur la possibilité d'obtenir 0, 2, ... les résultats plutôt que 1), voici comment faire: tout d'abord, fstat la FD -- ce que vous avez dit, dans le résultat de l' struct stat
, ce dispositif le fichier sur la vie, combien de liens en dur elle a, si c'est un fichier spécial, etc. Cela peut déjà répondre à votre question -- par exemple, si 0 liens en dur, vous SAVEZ qu'il ya en fait pas de nom de fichier sur le disque.
Si les stats de vous donner de l'espoir, alors vous avez à marcher "l'arbre" de répertoires sur l'appareil jusqu'à ce que vous trouvez tous les liens en dur (ou tout simplement la première, si vous n'avez pas besoin de plus d'un et n'importe lequel). Pour cela, vous utilisez readdir (et les fonctions opendir &c, bien sûr) de manière récursive d'ouverture de la sous-répertoires jusqu'à ce que vous trouver dans un struct dirent
a donc reçu le même numéro d'inœud vous aviez à l'origine, struct stat
(à ce moment, si vous voulez tout le chemin, plutôt que juste le nom, vous aurez besoin de marcher sur la chaîne de répertoires vers l'arrière afin de le reconstruire).
Si cette approche générale est acceptable, mais vous avez besoin de plus de détails le code en C, laissez-nous savoir, il ne sera pas difficile à écrire (même si je préfère ne pas écrire, si c'est inutile, c'est à dire vous ne pouvez pas résister à l'inévitable ralentissement des performances ou de la possibilité de se != 1 résultat pour les fins de votre demande;-).
Avant d'écrire ceci comme impossible, je vous suggère de regarder le code source de la commande lsof .
Il peut y avoir des restrictions mais lsof semble capable de déterminer le descripteur de fichier et le nom du fichier. Ces informations existent dans le système de fichiers / proc, il devrait donc être possible de les obtenir à partir de votre programme.