GNU/Linux >> LINUX-Kenntnisse >  >> Linux

Rufen Sie den Dateinamen aus dem Dateideskriptor in C ab

Ich hatte dieses Problem unter Mac OS X. Wir haben keinen /proc virtuelles Dateisystem, sodass die akzeptierte Lösung nicht funktionieren kann.

Wir haben stattdessen eine F_GETPATH Befehl für fcntl :

 F_GETPATH          Get the path of the file descriptor Fildes.  The argu-
                    ment must be a buffer of size MAXPATHLEN or greater.

Um also die einem Dateideskriptor zugeordnete Datei zu erhalten, können Sie dieses Snippet verwenden:

#include <sys/syslimits.h>
#include <fcntl.h>

char filePath[PATH_MAX];
if (fcntl(fd, F_GETPATH, filePath) != -1)
{
    // do something with the file path
}

Da ich mich nie erinnere wo MAXPATHLEN definiert ist, dachte ich PATH_MAX von syslimits wäre in Ordnung.


Sie können readlink verwenden auf /proc/self/fd/NNN wobei NNN der Dateideskriptor ist. Dadurch erhalten Sie den Namen der Datei, wie er beim Öffnen war. Wenn die Datei jedoch seitdem verschoben oder gelöscht wurde, ist sie möglicherweise nicht mehr korrekt (obwohl Linux in einigen Fällen Umbenennungen nachverfolgen kann). Zur Bestätigung stat der angegebene Dateiname und fstat die fd, die Sie haben, und stellen Sie sicher, dass st_dev und st_ino sind gleich.

Natürlich beziehen sich nicht alle Dateideskriptoren auf Dateien, und für diese werden Sie einige seltsame Textzeichenfolgen sehen, wie z. B. pipe:[1538488] . Da alle echten Dateinamen absolute Pfade sind, können Sie leicht feststellen, welche das sind. Außerdem können Dateien, wie andere angemerkt haben, mehrere Hardlinks haben, die auf sie verweisen - dies wird nur denjenigen melden, mit dem sie geöffnet wurde. Wenn Sie alle Namen für eine bestimmte Datei finden möchten, müssen Sie nur das gesamte Dateisystem durchlaufen.


Wie Tyler betont, gibt es keine Möglichkeit, das zu tun, was Sie "direkt und zuverlässig" benötigen, da ein bestimmter FD 0 Dateinamen (in verschiedenen Fällen) oder> 1 entsprechen kann (mehrere "harte Links", wie die letztere Situation allgemein beschrieben wird ). Wenn Sie dennoch die Funktionalität mit allen Einschränkungen benötigen (in Bezug auf die Geschwindigkeit UND auf die Möglichkeit, 0, 2, ... Ergebnisse anstelle von 1 zu erhalten), können Sie dies wie folgt tun:Zuerst fstat das FD – das sagt es Ihnen , im resultierenden struct stat , auf welchem ​​Gerät die Datei lebt, wie viele feste Links sie hat, ob es sich um eine spezielle Datei handelt usw. Dies beantwortet möglicherweise bereits Ihre Frage - z. Wenn 0 feste Links vorhanden sind, WISSEN Sie, dass es tatsächlich keinen entsprechenden Dateinamen auf der Festplatte gibt.

Wenn die Statistiken Ihnen Hoffnung geben, müssen Sie den Verzeichnisbaum auf dem entsprechenden Gerät "durchgehen", bis Sie alle festen Links gefunden haben (oder nur den ersten, wenn Sie nicht mehr als einen benötigen und jeder ausreicht). ). Zu diesem Zweck verwenden Sie readdir (und natürlich opendir &c) und öffnen rekursiv Unterverzeichnisse, bis Sie in einem struct dirent finden erhielt also dieselbe Inode-Nummer wie im Original struct stat (Zu diesem Zeitpunkt müssen Sie, wenn Sie den gesamten Pfad und nicht nur den Namen wollen, die Verzeichniskette rückwärts durchlaufen, um sie zu rekonstruieren).

Wenn dieser allgemeine Ansatz akzeptabel ist, Sie aber detaillierteren C-Code benötigen, lassen Sie es uns wissen, es wird nicht schwer zu schreiben sein (obwohl ich es lieber nicht schreiben würde, wenn es nutzlos ist, d Möglichkeit !=1 Ergebnis für Ihre Bewerbung zu erhalten;-).


Unter Windows können Sie mit GetFileInformationByHandleEx, indem Sie FileNameInfo übergeben, den Dateinamen abrufen.


Linux
  1. Portabilität von Dateideskriptor-Links?

  2. Lesen von Grep-Mustern aus einer Datei?

  3. So extrahieren Sie die Datei filename.tar.gz

  4. Erstellen Sie eine PEM aus einer PPK-Datei

  5. Datei von windows nach linux kopieren

So erhalten Sie den Dateinamen aus dem vollständigen Pfad in Linux

So entfernen Sie (^M) Zeichen aus einer Datei in Linux

Ist es möglich, / in einem Dateinamen zu verwenden?

Wie unterscheidet sich install -c von cp

Warum ist es so schwer, eine Datei in Ubuntu zu finden?

Wie rufe ich Videodateiinformationen von der Befehlszeile unter Linux ab?