Provided by: manpages-de-dev_0.10-1_all bug

BEZEICHNUNG

       select,  pselect,  FD_CLR,  FD_ISSET,  FD_SET, FD_ZERO - Synchrone I/O-
       Multiplexsteuerung

       Diese Handbuchseite ist eventuell veraltet. Im Zweifelsfall ziehen  Sie
       die englischsprachige Handbuchseite zu Rate, indem Sie

              man -LC 2 select

       eingeben.

ÜBERSICHT

       #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, 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);

BESCHREIBUNG

       Die  Funktionen  select und pselect überwachen den Dateistatus für eine
       Reihe von Datei-Deskriptoren.

       Die Funktionsweise der beiden Varianten ist  identisch,  abgesehen  von
       drei Unterschieden:

       (i)    The  select-Funktion  verwendet  zur  Angabe von Zeitlimits eine
              Struktur   vom   Typ   struct   timeval   (mit   Sekunden    und
              Mikrosekunden),  pselect  hingegen  den Typ struct timespec (mit
              Sekunden   und   Nanosekunden).   Die   Strukturen   sind   über
              /usr/include/sys/time.h definiert als:

              struct timeval {
                      long    tv_sec;         /* Sekunden */
                      long    tv_usec;        /* Mikrosekunden */
              };

              und

              struct timespec {
                      long    tv_sec;         /* Sekunden */
                      long    tv_nsec;        /* Nanosekunden */
              };

       (ii)   Während  select  den  Parameter  timeout  mitunter verändert, um
              anzuzeigen, wie viel Zeit des Limits noch verblieben ist,  lässt
              pselect den Wert immer unverändert.

       (iii)  Die select-Funktion besitzt keinen sigmask-Parameter und verhält
              sich wie pselect, das mit  einer  sigmask  von  NULL  aufgerufen
              wurde.

       Es   werden   drei  voneinander  unabhängige  Mengen  von  Deskriptoren
       behandelt. Bei den in readfds enthaltenen wird darauf geachtet, ob neue
       Zeichen  zum  Lesen  ankommen.  (Genauer,  es wird kontrolliert, ob ein
       nachfolgender  read-Systemaufruf  sofort  zurückkehren   würde.   Diese
       Bedingung  ist  insbesondere auch dann erfüllt, wenn der Deskriptor auf
       das Dateiende verweist.) Bei den in writefds  angegebenen  Deskriptoren
       wird  reagiert, wenn weitere Zeichen geschrieben werden können, und bei
       den in exceptfds angegebenen Deskriptoren, wenn etwas außergewöhnliches
       passiert  ist.  Kehrt  der  Systemaufruf  zurück,  sind die übergebenen
       Mengen so verändert,  dass  sie  anzeigen,  welcher  Deskriptor  seinen
       Status geändert hat.

       Vier  Makros  stehen  bereit, um mit diesen Mengen zu arbeiten. FD_ZERO
       löscht eine Menge, FD_SET und FD_CLR fügen einen Deskriptor  zur  Menge
       hinzu  bzw.  löschen  diesen,  FD_ISSET prüft, ob der Deskriptor in der
       Menge enthalten ist. Das  ist  insbesondere  nach  einem  select-  oder
       pselect-Aufruf sinnvoll.

       n entspricht der Zahl des am höchsten nummerierten Datei-Deskriptors in
       allen drei Mengen, plus 1.

       timeout  gibt  ein  Zeitlimit  an,  das  select  und  pselect   maximal
       verstreichen lassen, bevor sie zurückkehren. Ist das Zeitlimit null, so
       kehren die Funktionen sofort zurück. Besitzt timeout  selbst  den  Wert
       NULL,  so  wird kein Limit gesetzt, und die Funktionen können unendlich
       lange blockieren.

       sigmask ist entweder NULL oder ein Zeiger auf eine Signalmaske  wie  in
       sigprocmask(2)   beschrieben.  Im  zweiten  Fall  ersetzt  pselect  die
       aktuelle Signalmaske durch sigmask, führt dann  den  select-Aufruf  aus
       und stellt anschließend die ursprüngliche Maske wieder her.

       Die  Idee  hinter  pselect  geht  zurück  auf  folgende  Situation: Ein
       Programm wartet gleichzeitig auf ein Signal oder  eine  Veränderung  an
       einem   Datei-Deskriptor.   Trifft   das   Signal  ein,  so  setzt  der
       Signalhandler eine globale Variable.  Im  Hauptprogramm  wird  zunächst
       getestet, ob die Variable gesetzt ist und andernfalls ein select-Aufruf
       gestartet. Trifft das Signal zwischen dem Test  und  dem  select-Aufruf
       ein,  so  kann  das  dazu  führen, dass das Programm nicht mehr beendet
       wird. pselect hingegen erlaubt es, diese so genannte Race Condition  zu
       umgehen,   indem  das  Signal  zunächst  geblockt,  getestet  und  erst
       unmittelbar mit dem  select-Aufruf  wieder  freigegeben  wird.  Da  der
       Linux-Kernel  bislang  keinen  speziellen  pselect-Systemaufruf  bereit
       stellt, muss die aktuelle glibc2 ihn durch mehrere  Aufrufe  emulieren.
       Die Fehlerquelle ist daher auch mit pselect nach wie vor vorhanden.

