Los descriptores de archivos son parte de la API POSIX . Cada proceso Unix (excepto quizás los daemons ) debería tener tres descriptores de archivos POSIX estándar, correspondientes a los tres flujos estándar :
Descripción general
En la implementación tradicional de Unix, los descriptores de archivos se indexan en un índice por proceso.tabla de descriptores de archivos mantenida por el núcleo, que a su vez indexa en una tabla de todo el sistema de archivos abiertos por todos los procesos, llamadatabla de archivos . Esta tabla registra elmodoen que se ha abierto el archivo (u otro recurso): para lectura, escritura, adición y posiblemente otros modos. También se indexa en una tercera tabla llamadatabla de inodosque describe los archivos subyacentes reales.[3] Para realizar la entrada o salida, el proceso pasa el descriptor de archivo al núcleo a través de unallamada al sistema, y el núcleo accederá al archivo en nombre del proceso. El proceso no tiene acceso directo a las tablas de archivos o inodos.
En Linux , se puede acceder al conjunto de descriptores de archivos abiertos en un proceso a través de path /proc/PID/fd/, donde PID es el identificador del proceso . Los descriptores de archivos /proc/PID/fd/0son stdin, /proc/PID/fd/1is stdouty /proc/PID/fd/2is stderr. Como atajo a estos, cualquier proceso en ejecución también puede acceder a sus propios descriptores de archivos a través de las carpetas /proc/self/fdy /dev/fd. [4]
La estructura de datos FILE de la biblioteca de E/S estándar de C suele incluir un descriptor de archivo de bajo nivel para el objeto en cuestión en sistemas tipo Unix. La estructura de datos general proporciona una abstracción adicional y se conoce como identificador de archivo .
Operaciones sobre descriptores de archivos
A continuación se enumeran las operaciones típicas sobre descriptores de archivos en sistemas modernos similares a Unix . La mayoría de estas funciones se declaran en el <unistd.h>encabezado, pero algunas se encuentran en el <fcntl.h>encabezado.
Operaciones en la tabla de descriptores de archivos
La función fcntl() se utiliza para realizar varias operaciones en un descriptor de archivo, según el argumento del comando que se le pase. Hay comandos para obtener y establecer atributos asociados con un descriptor de archivo, incluidos F_GETFD, F_SETFD, F_GETFL y F_SETFL .
closefrom() (sólo BSD y Solaris; elimina todos los descriptores de archivos mayores o iguales al número especificado)
close_range() (para Linux) [6]
dup() (duplica un descriptor de archivo existente garantizando que sea el descriptor de archivo con el número más bajo disponible)
dup2 () , dup3() (Cierra fd1 si es necesario y hace que el descriptor de archivo fd1 apunte al archivo abierto de fd2)
función fcntl (F_DUPFD)
Operaciones que modifican el estado del proceso
fchdir() (establece el directorio de trabajo actual del proceso en función de un descriptor de archivo de directorio)
mmap () (mapea rangos de un archivo en el espacio de direcciones del proceso)
Bloqueo de archivos
rebaño()
fcntl() (F_GETLK, F_SETLK y F_SETLKW)
bloqueof()
Zócalos
conectar()
unir()
escuchar()
accept() (crea un nuevo descriptor de archivo para una conexión entrante)
obtenernombrecalcetín()
obtenernombredepar()
obtienesockopt()
conjuntosockopt()
shutoff() (apaga una o ambas mitades de una conexión dúplex completa)
Misceláneas
ioctl() (una gran colección de operaciones diversas en un único descriptor de archivo, a menudo asociado con un dispositivo)
Próximas operaciones
Se ha añadido una serie de nuevas operaciones sobre descriptores de archivos a muchos sistemas modernos similares a Unix, así como a numerosas bibliotecas de C, para que se estandaricen en una versión futura de POSIX . [7] El atsufijo significa que la función toma un primer argumento adicional que proporciona un descriptor de archivo a partir del cual se resuelven las rutas relativasat , por lo que las formas que carecen del sufijo se vuelven equivalentes a pasar un descriptor de archivo correspondiente al directorio de trabajo actual . El propósito de estas nuevas operaciones es defenderse contra una cierta clase de ataques TOCTOU .
abierto()
funciónaccesat()
fchmodat()
fchownat()
fstatat()
futimesat()
enlace()
mkdirat()
mknodat()
leerlinkat()
renombrar()
enlace simbólico()
desvincular()
mkfifoat()
fdopendir()
Descriptores de archivos como capacidades
Los descriptores de archivos de Unix se comportan de muchas maneras como capacidades . Se pueden pasar entre procesos a través de sockets de dominio Unix utilizando la sendmsg()llamada al sistema. Sin embargo, tenga en cuenta que lo que realmente se pasa es una referencia a una "descripción de archivo abierto" que tiene un estado mutable (el desplazamiento del archivo y los indicadores de acceso y estado del archivo). Esto complica el uso seguro de los descriptores de archivos como capacidades, ya que cuando los programas comparten el acceso a la misma descripción de archivo abierto, pueden interferir con el uso que hacen los demás al cambiar su desplazamiento o si es bloqueante o no bloqueante, por ejemplo. [8] [9] En los sistemas operativos que están diseñados específicamente como sistemas de capacidades, rara vez hay un estado mutable asociado con una capacidad en sí.
La tabla de descriptores de archivos de un proceso Unix es un ejemplo de una lista C.
^ The Open Group . «Especificaciones básicas de The Open Group, número 7, IEEE Std 1003.1-2008, edición 2016» . Consultado el 21 de septiembre de 2017 .
^ The Open Group. «Especificaciones básicas de The Open Group, número 7, IEEE Std 1003.1-2008, edición 2016». <stdio.h> . Consultado el 21 de septiembre de 2017 .
^ ab Bach, Maurice J. (1986). El diseño del sistema operativo UNIX (8.ª ed.). Prentice-Hall . pp. 92–96. ISBN9780132017992.
^ "Dispositivos: ¿Qué significa la salida de 'll /Proc/Self/Fd/' (de 'll /Dev/Fd')?".
^ The Open Group . «Especificaciones básicas de The Open Group, número 7, IEEE Std 1003.1-2008, edición 2018 – creat» . Consultado el 11 de abril de 2019 .
^ Stephen Kitt, Michael Kerrisk. «close_range(2) — Página del manual de Linux» . Consultado el 22 de marzo de 2021 .
^ Conjunto de API ampliado, parte 2. The Open Group. Octubre de 2006. ISBN1931624674.
^ Brinkmann, Marcus (4 de febrero de 2009). "Construyendo un puente: API de bibliotecas y descriptores de archivos". cap-talk . Archivado desde el original el 30 de julio de 2012 . Consultado el 21 de septiembre de 2017 .
^ de Boyne Pollard, Jonathan (2007). "No configure los descriptores de archivos compartidos en modo de E/S sin bloqueo" . Consultado el 21 de septiembre de 2017 .