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.