RÜCKGABEWERTE

       Bei Erfolg geben select und pselect die Anzahl der Deskriptoren zurück,
       deren Status sich geändert hat. Der Rückgabewert kann auch  null  sein,
       wenn  das  Zeitlimit erreicht wurde, bevor etwas interessantes passiert
       ist. Wenn ein Fehler aufgetreten ist, wird -1 zurückgegeben  und  errno
       entsprechend  gesetzt.  Die  Mengen  und  timeout befinden sich dann in
       einem undefinierten Zustand. Auf ihren Inhalt sollte man sich  folglich
       bei einem Fehler nicht mehr verlassen.

FEHLER

       EBADF   In  einer  der  Mengen  wurde  ein  ungültiger Datei-Deskriptor
               angegeben.

       EINTR   Ein nicht-blockiertes Signal wurde empfangen.

       EINVAL  n ist negativ.

       ENOMEM  select war  nicht  in  der  Lage,  Speicher  für  die  internen
               Tabellen zu bekommen.

ANMERKUNGEN

       Einige Programme rufen select mit drei leeren Mengen, n gleich null und
       einem von null verschiedenen timeout auf, um eine portable  Möglichkeit
       zu  haben, ein sleep mit der Präzision von Bruchteilen einer Sekunde zu
       benutzen.

       Bei Linux wird  timeout  derart  verändert,  dass  es  dem  noch  nicht
       verstrichenen    Teil    des   Zeitlimits   entspricht.   Die   meisten
       Implementierungen anderer Betriebssysteme unterlassen dies. Das  bringt
       Probleme  mit  sich,  wenn  unter  Linux  geschriebener  Quellcode, der
       timeout auswertet, auf andere Betriebssysteme portiert wird,  und  wenn
       Quellcode von anderen Betriebssystemen auf Linux portiert wird, der das
       struct timeval für mehrere selects in einer  Schleife  verwendet,  ohne
       ihn  jedesmal  neu  zu  initialisieren.  Portabler  Code  sollte  daher
       annehmen, dass timeout undefiniert ist, nachdem select beendet wurde.

       Wenn der einzige  Schreiber  eine  Named-Pipe  geschlossen  hat,  kehrt
       select  zurück und signalisiert, dass etwas von der Pipe gelesen werden
       kann. Ein anschließender read-Aufruf liefert jedoch null zurück, da das
       Dateiende  erreicht  ist. Code, der annimmt, dass select in diesem Fall
       blockiert, sollte die Pipe mit O_RDWR statt O_RDONLY öffnen.

BEISPIEL

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

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

           /* Achte auf stdin (fd 0), um zu sehen, wenn es
            * Eingaben gibt.
            */
           FD_ZERO(&rfds);
           FD_SET(0, &rfds);
           /* Warte bis zu fünf Sekunden. */
           tv.tv_sec = 5;
           tv.tv_usec = 0;

           retval = select(1, &rfds, NULL, NULL, &tv);
           /* Verlaß Dich jetzt bloß nicht auf den Wert von tv! */

           if (retval)
               printf("Daten sind jetzt da.\n");
               /* FD_ISSET(0, &rfds) müsste jetzt true sein. */
           else
               printf("Keine Dateien innerhalb von fünf Sekunden.\n");

           exit(0);
       }

KONFORM ZU

       4.4BSD. (Die  select-Funktion  trat  das  erste  Mal  in  4.2BSD  auf.)
       Gewöhnlich  auch  portierbar  auf Nicht-BSD-Systeme (System V-Varianten
       eingeschlossen), die eine Schnittstelle vom  Typ  des  BSD-Socketlayers
       unterstützen.  Zu  beachten  ist  jedoch,  dass  die System V-Varianten
       typischerweise die timeout-Variable vor der Rückkehr  setzen.  Bei  den
       BSD-Varianten ist das nicht üblich.

       Die pselect-Funktion ist in IEEE Std 1003.1g-2000 (POSIX.1g) definiert.
       Sie  ist  seit  glibc2.1  implementiert.  Auch  glibc2.0  besitzt  eine
       Funktion dieses Namens, die jedoch keinen Parameter sigmask verwendet.

SIEHE AUCH

       accept(2),    connect(2),    poll(2),    read(2),   recv(2),   send(2),
       sigprocmask(2), write(2).