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