¿Es posible obtener el nombre de archivo de un descriptor de archivo (Linux) en C?
c
linux
file
file-descriptor
adk
fuente
fuente
Respuestas:
Se puede utilizar
readlink
en/proc/self/fd/NNN
donde NNN es el descriptor de archivo. Esto le dará el nombre del archivo tal como estaba 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 verificarlo,stat
el nombre de archivo dado yfstat
el DF que tiene, y asegúresest_dev
yst_ino
son los mismos.Por supuesto, no todos los descriptores de archivo 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 señalado otros, los archivos pueden tener varios vínculos físicos que los apunten; 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.fuente
fd
sería dicha referencia), el número de inodo no se puede reutilizar. Cualquier software que utilice un número de inodo después de cerrar el archivo o antes de abrirlo está inherentemente sujeto a condiciones de carrera.setuid()
trucos, es posible/proc/self/fd
que su proceso no pueda acceder a él. Ver: permalink.gmane.org/gmane.linux.kernel/1302546Tuve 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 parafcntl
:Entonces, para obtener el archivo asociado a un descriptor de archivo, puede usar este fragmento:
Como nunca recuerdo dónde
MAXPATHLEN
está definido, pensé quePATH_MAX
desde syslimits estaría bien.fuente
getsockname
.En Windows, con GetFileInformationByHandleEx , pasando FileNameInfo , puede recuperar el nombre del archivo.
fuente
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 se describe generalmente esta última situación ). Si aún necesita la funcionalidad con todas las limitaciones (en velocidad Y en 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 resultado
struct stat
, en qué dispositivo vive el archivo, cuántos enlaces físicos tiene, si es un archivo especial, etc. Esto ya puede responder a su pregunta, por ejemplo, si hay 0 enlaces físicos, SABERÁ que de hecho no hay un nombre de archivo correspondiente. en 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 físicos (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 de manera recursiva hasta que encuentre en un
struct dirent
así recibido el mismo número de inodo que tenía en el originalstruct stat
(en ese momento, si desea la ruta completa, en lugar de solo el nombre, necesitará caminar la cadena de directorios hacia atrás para reconstruirlo).Si este enfoque general es aceptable, pero necesita un código C más detallado, avísenos, 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 para los propósitos de su aplicación ;-).
fuente
Antes de descartar esto como imposible, le sugiero que mire el código fuente del comando lsof .
Puede haber restricciones, pero lsof parece capaz de determinar el descriptor y el nombre del archivo. Esta información existe en el sistema de archivos / proc, por lo que debería ser posible acceder a ella desde su programa.
fuente
Puede usar fstat () para obtener el inodo del archivo por struct stat. Luego, usando readdir () puede comparar el inodo que encontró con los que existen (struct dirent) en un directorio (asumiendo que conoce el directorio, de lo contrario tendrá que buscar en todo el sistema de archivos) y encontrar el nombre de archivo correspondiente. ¿Asqueroso?
fuente
Imposible. Un descriptor de archivo puede tener varios nombres en el sistema de archivos o puede que no tenga ningún nombre.
Editar: Suponiendo que está hablando de un sistema POSIX antiguo, sin ninguna API específica del sistema operativo, ya que no especificó un sistema operativo.
fuente