Tuve este problema en Mac OS X. No tenemos un /proc
sistema de archivos virtual, por lo que la solución aceptada no puede funcionar.
En cambio, tenemos un F_GETPATH
comando para fcntl
:
F_GETPATH Get the path of the file descriptor Fildes. The argu-
ment must be a buffer of size MAXPATHLEN or greater.
Entonces, para asociar el archivo a un descriptor de archivo, puede usar este fragmento:
#include <sys/syslimits.h>
#include <fcntl.h>
char filePath[PATH_MAX];
if (fcntl(fd, F_GETPATH, filePath) != -1)
{
// do something with the file path
}
Ya que nunca recuerdo donde MAXPATHLEN
está definido, pensé PATH_MAX
de syslimits estaría bien.
Puedes usar readlink
el /proc/self/fd/NNN
donde NNN es el descriptor de archivo. Esto le dará el nombre del archivo tal como era cuando se abrió; sin embargo, si el archivo se movió o eliminó desde entonces, es posible que ya no sea exacto (aunque Linux puede rastrear los cambios de nombre en algunos casos). Para verificar, stat
el nombre de archivo dado y fstat
el fd que tienes, y asegúrate de que st_dev
y st_ino
son iguales.
Por supuesto, no todos los descriptores de archivos se refieren a archivos, y para ellos verá algunas cadenas de texto extrañas, como pipe:[1538488]
. Dado que todos los nombres de archivo reales serán rutas absolutas, puede determinar cuáles son con bastante facilidad. Además, como han notado otros, los archivos pueden tener múltiples enlaces duros que apuntan a ellos; esto solo informará con el que se abrió. Si desea encontrar todos los nombres de un archivo determinado, solo tendrá que recorrer todo el sistema de archivos.
Como señala Tyler, no hay forma de hacer lo que necesita "directa y confiablemente", ya que un FD dado puede corresponder a 0 nombres de archivo (en varios casos) o> 1 (múltiples "enlaces duros" es como generalmente se describe la última situación ). Si aún necesita la funcionalidad con todas las limitaciones (sobre la velocidad Y sobre la posibilidad de obtener 0, 2, ... resultados en lugar de 1), así es como puede hacerlo:primero, fstat el FD:esto le dice , en el struct stat
resultante , en qué dispositivo se encuentra el archivo, cuántos enlaces duros tiene, si es un archivo especial, etc. Esto ya puede responder a su pregunta, p. si hay 0 enlaces fijos, SABRÁ que, de hecho, no hay un nombre de archivo correspondiente en el disco.
Si las estadísticas le dan esperanza, entonces tiene que "recorrer el árbol" de directorios en el dispositivo relevante hasta que encuentre todos los enlaces duros (o solo el primero, si no necesita más de uno y cualquiera servirá). ). Para ese propósito, usa readdir (y opendir &c por supuesto) abriendo subdirectorios recursivamente hasta que encuentre en un struct dirent
así recibió el mismo número de inodo que tenía en el struct stat
original (En ese momento, si desea la ruta completa, en lugar de solo el nombre, deberá recorrer la cadena de directorios hacia atrás para reconstruirla).
Si este enfoque general es aceptable, pero necesita un código C más detallado, infórmenos, no será difícil de escribir (aunque prefiero no escribirlo si es inútil, es decir, no puede soportar el rendimiento inevitablemente lento o el posibilidad de obtener !=1 resultado a efectos de su aplicación;-).
En Windows, con GetFileInformationByHandleEx, pasando FileNameInfo, puede recuperar el nombre del archivo.