Domanda

E 'possibile ottenere il nome di un file descrittore (Linux) in C?

È stato utile?

Soluzione

È possibile utilizzare readlink su /proc/self/fd/NNN dove NNN è il descrittore di file. Questo vi darà il nome del file come lo era quando è stato aperto - tuttavia, se il file è stato spostato o cancellato da allora, si potrebbe non essere più accurata (anche se Linux in grado di monitorare rinomina in alcuni casi). Per verificare, stat il nome del file dato e fstat il fd che hai, e assicurarsi che st_dev e st_ino sono gli stessi.

Naturalmente, non tutti i descrittori di file fanno riferimento a file, e per quelli vedrete alcune stringhe di testo dispari, come ad esempio pipe:[1538488]. Dal momento che tutti i veri nomi saranno percorsi assoluti, è possibile determinare quale questi sono abbastanza facilmente. Inoltre, come altri hanno notato, i file possono avere più collegamenti fisici che puntano ad esse - questo riporterà solo quella è stato aperto con. Se si desidera trovare tutti i nomi per un dato file, dovrete semplicemente attraversare l'intero filesystem.

Altri suggerimenti

Ho avuto questo problema su Mac OS X. Non abbiamo un file system virtuale /proc, per cui la soluzione accettata non posso lavorare.

fare, invece, hanno un comando F_GETPATH per fcntl:

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

Quindi, per ottenere il file associato ad un descrittore di file, è possibile utilizzare questo frammento:

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

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

Dato che non mi ricordo mai dove si definisce MAXPATHLEN, ho pensato PATH_MAX da syslimits andrebbe bene.

In Windows, con GetFileInformationByHandleEx , passando FileNameInfo , è possibile recuperare il nome del file.

Come Tyler fa notare, non c'è modo di fare ciò che si richiede "direttamente e in modo affidabile", dal momento che un dato FD può corrispondere a 0 i nomi dei file (in diversi casi) o> 1 (di più "hard link" è il modo in quest'ultima situazione è generalmente descritto). Se ancora bisogno della funzionalità con tutti i limiti (sulla velocità e sulla possibilità di ottenere 0, 2, ... i risultati piuttosto che 1), ecco come si può fare: in primo luogo, fstat FD - questo ti dice, nel struct stat risultante, quale dispositivo il file vive, quanti link difficile ha , che si tratti di un file speciale, ecc Questo potrebbe già rispondere alla tua domanda - ad esempio, se 0 hard link potrete sapere che c'è in realtà non corrisponde il nome del file sul disco.

Se le statistiche danno la speranza, poi si deve "camminare l'albero" della directory del dispositivo in questione fino a trovare tutti gli hard link (o solo il primo, se non avete bisogno di più di uno e qualsiasi si farà). A tal fine, si utilizza readdir (e opendir & C ovviamente) sottodirectory di apertura in modo ricorsivo fino a quando non trovare in un struct dirent in tal modo ha ricevuto lo stesso numero di inode si aveva in struct stat originale (e in quel momento, se si desidera che l'intero percorso, non solo il nome, è necessario percorrere la catena di directory all'indietro per ricostruirla).

Se questo approccio generale è accettabile, ma è necessario il codice più dettagliato C, fateci sapere, non sarà difficile da scrivere (anche se preferirei non scrivere se è inutile, cioè non si può sopportare il inevitabilmente lenta le prestazioni o la possibilità di ottenere = 1 risultato ai fini dell'applicazione; -!).

Prima di scrivere questo come impossibile, vi consiglio di guardare il codice sorgente del lsof comando.

Potrebbero esserci delle limitazioni ma lsof sembra in grado di determinare il descrittore di file e il nome del file. esiste Queste informazioni nel filesystem / proc quindi dovrebbe essere possibile ottenere in dal programma.

È possibile utilizzare fstat () per ottenere inode del file da struct stat. Quindi, utilizzando readdir () è possibile confrontare l'inode che avete trovato con quelle che esistono (struct dirent) in una directory (supponendo che si conosce la directory, altrimenti dovrete cercare l'intero file system) e trovare il nome del file corrispondente. Nasty?

Impossibile. Un descrittore di file può avere più nomi nel filesystem, o può avere alcun nome a tutti.

Modifica: Supponendo che si sta parlando di un sistema di pianura POSIX vecchio, senza alcuna API specifiche del sistema operativo, dal momento che non è stato specificato un OS

.
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top