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

NOMBRE

       select, pselect, FD_CLR, FD_ISSET, FD_SET, FD_ZERO - multiplexación de E/S síncrona

SINOPSIS

       /* Según POSIX 1003.1-2001 */
       #include <sys/select.h>

       /* Según estándares anteriores */
       #include <sys/time.h>
       #include <sys/types.h>
       #include <unistd.h>

       int  select(int  n,  fd_set  *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval
       *timeout);

       int pselect(int n, fd_set *readfds, fd_set  *writefds,  fd_set  *exceptfds,  const  struct
       timespec *timeout, const sigset_t *sigmask);

       FD_CLR(int fd, fd_set *set);
       FD_ISSET(int fd, fd_set *set);
       FD_SET(int fd, fd_set *set);
       FD_ZERO(fd_set *set);

DESCRIPCIÓN

       Las  funciones select y pselect esperan a que un número de descriptores de fichero cambien
       de estado.

       Su función es idéntica, con tres diferencias:

       (i)    La función select usa un plazo de espera (timeout)  que es de tipo  struct  timeval
              (con  segundos  y microsegundos), mientras pselect usa el tipo struct timespec (con
              segundos y nanosegundos).

       (ii)   La función select puede actualizar el parámetro  timeout  para  indicar  el  tiempo
              sobrante. La función pselect no modifica este parámetro.

       (iii)  La  función  select no tiene parámetro sigmask , y se comporta como pselect llamada
              con el argumento sigmask a NULL.

       Se miran tres conjuntos independientes de descriptores. Aquéllos listados en readfds serán
       observados  para  ver  si  hay caracteres que llegan a estar disponibles para lectura (más
       concretamente,  para ver si una operación de lectura no se bloqueará - en  particular,  un
       descriptor  de  fichero  está  también  preparado en fin-de-fichero), aquéllos en writefds
       serán observados para ver si una operación de escritura no se  bloqueará,  y  aquéllos  en
       exceptfds  serán  observados  para  ver  si  ocurren  excepciones.  En  caso de éxito, los
       conjuntos se modifican en marcha para indicar  qué  descriptores  cambiaron  realmente  su
       estado.

       Se proporcionan cuatro macros para manipular los conjuntos.  FD_ZERO limpiará un conjunto.
       FD_SET y FD_CLR añaden o borran un descriptor dado a o de un conjunto.   FD_ISSET  mira  a
       ver si un descriptor es parte del conjunto; esto es útil después de que select regrese.

       n es el descriptor con el número más alto en cualquiera de los tres conjuntos, más 1.

       timeout  es  un  límite superior de la cantidad de tiempo transcurrida antes de que select
       regrese. Puede ser cero, causando que select regrese inmediatamente. Si  timeout  es  NULL
       (no hay tiempo de espera), select puede bloquear indefinidamente.

       sigmask  es  un  puntero  a una máscara de señales (vea sigprocmask(2)); si es distinto de
       NULL, pselect reemplaza en primer lugar la máscara de señales actual por aquella a la  que
       apunta  sigmask,  luego  hace  la funcion `select',  y por último restablece la máscara de
       señales original de nuevo.

       La idea de pselect es que si alguien quiere esperar un evento, bien una señal o  cualquier
       otra cosa sobre un descriptor de fichero, se necesita una comprobación atómica para evitar
       condiciones de carrera.  (Suponga que el manejador de señales fija  una  opción  global  y
       regresa.  Después una comprobación de esta opción seguida de una llamada a select() podría
       colgarse indefinidamente si la señal llegó justo después de  la  comprobación  pero  justo
       antes  de la llamada. Por otra parte, pselect le permite bloquear señales en primer lugar,
       manejar las señales que hayan llegado,  y  después  llamar  a  pselect()  con  la  máscara
       sigmask  deseada, evitando la condición de carrera.)  Puesto que en la actualidad Linux no
       cuenta con una llamada al sistema pselect() , la rutina actual  de  glibc2  todavía  tiene
       este defecto.

   El plazo de espera o timeout
       Las  estructuras  de  tiempo  involucradas  están  definidas  en  <sys/time.h> y tienen el
       siguiente aspecto

              struct timeval {
                  long    tv_sec;         /* segundos */
                  long    tv_usec;        /* microsegundos */
              };

       and

              struct timespec {
                  long    tv_sec;         /* segundo */
                  long    tv_nsec;        /* nanosegundos */
              };

       (Sin embargo,  lea más abajo sobre las versiones de POSIX 1003.1-2001.)

       Hay algún código por ahí que llama a select con los tres conjuntos vacíos, n  cero,  y  un
       timeout  distinto  de  cero  como  una  forma  transportable  y  curiosa de dormir con una
       precisión por debajo del segundo.

       En Linux, timeout se modifica para reflejar la cantidad de tiempo no dormido;  la  mayoría
       de  otras implementaciones no hacen esto. Esto produce problemas cuando el código de Linux
       que lee timeout se transporta a otros sistemas operativos, y cuando se transporta a  Linux
       código   que   reutiliza   una  struct  timeval  para  varias  selects  en  un  bucle  sin
       reinicializarla. Considere que timeout está indefinido después de que select regrese.

VALOR DEVUELTO

       En caso de éxito, select y pselect devuelven el número de descriptores contenidos  en  los
       conjuntos  de  descriptores, que puede ser cero si el tiempo de espera expira antes de que
       ocurra algo interesante.  En caso de error, se devuelve -1, y se pone un  valor  apropiado
       en errno; los conjuntos y timeout estarán indefinidos, así que no confíe en sus contenidos
       tras un error.

ERRORES

       EBADF  Se ha dado un descriptor de fichero inválido en uno de los conjuntos.

       EINTR  Se ha capturado una señal no bloqueante.

       EINVAL n es negativo o el valor contenido en timeout no es válido.

       ENOMEM select no ha sido capaz de reservar memoria para las tablas internas.

EJEMPLO

       #include <stdio.h>
       #include <sys/time.h>
       #include <sys/types.h>
       #include <unistd.h>

       int
       main(void) {
           fd_set rfds;
           struct timeval tv;
           int valret;

           /* Mirar stdin (df 0) para ver si tiene entrada */
           FD_ZERO(&rfds);
           FD_SET(0, &rfds);
           /* Esperar hasta 5 s */
           tv.tv_sec = 5;
           tv.tv_usec = 0;

           valret = select(1, &rfds, NULL, NULL, &tv);
           /* ¡No confiar ahora en el valor de tv! */

           if (valret)
               printf("Los datos ya están disponibles.\n");
               /* FD_ISSET(0, &rfds) será verdadero */
           else
               printf("Ningún dato en 5 segundos.\n");

           return 0;
       }

CONFORME A

       4.4BSD  (la  función  select  apareció  por  primera  vez  en  4.2BSD).  Generalmente   es
       transportable  a  o  desde sistemas no-BSD que admitan clones de la capa de zócalos de BSD
       (incluyendo variantes System V). Sin embargo, observe que la variante System V normalmente
       pone la variable de espera antes de salir, pero la variante BSD no.

       La  función  pselect  está  definida en IEEE Std 1003.1g-2000 (POSIX.1g), y parte de POSIX
       1003.1-2001.  Se encuentra en glibc2.1 y posteriores.  Glibc2.0 posee una función con este
       nombre, que sin embargo no acepta un parámetro sigmask.

OBSERVACIONES

       fd_set  es  un  buffer de tamaño fijo. Ejecutar FD_CLR o FD_SET con un valor de fd que sea
       negativo o igual o mayor que FD_SETSIZE  tendrá  un  comportamiento  indefinido.   Además,
       POSIX requiere que fd sea un descriptor de fichero válido.

       En  lo  que  se refiere a los tipos involucrados, lo habitual es que los dos campos de una
       estructura timeval sean de tipo long  (como  se  muestra  abajo),  y  la  estructura  esté
       definida en <sys/time.h>.  La postura de POSIX 1003.1-2001 es

              struct timeval {
                  time_t         tv_sec;     /* segundos */
                  suseconds_t    tv_usec;    /* microsegundos */
              };

       donde  la  estructura  está  definida  en  <sys/select.h>  y  los  tipos de datos time_t y
       suseconds_t están definidos en <sys/types.h>.

       En lo que se refiere a prototipos, lo habitual es incluir el fichero de cabecera  <time.h>
       para  select.   La  postura de POSIX 1003.1-2001 es incluir el fichero <sys/select.h> para
       select y pselect.  Libc4 y libc5 no poseen una cabecera <sys/select.h> ; bajo glibc 2.0  y
       posteriores  esta  cabecera sí existe.  Bajo glibc 2.0, proporciona incondicionalemente el
       prototipo incorrecto  para  pselect,  bajo  glibc  2.1-2.2.1  proporciona  pselect  cuando
       _GNU_SOURCE está definido, bajo glibc 2.2.2-2.2.4 lo proporciona cuando _XOPEN_SOURCE está
       definido y tiene un valor de 600 o mayor.  Sin duda, desde POSIX 1003.1-2001, debería  dar
       el prototipo por defecto.

VÉASE TAMBIÉN

       Para un tutorial detallado con ejemplos, vea select_tut(2).

       Para  una mera descripción, vea accept(2), connect(2), poll(2), read(2), recv(2), send(2),
       sigprocmask(2), write(2)