Provided by:
manpages-es_1.55-10_all 
NOMBRE
fcntl - manipula el descriptor de fichero
SINOPSIS
#include <unistd.h>
#include <fcntl.h>
int fcntl(int fd, int cmd);
int fcntl(int fd, int cmd, long arg);
int fcntl(int fd, int cmd, struct flock *lock);
DESCRIPCI'ON
fcntl realiza una de las diversas y variadas operaciones que se pueden
hacer sobre fd. La operacion en cuestion se determina mediante cmd.
Tratamiento de la bandera <<cerrar al ejecutar>>
F_DUPFD
Busca el descriptor de fichero disponible de menor numero, mayor
o igual que arg, y lo convierte en una copia de fd. Esto es
diferente en dup2(2) que usa exactamente el descriptor
especificado.
Los descriptores antiguo y nuevo pueden usarse indistintamente.
Ambos comparten bloqueos (``locks''), indicadores de posicion de
ficheros y opciones o banderas (``flags''); por ejemplo, si la
posicion del fichero se modifica usando lseek en uno de los
descriptores, la posicion del otro resulta modificada
simultaneamente.
Sin embargo, los dos descriptores no comparten la bandera close-
on-exec (<<cerrar al ejecutar>>). La bandera close-on-exec de la
copia esta desactivada, lo que significa que no se cerrara al
ejecutar.
En caso de exito, se devuelve el nuevo descriptor.
F_GETFD
Lee la bandera close-on-exec. Si el bit FD_CLOEXEC es 0, el
fichero permanecera abierto tras exec, en caso contrario se
cerrara el fichero.
F_SETFD
Establece la bandera close-on-exec al valor especificado por el
bit FD_CLOEXEC de arg.
Banderas de situaci'on de un fichero
Un descriptor de fichero posee ciertas banderas asociadas,
inicializadas por open(2) y posiblemente modificadas por fcntl(2). Las
banderas se comparten entre copias (hechas con dup(2), fork(2), etc.)
del mismo descriptor de fichero.
Las banderas y su semantica estan descritas en open(2).
F_GETFL
Lee las banderas de un descriptor de fichero.
F_SETFL
De las banderas de un descriptor, establece la parte que se
corresponde con las banderas de situacion de un fichero al valor
especificado por arg. Los restantes bits (modo de acceso,
banderas de creacion de un fichero) de arg se ignoran. En
Linux, esta orden solo puede cambiar las banderas O_APPEND,
O_NONBLOCK, O_ASYNC y O_DIRECT.
Bloqueos (candados) consultivos
F_GETLK, F_SETLK y F_SETLKW se usan para adquirir, liberar y comprobar
la existencia de bloqueos de registros (tambien conocidos como bloqueos
de segmentos de ficheros o regiones de ficheros). El tercer argumento
lock es un puntero a una estructura que tiene, al menos, los siguientes
campos (en un orden indeterminado).
struct flock {
...
short l_type; /* Tipo de bloqueo: F_RDLCK,
F_WRLCK, F_UNLCK */
short l_whence; /* Como interpretar l_start:
SEEK_SET, SEEK_CUR, SEEK_END */
off_t l_start; /* Direccion de inicio del bloqueo */
off_t l_len; /* Numero de bytes a bloquear */
pid_t l_pid; /* PID del proceso que bloquea nuestro candado
(solo F_GETLK) */
...
};
Los campos l_whence, l_start y l_len de esta estructura especifican el
rango de bytes que deseamos bloquear. l_start es la direccion inicial
para el bloqueo y se interpreta relativa a: el inicio del fichero (si
l_whence es SEEK_SET); la posicion actual dentro del fichero (si
l_whence es SEEK_CUR) o el fin del fichero (si l_whence es SEEK_END).
En los dos ultimos casos, l_start puede ser un numero negativo siempre
que la direccion inicial final no quede antes del principio del
fichero. l_len es un entero no negativo (aunque vea NOTAS mas abajo)
que indica el numero de bytes a bloquear. Los bytes que se encuentren
mas alla del final del fichero se pueden bloquear, pero no los bytes
que se encuentren antes del inicio del fichero. El especificar 0 para
l_len tiene un significado especial: bloquear todos los bytes desde la
posicion indicada por l_whence y l_start hasta el final del fichero,
sin importar cuanto crezca el fichero.
El campo l_type se puede usar para colocar un bloqueo de lectura
(F_RDLCK) o de escritura (F_WDLCK) sobre un fichero. Varios procesos
pueden tener un bloqueo de lectura (bloqueo compartido) sobre una
region de fichero, pero solo un proceso puede tener un bloqueo de
escritura (bloqueo exclusivo). Un bloqueo exclusivo excluye a todos los
demas bloqueos, tanto compartidos como exclusivos. Un unico proceso
solo puede tener un tipo de bloqueo sobre una region de fichero; si se
aplica un nuevo bloqueo a una region ya bloqueada, el bloqueo existente
se convierte al nuevo tipo de bloqueo. (Tales conversiones pueden
suponer dividir, reducir o fusionar un bloqueo existente si el rango de
bytes especificado por el nuevo bloqueo no coincide exactamente con el
rango del bloqueo existente).
F_SETLK
Adquiere un bloqueo (cuando l_type es F_RDLCK o F_WRLCK) o
libera un bloqueo (cunado l_type es F_UNLCK) sobre los bytes
especificados por los campos l_whence, l_start y l_len de lock.
Si otro proceso mantiene ya un bloqueo que entra en conflicto
con el nuevo, la llamada devuelve -1 y asigna a errno el codigo
de error EACCES o EAGAIN.
F_SETLKW
Como F_SETLK, pero si ya hay un bloqueo sobre el fichero que
entra en conflicto con el nuevo, entonces espera a que el
bloqueo se libere. Si llega y se captura una senal mientras se
esta esperando, se interrumpe la llamada y (tras terminar el
manejador de senal) regresa inmediatamente (devolviendo -1 y
asignado a errno el valor EINTR).
F_GETLK
Al entrar a esta llamada, lock describe un bloqueo que nos
gustaria colocar en un fichero. Si el bloqueo se pudiera
colocar, fcntl() realmente no lo colocara, pero devolvera
F_UNLCK en el campo l_type de lock y dejara los otros campos de
la estructura sin cambiar. Si uno o mas bloqueos incompatibles
impidieran que este bloqueo se colocara, entonces fcntl()
devolvera detalles sobre uno de estos bloqueos en los campos
l_type, l_whence, l_start y l_len de lock y asignara a l_pid el
PID del proceso que posee el bloqueo.
Para colocar un bloqueo de lectura, se debe abrir fd para lectura. Para
colocar un bloqueo de escritura, se debe abrir fd para escritura. Para
colocar ambos tipos de bloqueo, abra un fichero para lectura y
escritura.
Ademas de ser eliminados por un F_UNLCK explicito, los bloqueos de
registros se liberan automaticamente cuando un proceso termina o cierra
cualquier descriptor de fichero que haga referencia a un fichero sobre
el que se mantienen los bloqueos. Esto esta mal: significa que un
proceso puede perder los bloqueos sobre un fichero como /etc/passwd o
/etc/mtab cuando, por alguna razon, una funcion de biblioteca decida
abrir, leer y cerrar el fichero.
Los bloqueos de registros no los hereda un hijo creado mediante
fork(2), pero se conservan a traves de execve(2).
Debido al almacenamiento temporal que realiza stdio(3), se deberia
evitar el bloqueo de registros con rutinas de esa biblioteca; en su
lugar, use read(2) y write(2).
Bloqueos obligatorios
(No POSIX.) Los bloqueos de registro anteriores pueden ser o bien
consultivos o bien obligatorios, y son consultivos por omision. Para
usar bloqueos obligatorios, se debe habilitar dicho tipo de bloqueo en
el sistema de ficheros que contiene el fichero a bloquear (usando la
opcion "-o mand" en mount(8)) y en el propio fichero (deshabilitando el
permiso de ejecucion para el grupo y activado el bit de permiso set-
GID).
Los bloqueos consultivos no son de obligado cumplimiento y solo son
utiles entre procesos que cooperan. Los bloqueos obligatorios son
respetados por todos los procesos.
Manejo de se~nales
F_GETOWN, F_SETOWN, F_GETSIG y F_SETSIG se utilizan para gestionar las
senales de disponibilidad de E/S:
F_GETOWN
Obtiene el ID de proceso o el grupo de procesos que actualmente
recibe las senales SIGIO y SIGURG para los eventos sobre el
descriptor de fichero fd.
Los grupos de procesos se devuelven como valores negativos.
F_SETOWN
Establece el ID de proceso o el grupo de procesos que recibira
las senales SIGIO y SIGURG para los eventos sobre el descriptor
de fichero fd.
Los grupos de procesos se especifican mediante valores
negativos. (Se puede usar F_SETSIG para especificar una senal
diferente a SIGIO).
Si activa la bandera de estado O_ASYNC sobre un descriptor de
fichero (tanto si proporciona esta bandera con la llamada
open(2) como si usa la orden F_SETFL de fcntl), se enviara una
senal SIGIO cuando sea posible la entrada o la salida sobre ese
descriptor de fichero.
El proceso o el grupo de procesos que recibira la senal se puede
seleccionar usando la orden F_SETOWN de la funcion fcntl. Si el
descriptor de fichero es un conector (``socket''), esto tambien
seleccionara al recipiente de las senales SIGURG que se entregan
cuando llegan datos fuera de orden (``out-of-band'', OOB) sobre
el enchufe. (SIGURG se envia en cualquier situacion en la que
select(2) informaria que el conector tiene una "condicion
excepcional"). Si el descriptor de fichero corresponde a un
dispositivo de terminal, entonces las senales SIGIO se envian al
grupo de procesos en primer plano de la terminal.
F_GETSIG
Obtiene la senal enviada cuando la entrada o la salida son
posibles. Un valor cero significa que se envia SIGIO. Cualquier
otro valor (incluyendo SIGIO) es la senal enviada en su lugar y
en este caso se dispone de informacion adicional para el
manejador de senal si este se instala con SA_SIGINFO.
F_SETSIG
Establece la senal enviada cuando la entrada o la salida son
posibles. Un valor cero significa enviar la senal por defecto
SIGIO. Cualquier otro valor (incluyendo SIGIO) es la senal a
enviar en su lugar y en este caso se dispone de informacion
adiciona para el manejador de senal si este se instala con
SA_SIGINFO.
Usando F_SETSIF con un valor distinto de cero y asignando
SA_SIGINFO para el manejador de senal (vea sigaction(2)), se
pasa informacion extra sobre los eventos de E/S al manejador en
la estructura siginfo_t. Si el campo si_code indica que la
fuente es SI_SIGIO, el campo si_fd proporciona el descriptor de
fichero asociado con el evento. En caso contrario, no se indican
que descriptores de ficheros hay pendientes y, para determinar
que descriptores de fichero estan disponibles para E/S, deberia
usar los mecanismos usuales (select(2), poll(2), read(2) con
O_NONBLOCK activo, etc.).
Seleccionando una senal de tiempo real POSIX.1b (valor >=
SIGRTMIN), se pueden encolar varios eventos de E/S usando los
mismos numeros de senal. (El encolamiento depende de la memoria
disponible). Se dispone de informacion extra si se asigna
SA_SIGINFO al manejador de senal, como antes.
Usando estos mecanismos, un programa puede implementar E/S totalmente
asincrona, sin usar select(2) ni poll(2) la mayor parte del tiempo.
El uso de O_ASYNC, F_GETOWN y F_SETOWN es especifico de Linux y BSD.
F_GETSIG y F_SETSIG son especificos de Linux. POSIX posee E/S asincrona
y la estructura aio_sigevent para conseguir cosas similares; estas
tambien estan disponibles en Linux como parte de la biblioteca de C de
GNU (GNU C Library, Glibc).
Arrendamientos
F_SETLEASE y F_GETLEASE (Linux 2.4 y posteriores) se usan
(respectivamente) para establecer y obtener la configuracion actual del
arrendamiento del proceso invocador sobre el fichero referenciado por
fd. Un arrendamiento de fichero proporciona un mecanismo por medio del
cual al proceso que posee el arrendamiento (el "arrendatario") se le
notifica (mediante el envio de una senal) cuando otro proceso (el
"competidor") intenta abrir (open(2)) o truncar (truncate(2)) ese
fichero.
F_SETLEASE
Establece o elimina un arrendamiento de fichero segun que valor
de los siguientes se especifique en el entero arg:
F_RDLCK
Obtiene un arrendamiento de lectura. Esto hara que se nos
informe cuando otro proceso abra el fichero para escribir
en el o cuando lo trunque.
F_WRLCK
Obtiene un arrendamiento de escritura. Esto hara que se
nos informe cuando otro proceso abra el fichero (para
leer o escribir) o lo trunque. Solo se puede colocar un
arrendamiento de escritura en un fichero cuando ningun
otro proceso lo tenga abierto en ese momento.
F_UNLCK
Elimina nuestro arrendamiento del fichero.
Un proceso solo puede tener un tipo de arrendamiento sobre un fichero.
Los arrendamientos solo se pueden obtener para ficheros regulares. Un
proceso normal solo puede obtener un arrendamiento sobre un fichero
cuyo UID coincida con el UID de sistema de ficheros del proceso.
F_GETLEASE
Indica que tipo de arrendamiento tenemos sobre el fichero
referenciado por fd devolviendo F_RDLCK, F_WRLCK o F_UNLCK, lo
que indica, respectivamente, que el proceso invocador posee un
arrendamiento de lectura, de escritura o que no posee
arrendamiento alguno sobre el fichero. (El tercer argumento de
fcntl() se omite.)
Cuando el competidor realiza un open() o truncate() que entra en
conflicto con un arrendamiento establecido mediante F_SETLEASE, el
nucleo bloquea la llamada al sistema (a menos que se especifique la
opcion O_NONBLOCK en open(), en cuyo caso la llamada regresa
inmediatamente con el error EWOULDBLOCK). El nucleo entonces notifica
al arrendatario enviandole una senal (SIGIO por omision). El
arrendatario debe responder a la recepcion de esta senal haciendo
cualquier limpieza que sea necesaria para preparar el fichero para que
sea accedido por otro proceso (por ejemplo, vaciando los buffers en
cache) y entonces eliminar su arrendamiento ejecuntado una orden
F_SETLEASE que especifique en arg el valor F_UNLCK.
Si el arrendatario no libera el arrendamiento antes del numero de
segundos especificado en /proc/sys/fs/lease-break-time y la llamada al
sistema del competidor sigue bloqueada (es decir, el competidor no
especifico O_NONBLOCK en su llamada open() y la llamada al sistema no
ha sido interrumpida por un manejador de senal), entonces el nucleo
pone fin al arrendamiento del arrendatario por la fuerza.
Una vez que se ha eliminado voluntariamente o por la fuerza el
arrendamiento, y suponiendo que el competidor no ha desbloqueado su
llamada al sistema, el nucleo permite continuar a la llamada al sistema
del competidor.
La senal por omision que se usa para informar al arrendatario es SIGIO,
pero se puede cambiar usando la orden F_SETSIG de fcntl (). Si se
ejecuta una orden F_SETSIG (incluso una que especifique SIGIO) y el
manejador de senal se establece usando SA_SIGINFO, el manejador
recibira una estructura siginfo_t como su segundo argumento y el campo
si_fd de este argumento contendra el descriptor del fichero arrendado
que ha sido accedido por otro proceso. (Esto es util si el invocador
tiene arrendamientos para varios ficheros).
Notificaci'on de cambios en ficheros y directorios
F_NOTIFY
(Linux 2.4 y posteriores) Produce una notificacion cuando cambia
el directorio referenciado por fd o cualquiera de los ficheros
que contiene. Los eventos a notificar se indican en arg, que es
una mascara de bits que se especifica mediante un O-logico de
cero o mas de los siguientes bits:
Bit Descripcion (evento en el directorio)
---------------------------------------------------------------------
DN_ACCESS Se ha accedido a un fichero (read, pread, readv)
DN_MODIFY Se ha modificado un fichero (write, pwrite,
writev, truncate, ftruncate)
DN_CREATE Se ha creado un fichero (open, creat, mknod,
mkdir, link, symlink, rename)
DN_DELETE Se ha borrando un fichero (unlink, rename a
otro directorio, rmdir)
DN_RENAME Se ha cambiado el nombre de un fichero de este
directorio (rename)
DN_ATTRIB Se han cambiado los atributos de un fichero
(chown, chmod, utime[s])
(Para obtener estas definiciones, se debe define la macro
_GNU_SOURCE antes de incluir <fcntl.h>.)
Las notificaciones de directorio normalmente se reciben una
unica vez (son de tipo ``one-shot'') y la aplicacion debe volver
a hacer el registro para recibir notificaciones adicionales.
Otra posibilidad es incluir DN_MULTISHOT en arg, en cuyo caso la
notificacion se producira hasta que se elimine explicitamente.
Una serie de llamadas que especifican DN_MULTISHOT es
acumulativa, con los eventos en arg anadiendose al conjunto ya
monitorizado. Para desactivar la notificacion de todos los
eventos, haga una llamada F_NOTIFY especificando 0 en arg.
La notificacion se produce mediante el envio de una senal. La
senal por omision es SIGIO, pero se puede cambiar usando la
orden F_SETSIG de fcntl(). En el segundo caso, el manejador de
senal recibe una estructura siginfo_t como su segundo argumento
(si el manejador se establecio usando SA_SIGINFO) y el campo
si_fd de esta estructura contiene el descriptor de fichero que
produjo la notificacion (util cuando se establecen
notificaciones en varios directorios).
Especialmente cuando se usa DN_MULTISHOT, se deberia usar una
senal POSIX.1b de tiempo real para notificacion, de tal manera
que se pueden encolar multiples notificaciones.
VALOR DEVUELTO
Para una llamada con exito, el valor devuelto depende de la operacion:
F_DUPFD El nuevo descriptor.
F_GETFD Valor de la bandera.
F_GETFL Valor de las banderas.
F_GETOWN Valor del propietario del descriptor.
F_GETSIG Valor de la senal enviada cuando la lectura o la escritura son
posibles o cero para el comportamiento tradicional con SIGIO.
Para cualquier otra orden
Cero.
En caso de error el valor devuelto es -1 y se asigna a errno un valor
apropiado.
ERRORES
EACCESS o EAGAIN
Se ha prohibido la operacion debido a bloqueos mantenidos por
otros procesos. O se ha prohibido la operacion porque el
fichero ha sido proyectado (``mapped'') en memoria por otro
proceso.
EDEADLK
Se ha detectado que la orden F_SETLKW especificada provocaria un
interbloqueo.
EFAULT lock esta fuera de su espacio de direcciones accesible.
EBADF fd no es un descriptor de fichero abierto o la orden era F_SETLK
o F_SETLKW y el modo de apertura del descriptor de fichero no
coincide con el tipo de bloqueo solicitado.
EINTR Para F_SETLKW, la orden ha sido interrumpida por una senal.
Para F_GETLK y F_SETLK, la orden ha sido interrumpida por una
senal antes de que el bloqueo se haya comprobado o adquirido.
Esto ocurre con mas probabilidad al poner un bloqueo en un
fichero remoto (por ejemplo, un bloqueo sobre NFS) pero algunas
veces puede ocurrir localmente.
EINVAL Para F_DUPFD, arg es negativo o mayor que el valor maximo
permitido. Para F_SETSIG, arg no es un numero de senal
permitido.
EMFILE Para F_DUPFD, el proceso ya ha llegado al numero maximo de
descriptores de ficheros abiertos.
ENOLCK Demasiados bloqueos de segmentos abiertos, la tabla de bloqueos
esta llena o ha fallado un protocolo de bloqueos remoto (por
ejemplo, un bloqueo sobre NFS).
EPERM Se ha intentado quitar la bandera O_APPEND sobre un fichero que
tiene activo el atributo de ``solo anadir'' (append-only).
OBSERVACIONES
Los errores devueltos por dup2 son distintos de aquellos dados por
F_DUPFD.
Desde el nucleo 2.0, no hay interaccion entre los tipos de bloqueo
colocados por flock(2) y fcntl(2).
POSIX 1003.1-2001 permite que l_len sea negativo. (Y si lo es, el
intervalo descrito por el bloqueo cubre los bytes desde l_start+l_len
hasta l_start-1 inclusive.) Sin embargo, para los nucleos actuales, la
llamada al sistema de Linux devuelve EINVAL en esta situacion.
Otros sistemas tienen mas campos en struct flock como, por ejemplo,
l_sysid. Evidentemente, l_pid solo no va a ser muy util si el proceso
que posee el bloqueo puede residir en una maquina diferente.
CONFORME A
SVID, AT&T, POSIX, X/OPEN, BSD 4.3. Solo las operaciones F_DUPFD,
F_GETFD, F_SETFD, F_GETFL, F_SETFL, F_GETLK, F_SETLK y F_SETLKW se
especifican en POSIX.1. F_GETOWN y F_SETOWN son BSD-ismos no aceptados
en SVr4; F_GETSIG y F_SETSIG son especificos de Linux. F_NOTIFY,
F_GETLEASE y F_SETLEASE son especificos de Linux. (Defina la macro
_GNU_SOURCE antes de incluir <fcntl.h> para obtener estas
definiciones.) Las banderas legales para F_GETFL/F_SETFL son aquellas
que acepta open(2) y varian entre estos sistemas; O_APPEND, O_NONBLOCK,
O_RDONLY y O_RDWR son las que se mencionan en POSIX.1. SVr4 admite
algunas otras opciones y banderas no documentadas aqui.
SVr4 documenta las condiciones de error adicionales EIO, ENOLINK y
EOVERFLOW.
V'EASE TAMBI'EN
dup2(2), flock(2), lockf(3), open(2), socket(2)
Vea tambien locks.txt, mandatory.txt y dnotify.txt en
/usr/src/linux/Documentation.