Abrufen Dateiname von Datei-Deskriptor in C
Ist es möglich, den Dateinamen einer Datei-Deskriptor (Linux) in C?
Ich denke, die gewählte Antwort gegeben werden soll zneak als seine Lösung hat eine bessere Portabilität und hat nicht bemerkt Probleme mit dem Zugriff.
Es unterstützt nicht auf Ubuntu 14.04 (kernel 3.16.0-76-generic). Ich vermute, es ist unter Linux nicht unterstützt bei allen.
Es unterstützt nicht auf Ubuntu 14.04 (kernel 3.16.0-76-generic). Ich vermute, es ist unter Linux nicht unterstützt bei allen.
InformationsquelleAutor adk | 2009-07-27
Du musst angemeldet sein, um einen Kommentar abzugeben.
Können Sie
readlink
auf/proc/self/fd/NNN
NNN wird der file-Deskriptor. Diesem geben Sie den Namen der Datei, wie es war, wenn es geöffnet wurde — allerdings, wenn die Datei verschoben oder gelöscht wurde, da dann möglicherweise nicht mehr korrekt (obwohl Linux verfolgen können, benennt in einigen Fällen). Um zu überprüfen,stat
die mit dem Namen gegeben undfstat
die fd, die Sie haben, und stellen Sie sicher, dassst_dev
undst_ino
sind die gleichen.Natürlich nicht alle Datei-Deskriptoren verweisen auf Dateien, und für diejenigen, die Sie sehen einige seltsame text-strings, wie
pipe:[1538488]
. Da alle realen Dateinamen werden die absoluten Pfade, können Sie bestimmen, welche diese sind leicht genug. Des weiteren, wie andere haben darauf hingewiesen, Dateien können mehrere hardlinks zeigen auf Sie - dies wird nur berichten, das es geöffnet wurde. Wenn Sie möchten, zu finden, alle Namen für eine bestimmte Datei, Sie müssen nur zum Durchlaufen des gesamten Dateisystems.fd
würde solch eine Referenz), der inode-Nummer nicht wiederverwendet werden. Jede software, die Verwendung einer inode-Nummer nach es ist die Datei geschlossen, oder bevor Sie es öffnen, ist von Natur aus unterliegt, um race-Bedingungen.Gefahr, Will Robinson! Dies gilt nicht immer Arbeit --- wenn Sie
setuid()
tricks ist es möglich, für/proc/self/fd
nicht zugänglich sein, indem Sie Ihren Prozess. Siehe: permalink.gmane.org/gmane.linux.kernel/1302546und in dem Fall ist /proc nicht gemountet?
diese Antwort ist Linux-spezifisch. Ich weiß nicht, ob NetBSD unterstützt procfs an alle - wenn Ihr shared host nicht bieten, ist es wahrscheinlich, weil NetBSD nicht unterstützt wird, und nutzt einen anderen Mechanismus statt. Sie wollen vielleicht nach einer anderen Frage mit einem NetBSD-Fokus, um zu sehen, ob jemand weiß, wie NetBSD stellt diese Informationen (Sie möchten vielleicht auch versuchen, zneak Antwort unter OS X ist ähnlich wie BSD als Linux)
NetBSD Unterstützung des /proc-aber es ist nicht obligatorisch, es zu montieren. Jedes mal, wenn ich erwähnt habe, wurde die Antwort "Schalter Weg zu einem höheren cost-Anbieter, und Sie erhalten /proc". Also ich bin auf der Suche nach einem procless Lösung.
InformationsquelleAutor bdonlan
Ich hatte dieses problem auf Mac OS X. Wir haben keine
/proc
virtuelles Datei-system, so akzeptiert die Lösung nicht.Wir tun, stattdessen haben
F_GETPATH
Befehl fürfcntl
:So, um die Datei, die zu einem Datei-Deskriptor, können Sie dieses snippet:
Da ich mich nie daran erinnern, wo
MAXPATHLEN
definiert ist, dachte ichPATH_MAX
aus syslimits wäre in Ordnung.wahrscheinlich nicht. Verwenden
getsockname
.Was erwarten Sie? Es sei denn, es ist ein UNIX-socket, hat es keine Datei zugeordnet ist.
Ja, alles ist eine Datei, aber nicht alles ist ein Verzeichnis-Eintrag durch einen Namen und eine Position im Dateisystem-Baum. Eine Datei ist gekennzeichnet durch ein inode, es besteht ohne Eintrag in ein Verzeichnis bezieht.
In <sys/param.h>: #define MAXPATHLEN PATH_MAX
InformationsquelleAutor zneak
In Windows, mit GetFileInformationByHandleEx, vorbei FileNameInfo, können Sie rufen Sie die Datei name.
InformationsquelleAutor Martin v. Löwis
Als Tyler Punkte aus, gibt es keine Möglichkeit, das zu tun, was Sie verlangen "direkt und sicher", da ein FD entspricht 0 Dateinamen (in verschiedenen Fällen) oder > 1 (mehrere "harte links" ist, wie die letztere situation ist in der Regel beschrieben). Wenn Sie noch brauchen, die Funktionalität mit, die Einschränkungen (auf die Geschwindigkeit UND auf die Möglichkeit des Erhaltens von 0, 2, ... Ergebnisse eher als 1 ist), hier ist, wie Sie es tun können: Erstens, fstat die FD -- das sagt Sie, in der resultierenden
struct stat
, welches Gerät die Datei lebt, wie viele harte links, die es hat, ob es eine spezielle Datei, etc. Diese könnte bereits die Antwort auf Ihre Frage-z.B. wenn der Wert 0 ist hart links, die Sie WISSEN, gibt es in der Tat keine entsprechenden Dateinamen auf der Festplatte.Wenn die Statistiken geben Ihnen Hoffnung, dann haben Sie an "walk the tree" von Verzeichnissen, die auf das entsprechende Gerät, bis Sie alle hart links (oder nur die erste, wenn Sie nicht brauchen mehr als einen, und einer tun wird). Zu diesem Zweck, verwenden Sie readdir (und opendir &c natürlich) rekursiv Unterverzeichnisse öffnen, bis Sie in einem
struct dirent
so erhielten die gleiche inode-Nummer, die Sie hatten in der ursprünglichenstruct stat
(zu dem Zeitpunkt, wenn Sie möchten, den kompletten Pfad anstatt nur den Namen, Sie müssen zu Fuß die Kette der Verzeichnisse rückwärts zu rekonstruieren).Wenn dieser Allgemeine Ansatz ist akzeptabel, aber Sie brauchen mehr detaillierte C-code, lassen Sie es uns wissen, es wird nicht schwer sein zu schreiben (obwohl ich lieber nicht schreiben, wenn es ist nutzlos, D. H. Sie kann nicht widerstehen, das zwangsläufig langsame Leistung oder die Möglichkeit, erste != 1 Ergebnis für die Zwecke der Anwendung;-).
InformationsquelleAutor Alex Martelli
Vor dem schreiben dieser Weg als unmöglich, ich schlage vor, Sie Blick auf den Quellcode der lsof Befehl.
Möglicherweise gibt es Einschränkungen, aber lsof scheint fähig zu bestimmen, die den Datei-descriptor-und Datei-Namen. Diese information existiert in der /proc-Dateisystem es sollte also möglich sein, aus Ihrem Programm.
InformationsquelleAutor Duck
Können Sie verwenden, fstat (), um die Datei-inode von struct stat. Dann, mit readdir() können Sie vergleichen Sie die inode-Sie finden mit denen, die existieren (struct dirent) in ein Verzeichnis (unter der Annahme, dass Sie wissen, das Verzeichnis, ansonsten wirst du suchen müssen, der das ganze Dateisystem) und finden die entsprechenden Datei-Namen.
Böse?
InformationsquelleAutor PetrosB
Unmöglich. Ein Datei-Deskriptor können mehrere Namen im Dateisystem, oder es kann gar kein name.
Edit: Vorausgesetzt, Sie sprechen über eine einfache alte POSIX-system, ohne OS-spezifische APIs, da Sie nicht angegeben haben, ein OS.
Versuchen Sie, einen Blick auf die lsof-source-code. 🙂 Das ist, was ich Tat, als ich hatte die gleiche Frage, mich eine Weile zurück. lsof funktioniert, die schwarze Magie und Opfergaben Ziegen - Sie können nicht hoffen, zu duplizieren sein Verhalten. Um genauer zu sein, lsof ist eng gekoppelt mit dem linux-kernel, und nicht tut, was es tut, durch eine API, die verfügbar ist, um Benutzer-code land.
Linux ist eine nicht-portable proc-API für das. Es gibt zwar Einschränkungen, aber zu sagen, dass es unmöglich ist schlichtweg falsch.
lsof läuft im userspace. Daher gibt es eine API für das, was er zur Verfügung userland-code 🙂
die übertragbarkeit es ist wahrscheinlich der Grund, warum lsof Quelle hat so viel schwarze Magie; jede UNIX-Variante macht es anders. Das linux-proc-Schnittstellen sind auch nicht schlecht, wirklich, alebit eher spärlich dokumentiert.
InformationsquelleAutor Tyler McHenry