Provided by: manpages-es_1.55-10_all bug

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ÓN

       fcntl  realiza  una de las diversas y variadas operaciones que se pueden hacer sobre fd.  La operación en
       cuestión se determina mediante cmd.

   Tratamiento de la bandera «cerrar al ejecutar»
       F_DUPFD
              Busca el descriptor de fichero disponible de menor número, 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 posición de ficheros y opciones o banderas (``flags'');  por  ejemplo,
              si  la  posición  del fichero se modifica usando lseek en uno de los descriptores, la posición del
              otro resulta modificada simultáneamente.

              Sin embargo, los dos descriptores no comparten la bandera close-on-exec («cerrar al ejecutar»). La
              bandera close-on-exec de la copia está  desactivada,  lo  que  significa  que  no  se  cerrará  al
              ejecutar.

              En caso de éxito, se devuelve el nuevo descriptor.

       F_GETFD
              Lee  la  bandera  close-on-exec.   Si  el bit FD_CLOEXEC es 0, el fichero permanecerá abierto tras
              exec, en caso contrario se cerrará el fichero.

       F_SETFD
              Establece la bandera close-on-exec al valor especificado por el bit FD_CLOEXEC de arg.

   Banderas de situación 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 semántica están 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
              situación  de  un  fichero  al  valor  especificado  por arg.  Los restantes bits (modo de acceso,
              banderas de creación de un fichero) de arg se ignoran.  En Linux, esta orden  sólo  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 (también 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;  /* Cómo interpretar l_start:
                                 SEEK_SET, SEEK_CUR, SEEK_END */
             off_t l_start;   /* Dirección de inicio del bloqueo */
             off_t l_len;     /* Número de bytes a bloquear */
             pid_t l_pid;     /* PID del proceso que bloquea nuestro candado
                                 (sólo 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  dirección  inicial para el bloqueo y se interpreta relativa a: el inicio del
       fichero (si l_whence es SEEK_SET); la posición actual dentro del fichero (si l_whence es SEEK_CUR)  o  el
       fin  del  fichero  (si  l_whence  es  SEEK_END).   En  los dos últimos casos, l_start puede ser un número
       negativo siempre que la dirección inicial final no quede antes del principio del fichero.   l_len  es  un
       entero  no  negativo (aunque vea NOTAS más abajo) que indica el número de bytes a bloquear. Los bytes que
       se encuentren más allá 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 posición indicada por l_whence y l_start hasta el  final  del  fichero,  sin  importar
       cuánto 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 región de
       fichero, pero sólo un proceso puede tener  un  bloqueo  de  escritura  (bloqueo  exclusivo).  Un  bloqueo
       exclusivo  excluye  a  todos los demás bloqueos, tanto compartidos como exclusivos. Un único proceso sólo
       puede tener un tipo de bloqueo sobre una región de fichero; si se aplica un nuevo bloqueo a una región 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 código 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  señal  mientras  se  está
              esperando, se interrumpe la llamada y (tras terminar el manejador de señal) regresa inmediatamente
              (devolviendo -1 y asignado a errno el valor EINTR).

       F_GETLK
              Al  entrar  a esta llamada, lock describe un bloqueo que nos gustaría colocar en un fichero. Si el
              bloqueo se pudiera colocar, fcntl() realmente no lo colocará, pero devolverá F_UNLCK en  el  campo
              l_type  de  lock  y  dejará  los  otros campos de la estructura sin cambiar. Si uno o más bloqueos
              incompatibles impidieran que este bloqueo se colocara, entonces fcntl() devolverá  detalles  sobre
              uno  de  estos bloqueos en los campos l_type, l_whence, l_start y l_len de lock y asignará 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.

       Además de ser eliminados por un F_UNLCK explícito, los bloqueos de registros se  liberan  automáticamente
       cuando un proceso termina o cierra cualquier descriptor de fichero que haga referencia a un fichero sobre
       el  que  se  mantienen  los  bloqueos.  Esto está mal: significa que un proceso puede perder los bloqueos
       sobre un fichero como /etc/passwd o /etc/mtab cuando, por alguna razón, una función 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 través de
       execve(2).

       Debido al almacenamiento temporal que realiza stdio(3), se debería 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  omisión. Para usar bloqueos obligatorios, se debe habilitar dicho tipo de bloqueo en el
       sistema de ficheros que contiene el fichero a bloquear (usando la opción "-o mand" en mount(8)) y  en  el
       propio  fichero  (deshabilitando  el permiso de ejecución para el grupo y activado el bit de permiso set-
       GID).

       Los bloqueos consultivos no son de obligado cumplimiento y sólo son útiles entre procesos  que  cooperan.
       Los bloqueos obligatorios son respetados por todos los procesos.

   Manejo de señales
       F_GETOWN, F_SETOWN, F_GETSIG y F_SETSIG se utilizan para gestionar las señales de disponibilidad de E/S:

       F_GETOWN
              Obtiene  el ID de proceso o el grupo de procesos que actualmente recibe las señales 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 recibirá las señales 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 señal 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 enviará una señal  SIGIO
              cuando sea posible la entrada o la salida sobre ese descriptor de fichero.

              El  proceso  o  el  grupo  de  procesos que recibirá la señal se puede seleccionar usando la orden
              F_SETOWN de la función fcntl.  Si el descriptor de  fichero  es  un  conector  (``socket''),  esto
              también seleccionará al recipiente de las señales SIGURG que se entregan cuando llegan datos fuera
              de  orden  (``out-of-band'',  OOB) sobre el enchufe. (SIGURG se envía en cualquier situación en la
              que select(2) informaría que el conector tiene una "condición excepcional"). Si el  descriptor  de
              fichero corresponde a un dispositivo de terminal, entonces las señales SIGIO se envían al grupo de
              procesos en primer plano de la terminal.

       F_GETSIG
              Obtiene  la  señal enviada cuando la entrada o la salida son posibles. Un valor cero significa que
              se envía SIGIO. Cualquier otro valor (incluyendo SIGIO) es la señal enviada en su lugar y en  este
              caso  se  dispone  de  información  adicional  para  el  manejador de señal si éste se instala con
              SA_SIGINFO.

       F_SETSIG
              Establece la señal enviada cuando la entrada o la salida son posibles.  Un  valor  cero  significa
              enviar la señal por defecto SIGIO. Cualquier otro valor (incluyendo SIGIO) es la señal a enviar en
              su  lugar  y en este caso se dispone de información adiciona para el manejador de señal si éste se
              instala con SA_SIGINFO.

              Usando F_SETSIF con un valor distinto de cero y asignando SA_SIGINFO para el  manejador  de  señal
              (vea  sigaction(2)),  se  pasa  información  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 qué
              descriptores de ficheros hay pendientes y, para  determinar  qué  descriptores  de  fichero  están
              disponibles  para  E/S,  debería  usar  los  mecanismos  usuales  (select(2), poll(2), read(2) con
              O_NONBLOCK activo, etc.).

              Seleccionando una señal de tiempo real POSIX.1b (valor >=  SIGRTMIN),  se  pueden  encolar  varios
              eventos  de  E/S  usando  los  mismos  números  de  señal.  (El encolamiento depende de la memoria
              disponible). Se dispone de información extra si se asigna SA_SIGINFO al manejador de  señal,  como
              antes.

       Usando  estos  mecanismos,  un programa puede implementar E/S totalmente asíncrona, sin usar select(2) ni
       poll(2) la mayor parte del tiempo.

       El uso de O_ASYNC, F_GETOWN y F_SETOWN es específico de Linux y BSD.  F_GETSIG y F_SETSIG son específicos
       de Linux. POSIX posee E/S asíncrona y la estructura aio_sigevent para conseguir  cosas  similares;  éstas
       también están 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
       configuración 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 envío de una señal) cuándo otro proceso (el
       "competidor") intenta abrir (open(2)) o truncar (truncate(2)) ese fichero.

       F_SETLEASE
              Establece o elimina un arrendamiento de fichero según qué valor de los siguientes  se  especifique
              en el entero arg:

              F_RDLCK
                     Obtiene  un arrendamiento de lectura. Esto hará que se nos informe cuando otro proceso abra
                     el fichero para escribir en él o cuando lo trunque.

              F_WRLCK
                     Obtiene un arrendamiento de escritura. Esto hará que se nos  informe  cuando  otro  proceso
                     abra el fichero (para leer o escribir) o lo trunque. Sólo se puede colocar un arrendamiento
                     de escritura en un fichero cuando ningún otro proceso lo tenga abierto en ese momento.

              F_UNLCK
                     Elimina nuestro arrendamiento del fichero.

       Un proceso sólo puede tener un tipo de arrendamiento sobre un fichero.

       Los  arrendamientos  sólo se pueden obtener para ficheros regulares. Un proceso normal sólo puede obtener
       un arrendamiento sobre un fichero cuyo UID coincida con el UID de sistema de ficheros del proceso.

       F_GETLEASE
              Indica qué 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 núcleo bloquea la llamada al sistema (a menos que se  especifique  la
       opción  O_NONBLOCK  en  open(), en cuyo caso la llamada regresa inmediatamente con el error EWOULDBLOCK).
       El núcleo entonces notifica al arrendatario enviándole una señal (SIGIO por  omisión).   El  arrendatario
       debe  responder  a la recepción de esta señal haciendo cualquier limpieza que sea necesaria para preparar
       el fichero para que sea accedido por otro proceso (por ejemplo, vaciando los buffers en caché) 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  número  de  segundos   especificado   en
       /proc/sys/fs/lease-break-time  y  la  llamada  al  sistema  del  competidor sigue bloqueada (es decir, el
       competidor no especificó O_NONBLOCK en su llamada open() y la llamada al sistema no ha sido  interrumpida
       por un manejador de señal), entonces el núcleo 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 núcleo permite continuar a la llamada al  sistema
       del competidor.

       La  señal  por omisión 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 señal se establece usando SA_SIGINFO, el manejador recibirá una estructura siginfo_t como su
       segundo argumento y el campo si_fd de este argumento contendrá el descriptor del fichero arrendado que ha
       sido accedido por otro proceso. (Esto es útil si el invocador tiene arrendamientos para varios ficheros).

   Notificación de cambios en ficheros y directorios
       F_NOTIFY
              (Linux 2.4 y posteriores) Produce una notificación 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
              máscara de bits que se especifica mediante un O-lógico de cero o más de los siguientes bits:

              Bit         Descripción (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 única vez (son de tipo ``one-shot'') y
              la aplicación debe volver a hacer  el  registro  para  recibir  notificaciones  adicionales.  Otra
              posibilidad es incluir DN_MULTISHOT en arg, en cuyo caso la notificación se producirá hasta que se
              elimine  explícitamente.   Una  serie de llamadas que especifican DN_MULTISHOT es acumulativa, con
              los eventos en arg añadiéndose al conjunto ya monitorizado.  Para desactivar  la  notificación  de
              todos los eventos, haga una llamada F_NOTIFY especificando 0 en arg.

              La  notificación se produce mediante el envío de una señal. La señal por omisión es SIGIO, pero se
              puede cambiar usando la orden F_SETSIG de fcntl().  En el segundo  caso,  el  manejador  de  señal
              recibe  una  estructura  siginfo_t como su segundo argumento (si el manejador se estableció usando
              SA_SIGINFO) y el campo si_fd de esta estructura contiene el descriptor de fichero que  produjo  la
              notificación (útil cuando se establecen notificaciones en varios directorios).

              Especialmente  cuando  se usa DN_MULTISHOT, se debería usar una señal POSIX.1b de tiempo real para
              notificación, de tal manera que se pueden encolar multiples notificaciones.

VALOR DEVUELTO

       Para una llamada con éxito, el valor devuelto depende de la operación:

       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 señal 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 operación debido a bloqueos mantenidos por otros procesos.  O se ha prohibido
              la operación porque el fichero ha sido proyectado (``mapped'') en memoria por otro proceso.

       EDEADLK
              Se ha detectado que la orden F_SETLKW especificada provocaría un interbloqueo.

       EFAULT lock está 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 señal.  Para F_GETLK y F_SETLK, la orden ha
              sido interrumpida por una señal antes de que el bloqueo  se  haya  comprobado  o  adquirido.  Esto
              ocurre  con  más  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 máximo permitido. Para F_SETSIG, arg no  es  un
              número de señal permitido.

       EMFILE Para F_DUPFD, el proceso ya ha llegado al número máximo de descriptores de ficheros abiertos.

       ENOLCK Demasiados  bloqueos  de  segmentos  abiertos,  la  tabla  de  bloqueos está 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 ``sólo
              añadir'' (append-only).

OBSERVACIONES

       Los errores devueltos por dup2 son distintos de aquéllos dados por F_DUPFD.

       Desde el núcleo 2.0, no hay interacción 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  núcleos  actuales,  la
       llamada al sistema de Linux devuelve EINVAL en esta situación.

       Otros  sistemas  tienen más campos en struct flock como, por ejemplo, l_sysid.  Evidentemente, l_pid sólo
       no va a ser muy útil si el proceso que posee el bloqueo puede residir en una máquina diferente.

CONFORME A

       SVID, AT&T, POSIX, X/OPEN, BSD 4.3. Sólo 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 específicos de Linux.  F_NOTIFY, F_GETLEASE y F_SETLEASE son específicos 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  aquéllas que acepta open(2) y varían 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 aquí.

       SVr4 documenta las condiciones de error adicionales EIO, ENOLINK y EOVERFLOW.

VÉASE TAMBIÉN

       dup2(2), flock(2), lockf(3), open(2), socket(2)

       Vea también locks.txt, mandatory.txt y dnotify.txt en /usr/src/linux/Documentation.

Linux-2.5.18                                       24-04-2002                                           FCNTL(2)