È possibile ottenere il nome del file di un descrittore di file (Linux) in C?
È possibile ottenere il nome del file di un descrittore di file (Linux) in C?
Risposte:
È possibile utilizzare readlinksu /proc/self/fd/NNNdove NNN è il descrittore di file. Questo ti darà il nome del file com'era quando è stato aperto - tuttavia, se il file è stato spostato o cancellato da allora, potrebbe non essere più accurato (sebbene Linux possa tenere traccia delle rinomine in alcuni casi). Per verificare, statil nome del file dato e fstatil fd che hai, e assicurati che st_deve st_inosiano gli stessi.
Ovviamente, 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 dato file, dovrai solo attraversare l'intero filesystem.
fdsarebbe un tale riferimento), il numero di inode non può essere riutilizzato. Qualsiasi software che utilizza un numero di inode dopo aver chiuso il file o prima di aprirlo è intrinsecamente soggetto a condizioni di competizione.
setuid()trucchi, è possibile /proc/self/fdche non sia accessibile dal tuo processo. Vedi: permalink.gmane.org/gmane.linux.kernel/1302546
Ho avuto questo problema su Mac OS X. Non abbiamo un /procfile system virtuale, quindi la soluzione accettata non può funzionare.
Abbiamo, invece, un F_GETPATHcomando 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 a un descrittore di file, puoi usare 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 ricordo mai dove MAXPATHLENè definito, ho pensato che PATH_MAXda syslimits sarebbe andato bene.
getsockname.
In Windows, con GetFileInformationByHandleEx , passando FileNameInfo , è possibile recuperare il nome del file.
Come fa notare Tyler, non c'è modo di fare ciò che si richiede "direttamente e in modo affidabile", poiché un dato FD può corrispondere a 0 nomi di file (in vari casi) o> 1 (più "collegamenti fisici" è come viene generalmente descritta l'ultima situazione ). Se hai ancora bisogno della funzionalità con tutte le limitazioni (sulla velocità E sulla possibilità di ottenere 0, 2, ... risultati invece di 1), ecco come puoi farlo: primo, fstat FD - questo ti dice , nel risultato struct stat, su quale dispositivo risiede il file, quanti collegamenti fisici ha, se si tratta di un file speciale, ecc. Questo potrebbe già rispondere alla tua domanda - ad es. se 0 collegamenti fisici SAPRETE che in realtà non esiste un nome file corrispondente su 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 più di uno e nessuno lo farà ). A tale scopo, usi readdir (e opendir & c ovviamente) aprendo ricorsivamente le sottodirectory finché non trovi in un struct direntcosì ricevuto lo stesso numero di inode che avevi nell'originale struct stat(in quel momento se vuoi l'intero percorso, piuttosto che solo il nome, dovrai percorrere 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 dell'applicazione ;-).
Prima di scrivere questo come impossibile ti suggerisco di guardare il codice sorgente del comando lsof .
Potrebbero esserci delle restrizioni ma lsof sembra in grado di determinare il descrittore e il nome del file. Queste informazioni esistono nel filesystem / proc quindi dovrebbe essere possibile ottenerle dal tuo programma.
Puoi usare fstat () per ottenere l'inode del file da struct stat. Quindi, usando readdir () puoi confrontare l'inode che hai trovato con quelli che esistono (struct dirent) in una directory (assumendo che tu conosca la directory, altrimenti dovrai cercare in tutto il filesystem) e trovare il nome del file corrispondente. Cattiva?
Impossibile. Un descrittore di file può avere più nomi nel filesystem o potrebbe non avere alcun nome.
Modifica: supponendo che tu stia parlando di un semplice vecchio sistema POSIX, senza API specifiche del sistema operativo, poiché non hai specificato un sistema operativo.