Provided by: manpages-de-dev_0.5-4.1ubuntu1_all bug

BEZEICHNUNG

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

Ü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).