Ho avuto questo problema su Mac OS X. Non abbiamo un /proc
file system virtuale, quindi la soluzione accettata non può funzionare.
Abbiamo, invece, un F_GETPATH
comando 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 associare il file a un descrittore di file, puoi utilizzare questo snippet:
#include <sys/syslimits.h>
#include <fcntl.h>
char filePath[PATH_MAX];
if (fcntl(fd, F_GETPATH, filePath) != -1)
{
// do something with the file path
}
Dal momento che non ricordo mai dove MAXPATHLEN
è definito, ho pensato PATH_MAX
da syslimits andrebbe bene.
Puoi usare readlink
su /proc/self/fd/NNN
dove NNN è il descrittore di file. Questo ti darà il nome del file com'era quando è stato aperto, tuttavia, se il file è stato spostato o eliminato da allora, potrebbe non essere più accurato (sebbene Linux possa tenere traccia delle rinominazioni in alcuni casi). Per verificare, stat
il nome del file dato e fstat
il fd che hai e assicurati che st_dev
e st_ino
sono uguali.
Naturalmente, non tutti i descrittori di file si riferiscono a file, e per quelli vedrai alcune strane stringhe di testo, come pipe:[1538488]
. Poiché tutti i nomi di file reali saranno percorsi assoluti, è possibile determinare quali sono abbastanza facilmente. Inoltre, come altri hanno notato, i file possono avere più collegamenti fisici che puntano a loro:questo riporterà solo quello con cui è stato aperto. Se vuoi trovare tutti i nomi per un determinato file, dovrai solo attraversare l'intero filesystem.
Come sottolinea Tyler, non c'è modo di fare ciò di cui hai bisogno "direttamente e in modo affidabile", poiché un dato FD può corrispondere a 0 nomi di file (in vari casi) o> 1 (più "hard link" è come viene generalmente descritta quest'ultima situazione ). Se hai ancora bisogno della funzionalità con tutte le limitazioni (sulla velocità E sulla possibilità di ottenere 0, 2, ... risultati anziché 1), ecco come puoi farlo:in primo luogo, fstat l'FD - questo ti dice , nel risultante struct stat
, su quale dispositivo risiede il file, quanti hard link ha, se si tratta di un file speciale, ecc. Questo potrebbe già rispondere alla tua domanda, ad es. se 0 hard link saprai che in realtà non esiste alcun nome di file corrispondente sul disco.
Se le statistiche ti danno speranza, allora devi "percorrere l'albero" delle directory sul dispositivo pertinente finché non trovi tutti i collegamenti fisici (o solo il primo, se non ne hai bisogno di più di uno e uno qualsiasi andrà bene ). A tale scopo, usi readdir (e opendir &c ovviamente) aprendo in modo ricorsivo le sottodirectory finché non trovi in un struct dirent
ha quindi ricevuto lo stesso numero di inode che avevi nel struct stat
originale (a quel punto se vuoi l'intero percorso, piuttosto che solo il nome, dovrai ripercorrere la catena di directory all'indietro per ricostruirla).
Se questo approccio generale è accettabile, ma hai bisogno di codice C più dettagliato, faccelo sapere, non sarà difficile da scrivere (anche se preferirei non scriverlo se è inutile, cioè non puoi sopportare le prestazioni inevitabilmente lente o il possibilità di ottenere !=1 risultato ai fini della tua candidatura;-).
In Windows, con GetFileInformationByHandleEx, passando FileNameInfo, puoi recuperare il nome del file.