Subrutina fcntl, dup o dup2
Finalidad
Controla los descriptores de archivos abiertos.
Biblioteca
Biblioteca C estándar (libc.a)
Biblioteca de compatibilidad de Berkeley (libbsd.a) (para la subrutina fcntl )
Sintaxis
#include <fcntl.h>
int fcntl ( Descriptor de archivo, Comando, Argumento) int Descriptor de archivo, Comando, Argumento;
#include <unistd.h>
int dup2( Antiguo, Nuevo) int Antiguo, Nuevo;
int dup( FileDescriptor) int FileDescriptor;
Descripción
La subrutina fcntl realiza operaciones de control en el archivo abierto especificado por el parámetro FileDescriptor . Si Network File System (NFS) está instalado en el sistema, el archivo abierto puede residir en otro nodo. La subrutina fcntl se utiliza para:
- Duplicados de descriptores de archivos abiertos.
- Establezca y obtenga los distintivos de descriptor de archivo.
- Establezca y obtenga los distintivos de estado de archivo.
- Gestionar bloqueos de registro.
- Gestionar la propiedad de E/S asíncrona.
- Cierre varios archivos.
La subrutina fcntl puede proporcionar las mismas funciones que las subrutinas dup y dup2 .
Si FileDescriptor hace referencia a un dispositivo de terminal o socket, se pueden utilizar los recursos de E/S asíncronos. Normalmente, estos recursos se habilitan utilizando la subrutina ioctl con los mandatos FIOASYNC, FIOSETOWNy FIOGETOWN . Sin embargo, también está disponible un mecanismo compatible con BSD si la aplicación está enlazada con la biblioteca libbsd.a .
Cuando el parámetro FileDescriptor hace referencia a un objeto de memoria compartida, la subrutina fcntl sólo gestiona los mandatos F_DUPFD, F_DUP2FD, F_GETFD, F_SETFD, F_GETFLy F_CLOSEM .
Cuando se utiliza la biblioteca libbsd.a , la E/S asíncrona se habilita utilizando el mandato F_SETFL con el distintivo FASYNC establecido en el parámetro Argument . Los mandatos F_GETOWN y F_SETOWN obtienen el propietario de E/S asíncrona actual y establecen el propietario de E/S asíncrona. Sin embargo, estos mandatos sólo son válidos cuando el descriptor de archivo hace referencia a un dispositivo de terminal o a un socket.
Todas las aplicaciones que contienen la subrutina fcntl deben cumplirse con _BSD establecido en un valor específico. Los valores aceptables son 43 y 44. Además, todas las aplicaciones de socket deben incluir la biblioteca BSD libbsd.a .
Información de bloqueo de registro general
Un bloqueo es un Obligatorio o bloqueo consultivo y un leer o un bloqueo de escritura.
Atención: La E/S de almacenamiento intermedio no funciona correctamente cuando se utiliza con el bloqueo de archivos. No utilice las rutinas de paquete de E/S estándar en los archivos que se van a bloquear.
Para que un bloqueo sea un bloqueo forzado, se debe establecer el atributo de bloqueo obligatorio del archivo; por ejemplo, se debe establecer el bit S_ENFMT , pero los bits S_IXGRP, S_IXUSRy S_IXOTH deben ser claros. De lo contrario, el bloqueo es un bloqueo de aviso. Un archivo determinado puede tener bloqueos de aviso o de ejecución, pero no ambos. La descripción del archivo sys/mode.h incluye una descripción de los atributos de archivo.
Cuando un proceso mantiene un bloqueo forzado en una sección de un archivo, ningún otro proceso puede acceder a esa sección del archivo con la subrutina leer o Escribir . Además, las subrutinas Abierto y ftruncate no pueden truncar la sección bloqueada del archivo y la subrutina fclear no puede modificar la sección bloqueada del archivo. Si otro proceso intenta leer o modificar la sección bloqueada del archivo, el proceso se duerme hasta que la sección se desbloquea o vuelve con una indicación de error.
Cuando un proceso mantiene un bloqueo de aviso en una sección de un archivo, ningún otro proceso puede bloquear esa sección del archivo (o una sección solapada) con la subrutina fcntl . (No hay otras subrutinas afectadas.) Como resultado, los procesos deben llamar voluntariamente a la subrutina fcntl para que los bloqueos de asesoramiento sean efectivos.
Cuando un proceso contiene un bloqueo de lectura en una sección de un archivo, otros procesos también pueden establecer bloqueos de lectura en esa sección o en subconjuntos del mismo. Los bloqueos de lectura también se llaman bloqueos de Compartido .
Un bloqueo de lectura impide que cualquier otro proceso establezca un bloqueo de escritura en cualquier parte del área protegida. Si el bloqueo de lectura también es un bloqueo forzado, ningún otro proceso puede modificar el área protegida.
El descriptor de archivo en el que se coloca un bloqueo de lectura debe haberse abierto con acceso de lectura.
Cuando un proceso contiene un bloqueo de escritura en una sección de un archivo, ningún otro proceso puede establecer un bloqueo de lectura o un bloqueo de grabación en esa sección. Los bloqueos de escritura también se llaman bloqueos de exclusivo . Sólo puede existir un bloqueo de grabación y no hay bloqueos de lectura para una sección específica de un archivo en cualquier momento.
Si el bloqueo también es un bloqueo forzado, ningún otro proceso puede leer o modificar el área protegida.
Se aplican las siguientes reglas generales sobre el bloqueo de archivos:
- Cambiar o desbloquear parte de un archivo en medio de una sección bloqueada deja dos secciones más pequeñas bloqueadas en cada extremo de la sección originalmente bloqueada.
- Si el proceso de llamada mantiene un bloqueo en un archivo, dicho bloqueo se puede sustituir por llamadas posteriores a la subrutina fcntl .
- Todos los bloqueos asociados con un archivo para un proceso determinado se eliminan cuando el proceso cierra el descriptor de archivo cualquier para dicho archivo.
- Un proceso hijo no hereda los bloqueos después de que se ejecute una subrutina fork .Nota: Los puntos muertos debido a bloqueos de archivo en un sistema distribuido no siempre se detectan. Cuando tales puntos muertos pueden ocurrir, los programas que solicitan los bloqueos deben establecer temporizadores de tiempo de espera.
Los bloqueos pueden empezar y extenderse más allá del final actual de un archivo, pero no pueden ser negativos en relación al principio del archivo. Se puede establecer un bloqueo para ampliar al final del archivo estableciendo lal_lencampo a 0. Si tal bloqueo también tiene ell_startyl_whencecampos establecidos en 0, todo el archivo está bloqueado. Los 2l_len,l_start, yl_whencelos campos de bloqueo forman parte de la estructura grey .
Cuando una aplicación bloquea una región de un archivo utilizando la interfaz de bloqueo de 32 bits (F_SETLK) y el último byte del rango de bloqueo incluye MAX_OFF (2 Gb-1), el rango de bloqueo para la solicitud de desbloqueo se ampliará para incluir MAX_END (2 ^ ^ 63-1).
Parámetros
| Elemento | Descripción |
|---|---|
| FileDescriptor | Especifica un descriptor de archivo abierto obtenido de una llamada satisfactoria a la subrutina Abierto , subrutina fcntl , subrutina pipa o subrutina shm_open . Los descriptores de archivo son pequeños enteros positivos utilizados (en lugar de nombres de pila) para identificar archivos o un objeto de memoria compartida. |
| Argumento | Especifica una variable cuyo valor establece la función especificada por el parámetro Comando . Cuando se trata de bloqueos de archivo, el parámetro Argumento debe ser un puntero a la estructura FLOCK . |
| Mandato | Especifica la operación realizada por la subrutina fcntl . La subrutina fcntl puede duplicar descriptores de archivos abiertos, establecer distintivos de descriptor de archivo, bloqueos de descriptor de archivo set , establecer ID de procesoy cerrar descriptores de archivos abiertos. |
Duplicación de descriptores de archivo
| Elemento | Descripción |
|---|---|
| F_DUPFD | Devuelve un descriptor de archivo nuevo como se indica a continuación:
|
Establecimiento de distintivos de descriptor de archivo
| Elemento | Descripción |
|---|---|
| F_GETFD | Obtiene el distintivo close-on-exec (bitFD_CLOEXEC ) que está asociado con el descriptor de archivo especificado por el parámetro FileDescriptor . Se ignora el parámetro Argumento . Los distintivos de descriptor de archivo están asociados a un único descriptor de archivo y no afectan a otros asociados con el mismo archivo. |
| F_SETFD | Asigna el valor del parámetro Argument al distintivo close-on-exec (FD_CLOEXEC bit) asociado con el parámetro FileDescriptor . Si el valor del distintivo FD_CLOEXEC es 0, el archivo permanece abierto en cualquier llamada a las subrutinas exec ; de lo contrario, el archivo se cerrará tras la ejecución satisfactoria de una subrutina de exec . |
| F_GETFL | Obtiene los distintivos de estado de archivo y las modalidades de acceso a archivo para la descripción de archivo abierta asociada con el descriptor de archivo especificado por el parámetro FileDescriptor . La descripción de archivo abierto se establece en el momento en que se abre el archivo y se aplica sólo a los descriptores de archivo asociados con esa llamada concreta al archivo. Este descriptor de archivo abierto no afecta a otros descriptores de archivo que hacen referencia al mismo archivo con diferentes descripciones de archivo abierto. Los distintivos de estado de archivo tienen los valores siguientes:
Las modalidades de acceso a archivo tienen los valores siguientes:
Los distintivos de acceso de archivo se pueden extraer del valor de retorno utilizando la máscara O_ACCMODE , que se define en el archivo fcntl.h . |
| F_SETFL | Establece los distintivos de estado de archivo de los bits correspondientes especificados por el parámetro Argumento . Los distintivos de estado de archivo se establecen para la descripción de archivo abierta asociada con el descriptor de archivo especificado por el parámetro FileDescriptor . Se pueden establecer las siguientes banderas:
Los distintivos O_NDELAY y O_NONBLOCK afectan únicamente a las operaciones contra los descriptores de archivo derivados de la misma subrutina Abierto . En BSD, estas operaciones se aplican a todos los descriptores de archivo que hacen referencia al objeto. |
Establecimiento de bloqueos de archivo
| Elemento | Descripción |
|---|---|
| F_GETLK | Obtiene información sobre el primer bloqueo que bloquea el bloqueo descrito en la estructura grey . El parámetro Argument debe ser un puntero a un tipo struct flock, tal como se define en el archivo flock.h . La información recuperada por la subrutina fcntl sobrescribe la información del struct grey al que apunta el parámetro Argumento . Si no se encuentra ningún bloqueo que impida que se cree este bloqueo, la estructura se deja sin cambios, excepto para el tipo de bloqueo (l_type) que está establecido en F_UNLCK. |
| F_SETLK | Establece o borra un bloqueo de segmento de archivo de acuerdo con la descripción de bloqueo señalada por el parámetro Argumento . El parámetro Argument debe ser un puntero a un tipo struct flock, que se define en el archivo flock.h . La opción F_SETLK se utiliza para establecer bloqueos de lectura (o compartido) (F_RDLCK), o bloqueos de escritura (o exclusivos) (F_WRLCK), así como para eliminar cualquier tipo de bloqueo (F_UNLCK). Los tipos de bloqueo se definen mediante el archivo fcntl.h . Si no se puede establecer un bloqueo compartido o exclusivo, la subrutina fcntl vuelve inmediatamente. |
| F_SETLKW | Realiza la misma función que la opción F_SETLK a menos que un bloqueo de lectura o grabación esté bloqueado por bloqueos existentes, en cuyo caso el proceso se duerme hasta que la sección del archivo está libre para bloquearse. Si se recibe una señal que debe ser capturada mientras la subrutina ' fcntl ' está esperando una región, la subrutina ' fcntl ' se interrumpe, devuelve un ' -1, pone la variable global ' errno ' a ' EINTR. La operación de bloqueo no se realiza. |
| Elemento | Descripción |
|---|---|
| F_GETLK64 | Obtiene información sobre el primer bloqueo que bloquea el bloqueo descrito en la estructura flock64 . El parámetro Argument debe ser un puntero a un objeto del tipo struct flock64, tal como se define en el archivo flock.h . La información recuperada por la subrutina fcntl sobrescribe la información de la estructura flock64 a la que apunta el parámetro Argument . Si no se encuentra ningún bloqueo que impida que se cree este bloqueo, la estructura se deja sin cambios, excepto para el tipo de bloqueo (l_type) que está establecido en F_UNLCK. |
| F_SETLK64 | Establece o borra un bloqueo de segmento de archivo de acuerdo con la descripción de bloqueo señalada por el parámetro Argumento . El parámetro Argument debe ser un puntero a un tipo struct flock64, que se define en el archivo flock.h . La opción F_SETLK se utiliza para establecer bloqueos de lectura (o compartido) (F_RDLCK), o bloqueos de escritura (o exclusivos) (F_WRLCK), así como para eliminar cualquier tipo de bloqueo (F_UNLCK). Los tipos de bloqueo se definen mediante el archivo fcntl.h . Si no se puede establecer un bloqueo compartido o exclusivo, la subrutina fcntl vuelve inmediatamente. |
| F_SETLKW64 | Realiza la misma función que la opción F_SETLK a menos que un bloqueo de lectura o grabación esté bloqueado por bloqueos existentes, en cuyo caso el proceso se duerme hasta que la sección del archivo está libre para bloquearse. Si se recibe una señal que debe ser capturada mientras la subrutina ' fcntl ' está esperando una región, la subrutina ' fcntl ' se interrumpe, devuelve un ' -1, pone la variable global ' errno ' a ' EINTR. La operación de bloqueo no se realiza. |
Establecer ID de proceso
| Elemento | Descripción |
|---|---|
| F_GETOWN | Obtiene el ID de proceso o el grupo de procesos que reciben actualmente señales SITIO y SIGURG . Los grupos de procesos se devuelven como valores negativos. |
| F_SETOWN | Establece el proceso o el grupo de procesos para recibir señales SITIO y SIGURG . Los grupos de procesos se especifican proporcionando un valor Argumento negativo. De lo contrario, el parámetro Argumento se interpreta como un ID de proceso. |
Cómo cerrar descriptores de archivo
| Elemento | Descripción |
|---|---|
| F_CLOSEM | Cierra todos los descriptores de archivo de FileDescriptor hasta el descriptor de archivo abierto actualmente más alto (U_maxofile). |
| VIEJO(S) | Especifica un descriptor de archivo abierto. |
| Nuevo | Especifica un descriptor de archivo abierto que devuelve la subrutina dup2 . |
Interfaces de compatibilidad
La subrutina lockfx
Las funciones de subrutina fcntl similares a la subrutina lockfx , cuando el parámetro Comando es F_SETLK, F_SETLKWo F_GETLK, y cuando se utilizan de la siguiente manera:
fcntl (Descriptor de archivo, Comando, Argumento)
equivale a:
lockfx (Descriptor de archivo, Comando, Argumento)
Las subrutinas dup y dup2
Las funciones de subrutina fcntl similares a las subrutinas dup y dup2 , cuando se utilizan de la siguiente manera:
dup (FileDescriptor)equivale a:
fcntl (FileDescriptor, F_DUPFD, 0) dup2 (Old, New)equivale a:
close (New);
fcntl(Old, F_DUPFD, New)Las subrutinas dup y dup2 difieren de la subrutina fcntl de las maneras siguientes:
- Si el descriptor de fichero especificado por el parámetro New es mayor o igual que OPEN_MAX, la subrutina dup2 devuelve un -1 y pone la variable errno a EBADF.
- Si el descriptor de archivo especificado por el parámetro Antiguo es válido e igual al descriptor de archivo especificado por el parámetro Nuevo , la subrutina dup2 devolverá el descriptor de archivo especificado por el parámetro Nuevo , sin cerrarlo.
- Si el descriptor de archivo especificado por el parámetro Antiguo no es válido, la subrutina dup2 no tendrá éxito y no cerrará el descriptor de archivo especificado por el parámetro Nuevo .
- El valor devuelto por las subrutinas dup y dup2 es igual al parámetro New al finalizar con éxito; de lo contrario, el valor devuelto es -1.
Valores de retorno
Tras la finalización satisfactoria, el valor devuelto depende del valor del parámetro Comando , como se indica a continuación:
| Elemento | Descripción |
|---|---|
| Mandato | Valor de retorno |
| F_DUPFD | Un descriptor de archivo nuevo |
| F_GETFD | El valor del distintivo (sólo se define el bit FD_CLOEXEC ) |
| F_SETFD | Un valor distinto de -1 |
| F_GETFL | El valor de los distintivos de archivo |
| F_SETFL | Un valor distinto de -1 |
| F_GETOWN | El valor del propietario del descriptor |
| F_SETOWN | Un valor distinto de -1 |
| F_GETLK | Un valor distinto de -1 |
| F_SETLK | Un valor distinto de -1 |
| F_SETLKW | Un valor distinto de -1 |
| F_CLOSEM | Un valor distinto de -1. |
Si la subrutina fcntl falla, se devuelve un valor de -1 y se establece la variable global errno para indicar el error.
Códigos de error
La subrutina fcntl no es satisfactoria si una o más de las siguientes son verdaderas:
| Elemento | Descripción |
|---|---|
| EACCES | El argumento Comando es F_SETLK; el tipo de bloqueo es un bloqueo compartido o exclusivo y el segmento de un archivo que se va a bloquear ya está bloqueado exclusivamente por otro proceso, o el tipo es un bloqueo exclusivo y parte del segmento de un archivo que se va a bloquear ya está bloqueado o no está bloqueado por otro proceso. |
| EBADF | El parámetro FileDescriptor no es un descriptor de archivo abierto válido. |
| EDEADLK | El argumento Comando es F_SETLKW; el bloqueo está bloqueado por algún bloqueo de otro proceso y poniendo el proceso de llamada a dormir, a la espera de que ese bloqueo quede libre causaría un punto muerto. |
| ENOTTY | El descriptor de archivo no hace referencia a un dispositivo de terminal o socket. |
| EMFILE | El parámetro Comando es F_DUPFDy el número máximo de descriptores de archivo están abiertos actualmente (OPEN_MAX). |
| EINVAL | El parámetro Comando es F_DUPFDy el parámetro Argumento es negativo o mayor o igual que OPEN_MAX. |
| EINVAL | Se ha proporcionado un valor no permitido para el parámetro Comando. |
| EINVAL | Se ha intentado bloquear un fifo o una pipa. |
| ESRCH | El valor del parámetro Comando es F_SETOWNy el ID de proceso especificado como el parámetro Argumento no se está utilizando. |
| EINTR | El parámetro Comando fue F_SETLKW y el proceso recibió una señal mientras esperaba para adquirir el bloqueo. |
| EVERFLOW | El parámetro Comando era F_GETLK y el bloqueo de bloque no se ha podido representar en la estructura grey . |
Las subrutinas dup y dup2 fallan si una o ambas de las siguientes son verdaderas:
| Elemento | Descripción |
|---|---|
| EBADF | El parámetro Antiguo especifica un descriptor de archivo abierto no válido o el parámetro Nuevo especifica un descriptor de archivo que está fuera de rango. |
| EMFILE | El número de descriptores de archivo excede el valor de OPEN_MAX o no hay ningún descriptor de archivo por encima del valor del parámetro Nuevo . |
Si NFS está instalado en el sistema, la subrutina fcntl puede fallar si se cumple lo siguiente:
| Elemento | Descripción |
|---|---|
| ETIMEDOUT | El tiempo de espera de la conexión. |