Ist es möglich, den Dateinamen eines Dateideskriptors (Linux) in C abzurufen?
c
linux
file
file-descriptor
adk
quelle
quelle
Antworten:
Sie können mit
readlink
auf/proc/self/fd/NNN
dem NNN ist der Dateideskriptor. Dadurch erhalten Sie den Namen der Datei wie beim Öffnen. Wenn die Datei jedoch seitdem verschoben oder gelöscht wurde, ist sie möglicherweise nicht mehr korrekt (obwohl Linux in einigen Fällen Umbenennungen verfolgen kann). Um zu überprüfen,stat
der Dateiname angegeben undfstat
die fd Sie haben, und stellen Sie sicher ,st_dev
undst_ino
sind gleich.Natürlich beziehen sich nicht alle Dateideskriptoren auf Dateien, und für diese werden einige seltsame Textzeichenfolgen angezeigt, z
pipe:[1538488]
. Da alle realen Dateinamen absolute Pfade sind, können Sie leicht bestimmen, welche diese Pfade sind. Wie andere angemerkt haben, können Dateien mehrere Hardlinks haben, die auf sie verweisen - dies meldet nur den, mit dem sie geöffnet wurden. Wenn Sie alle Namen für eine bestimmte Datei finden möchten, müssen Sie nur das gesamte Dateisystem durchlaufen.quelle
fd
wäre ein solcher Verweis), kann die Inode-Nummer nicht wiederverwendet werden. Jede Software, die nach dem Schließen der Datei oder vor dem Öffnen eine Inode-Nummer verwendet, unterliegt von Natur aus den Rennbedingungen.setuid()
Tricks ausführen, kann es sein/proc/self/fd
, dass Ihr Prozess nicht auf Sie zugreift. Siehe: permalink.gmane.org/gmane.linux.kernel/1302546Ich hatte dieses Problem unter Mac OS X. Wir haben kein
/proc
virtuelles Dateisystem, daher kann die akzeptierte Lösung nicht funktionieren.Wir haben stattdessen einen
F_GETPATH
Befehl fürfcntl
:Um die einem Dateideskriptor zugeordnete Datei abzurufen, können Sie dieses Snippet verwenden:
Da ich mich nie daran erinnere, wo
MAXPATHLEN
definiert ist, dachte ich, dassPATH_MAX
Syslimits in Ordnung wären.quelle
getsockname
.In Windows können Sie mit GetFileInformationByHandleEx , indem Sie FileNameInfo übergeben , den Dateinamen abrufen.
quelle
Wie Tyler betont, gibt es keine Möglichkeit, "direkt und zuverlässig" das zu tun, was Sie benötigen, da eine bestimmte FD 0 Dateinamen (in verschiedenen Fällen) oder> 1 (mehrere "harte Links") entsprechen kann, wie die letztere Situation allgemein beschrieben wird ). Wenn Sie die Funktionalität mit allen Einschränkungen (Geschwindigkeit UND Möglichkeit, 0, 2, ... Ergebnisse anstelle von 1 zu erhalten) weiterhin benötigen, können Sie dies folgendermaßen tun: Zuerst fstat the FD - dies sagt Ihnen In der Folge
struct stat
, auf welchem Gerät die Datei lebt, wie viele Hardlinks sie hat, ob es sich um eine spezielle Datei handelt usw. Dies kann Ihre Frage bereits beantworten - z. B. wenn Sie 0 Hardlinks kennen, wissen Sie, dass es tatsächlich keinen entsprechenden Dateinamen gibt auf der Festplatte.Wenn die Statistiken Ihnen Hoffnung geben, müssen Sie den Baum der Verzeichnisse 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 dies tun wird ). Zu diesem Zweck verwenden Sie readdir (und natürlich opendir & c), um Unterverzeichnisse rekursiv zu öffnen, bis Sie in einem
struct dirent
so empfangenen die gleiche Inode-Nummer finden, die Sie im Original hattenstruct stat
(zu diesem Zeitpunkt, wenn Sie den gesamten Pfad und nicht nur den Namen möchten). Sie müssen die Verzeichniskette rückwärts durchlaufen, um sie zu rekonstruieren.Wenn dieser allgemeine Ansatz akzeptabel ist, Sie jedoch detaillierteren C-Code benötigen, lassen Sie es uns wissen, es wird nicht schwer zu schreiben sein (obwohl ich ihn lieber nicht schreiben würde, wenn er nutzlos ist, dh Sie können der unvermeidlich langsamen Leistung oder der Leistung nicht standhalten Möglichkeit zu bekommen! = 1 Ergebnis für die Zwecke Ihrer Bewerbung ;-).
quelle
Bevor Sie dies als unmöglich abschreiben, sollten Sie sich den Quellcode des Befehls lsof ansehen .
Es kann Einschränkungen geben, aber lsof scheint in der Lage zu sein, den Dateideskriptor und den Dateinamen zu bestimmen. Diese Informationen sind im Dateisystem / proc vorhanden, sodass es möglich sein sollte, von Ihrem Programm aus darauf zuzugreifen.
quelle
Sie können fstat () verwenden, um den Inode der Datei nach struct stat abzurufen. Mit readdir () können Sie dann den gefundenen Inode mit dem in einem Verzeichnis vorhandenen (struct dirent) vergleichen (vorausgesetzt, Sie kennen das Verzeichnis, andernfalls müssen Sie das gesamte Dateisystem durchsuchen) und den entsprechenden Dateinamen finden. Böse?
quelle
Unmöglich. Ein Dateideskriptor kann mehrere Namen im Dateisystem haben oder überhaupt keinen Namen.
Bearbeiten: Angenommen, Sie sprechen von einem einfachen alten POSIX-System ohne betriebssystemspezifische APIs, da Sie kein Betriebssystem angegeben haben.
quelle