GNU/Linux >> Tutoriels Linux >  >> Linux

Récupérer le nom du fichier à partir du descripteur de fichier en C

J'ai eu ce problème sur Mac OS X. Nous n'avons pas de /proc système de fichiers virtuel, la solution acceptée ne peut donc pas fonctionner.

Nous avons, à la place, un F_GETPATH commande 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
}

Comme je ne me souviens jamais où MAXPATHLEN est défini, je pensais PATH_MAX de syslimits serait bien.


Vous pouvez utiliser readlink le /proc/self/fd/NNN où NNN est le descripteur de fichier. Cela vous donnera le nom du fichier tel qu'il était lors de son ouverture - cependant, si le fichier a été déplacé ou supprimé depuis lors, il peut ne plus être exact (bien que Linux puisse suivre les changements de nom dans certains cas). Pour vérifier, stat le nom de fichier donné et fstat le fd que vous avez, et assurez-vous que st_dev et st_ino sont les mêmes.

Bien sûr, tous les descripteurs de fichiers ne font pas référence à des fichiers, et pour ceux-ci, vous verrez des chaînes de texte étranges, telles que pipe:[1538488] . Étant donné que tous les vrais noms de fichiers seront des chemins absolus, vous pouvez déterminer lesquels sont assez facilement. De plus, comme d'autres l'ont noté, les fichiers peuvent avoir plusieurs liens physiques pointant vers eux - cela ne signalera que celui avec lequel il a été ouvert. Si vous souhaitez trouver tous les noms d'un fichier donné, vous n'aurez qu'à parcourir tout le système de fichiers.


Comme le souligne Tyler, il n'y a aucun moyen de faire ce dont vous avez besoin "directement et de manière fiable", car un FD donné peut correspondre à 0 noms de fichiers (dans divers cas) ou> 1 (plusieurs "liens durs" sont la façon dont cette dernière situation est généralement décrite ). Si vous avez toujours besoin de la fonctionnalité avec toutes les limitations (sur la vitesse ET sur la possibilité d'obtenir des résultats 0, 2, ... plutôt que 1), voici comment vous pouvez le faire :d'abord, fstat le FD - cela vous indique , dans le résultat struct stat , sur quel appareil se trouve le fichier, combien de liens physiques il a, s'il s'agit d'un fichier spécial, etc. Cela peut déjà répondre à votre question - par exemple. si 0 liens durs, vous saurez qu'il n'y a en fait aucun nom de fichier correspondant sur le disque.

Si les statistiques vous donnent de l'espoir, alors vous devez "parcourir l'arborescence" des répertoires sur l'appareil concerné jusqu'à ce que vous trouviez tous les liens physiques (ou juste le premier, si vous n'en avez pas besoin de plus d'un et que n'importe lequel fera l'affaire ). Pour cela, vous utilisez readdir (et opendir &c bien sûr) en ouvrant récursivement des sous-répertoires jusqu'à ce que vous trouviez dans un struct dirent ainsi reçu le même numéro d'inode que vous aviez dans le struct stat d'origine (à ce moment-là, si vous voulez le chemin complet, plutôt que juste le nom, vous devrez parcourir la chaîne de répertoires en arrière pour le reconstruire).

Si cette approche générale est acceptable, mais que vous avez besoin de code C plus détaillé, faites-le nous savoir, ce ne sera pas difficile à écrire (bien que je préfère ne pas l'écrire si c'est inutile, c'est-à-dire que vous ne pouvez pas supporter les performances inévitablement lentes ou le possibilité d'obtenir !=1 résultat pour les besoins de votre candidature;-).


Sous Windows, avec GetFileInformationByHandleEx, en passant FileNameInfo, vous pouvez récupérer le nom du fichier.


Linux
  1. Comment Cater un fichier depuis Awk ?

  2. Awk de différentes lignes ?

  3. Lire des modèles Grep à partir d'un fichier ?

  4. Lecture d'un fichier en assembleur

  5. Comment extraire le fichier filename.tar.gz

Comment obtenir le nom de fichier à partir du chemin complet sous Linux

Comment supprimer les caractères (^M) d'un fichier sous Linux

Créer un PEM à partir d'un fichier PPK

En quoi install -c est différent de cp

Pourquoi est-il si difficile de trouver un fichier dans Ubuntu ?

Comment récupérer les informations d'un fichier vidéo à partir de la ligne de commande sous Linux ?