Provided by: manpages-de-dev_2.16-1_all bug

BEZEICHNUNG

       select, pselect, FD_CLR, FD_ISSET, FD_SET, FD_ZERO - synchrones E/A-Zeitmultiplexverfahren

ÜBERSICHT

       /* Laut POSIX.1-2001, POSIX.1-2008 */
       #include <sys/select.h>

       /* Laut älterer Standards */
       #include <sys/time.h>
       #include <sys/types.h>
       #include <unistd.h>

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

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

       #include <sys/select.h>

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

   Mit Glibc erforderliche Makros (siehe feature_test_macros(7)):

       pselect(): _POSIX_C_SOURCE >= 200112L

BESCHREIBUNG

       Mit  den  Funktionen  select()  und  pselect() kann ein Programm mehrere Dateideskriptoren
       überwachen und warten, bis ein oder mehrere der Dateideskriptoren »bereit« für eine Klasse
       von  E/A-Aktionen  sind (z. B. Eingabe möglich). Ein Dateideskriptor gilt als bereit, wenn
       es möglich ist, eine entsprechende  E/A-Aktionen  (z.B.  read  (2)  oder  ein  hinreichend
       kleines write(2) ohne zu blockieren) durchzuführen.

       select()  kann  nur  Dateideskriptorennummern überwachen, die kleiner als FD_SETSIZE sind;
       poll(2) hat diese Einschränkung nicht. Siehe FEHLER.

       Das Verhalten  von  select()  und  pselect()  ist  bis  die  folgenden  drei  Unterschiede
       identisch:

       (i)    select()   verwendet   für   Wartezeiten  ein  struct  timeval  (mit  Sekunden  und
              Mikrosekunden), während pselect() stattdessen ein struct timespec (mit Sekunden und
              Nanosekunden) verwendet.

       (ii)   Während  select()  das  Argument  timeout  ändern  darf,  um  die verbleibende Zeit
              anzugeben, verändert pselect() dieses Argument nicht.

       (iii)  Die Funktion select() hat keinen Parameter sigmask und verhält  sich  wie  pselect,
              wenn ihr für sigmask ein NULL-Zeiger übergeben wird.

       Es  werden  drei voneinander unabhängige Mengen von Deskriptoren überwacht. Die in readfds
       aufgeführten Deskriptoren werden daraufhin beobachtet, ob neue Zeichen zum Lesen  ankommen
       (genauer: ob eine Leseaktion nicht blockiert; insbesondere ist ein Dateideskriptor auch am
       Dateiende (EOF) bereit). Die Datei-Deskriptoren in writefds werden  daraufhin  beobachtet,
       ob  Platz  zum  Schreiben  verfügbar  ist  (ein  größerer  Schreibaufruf kann aber dennoch
       blockieren)  und  die  Datei-Deskriptoren  in  exceptfds   werden   auf   außergewöhnliche
       Bedingungen  überwacht. (Lesen Sie die Diskussion von POLLPRI in poll(2) für Beispiele für
       außergewöhnliche Bedingungen.)

       Wenn die Funktion beendet wird, wird jede der Datei-Deskriptorenmengen so verändert,  dass
       sie  anzeigen,  welcher  Deskriptor  seinen Status geändert hat. (Falls Sie daher select()
       innerhalb einer Schleife verwenden, müssen die Mengen vor jedem Aufruf  neu  initialisiert
       werden.)

       Jeder  der  drei  Mengen  von  Deskriptoren  kann als NULL angegeben werden, falls für die
       entsprechenden Dateideskriptoren keine Klassen oder Ereignisse überwacht werden müssen.

       Es werden vier Makros bereitgestellt, um mit diesen Mengen zu arbeiten.  FD_ZERO()  löscht
       eine  Menge,  FD_SET()  fügt  einen  Deskriptor  zu  einer Menge hinzu und FD_CLR() löscht
       diesen. FD_ISSET()  prüft,  ob  der  Deskriptor  in  der  Menge  enthalten  ist.  Das  ist
       insbesondere nach einem Aufruf von select() nützlich.

       nfds  sollte  auf  die  Nummer des am höchsten nummerierten Dateideskriptors in allen drei
       Mengen plus 1 gesetzt werden. Der gekennzeichnete Dateideskriptor in jeder der drei Mengen
       wird bis zu dieser Begrenzung geprüft (siehe aber FEHLER).

       Das  Argument  timeout  legt  das  Intervall  fest,  das  select()  warten sollte, bis ein
       Dateideskriptor bereit wird. Der Aufruf wird blockieren, bis entweder:

       *  ein Dateideskriptor bereit wird,

       *  der Aufruf durch einen Signal-Handler unterbrochen wird, oder

       *  die Wartezeit abläuft.

       Beachten Sie, das das Intervall timeout auf die Auflösung der Systemuhr aufgerundet  wird.
       Durch  Verzögerungen beim Kernel-Scheduling kann dieser Wert nochmals etwas größer werden.
       Falls beide Felder der Struktur timeval gleich null sind, kehrt  select()  sofort  zurück.
       (Das  ist  praktisch  für  Polling). Falls timeout gleich NULL ist (keine Wartezeit), kann
       select() auf unbestimmte Zeit blockieren.

       sigmask ist ein Zeiger auf eine Signalmaske (siehe sigprocmask(2)); falls er ungleich NULL
       ist,  ersetzt  pselect()  zuerst  die aktuelle Signalmaske mit derjenigen, auf die sigmask
       weist, erledigt danach die »select«-Funktion und  stellt  als  Letztes  die  ursprüngliche
       Signalmaske wieder her.

       Abgesehen   von   der   unterschiedlichen   Genauigkeit   des  timeout-Arguments  ist  der
       pselect()-Aufruf

           ready = pselect(nfds, &readfds, &writefds, &exceptfds,
                           timeout, &sigmask);

       ist äquivalent zur atomaren Ausführung der folgenden Aufrufe:

           sigset_t origmask;

           pthread_sigmask(SIG_SETMASK, &sigmask, &origmask);
           ready = select(nfds, &readfds, &writefds, &exceptfds, timeout);
           pthread_sigmask(SIG_SETMASK, &origmask, NULL);

       Falls man auf die Verfügbarkeit eines Signals oder eines Dateideskriptors  warten  möchte,
       ist  zur  Vermeidung  von  Wettlaufsituationen  (race  conditions)  eine  atomare  Prüfung
       erforderlich, die von pselect() erledigt wird. (Angenommen, der Signal Handler setzt einen
       globalen  Schalter  und  kehrt  zurück. Dann könnte eine Prüfung dieses globalen Schalters
       gefolgt von einem Aufruf von  select()  auf  unbestimmte  Zeit  hängen,  wenn  das  Signal
       zwischen  der  Prüfung  und  vor  dem  Aufruf  von  select()  eintrifft. Im Gegensatz dazu
       ermöglicht  es  pselect()  zuerst  Signale  zu  blockieren,  die  eingetroffenen   Signale
       abzuarbeiten  und  anschließend  pselect() mit der gewünschten sigmask aufzurufen, um Race
       Conditions zu vermeiden.)

   Die Wartezeit (timeout)
       Die Zeitstrukturen sind in <sys/time.h> als

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

       und

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

       definiert. (Sehen Sie sich aber weiter unten die Besonderheiten der POSIX.1-Versionen an.)

       Es gibt Code, der select wie folgt aufruft: alle drei Deskriptor-Mengen leer, nfds  gleich
       null  und  ein  von NULL verschiedenes timeout als recht portabler Weg, um mit Auflösungen
       unterhalb einer Sekunde zu schlafen.

       Unter  Linux  modifiziert  select()  timeout,  um  die  nicht  schlafend  verbrachte  Zeit
       anzuzeigen;  die meisten anderen Implementierungen tun das nicht. (POSIX.1 lässt beiderlei
       Verhalten zu.) Dies führt zu Problemen sowohl  bei  der  Portierung  von  Linux-Code,  der
       timeout liest, auf andere Betriebssysteme als auch bei der Portierung von Code nach Linux,
       der eine struct timeval in einer Schleife für mehrfache Aufrufe von select()  nutzt,  ohne
       sie  erneut  zu  initialisieren.  Gehen  Sie davon aus, dass timeout nach der Rückkehr aus
       select() nicht definiert ist.

RÜCKGABEWERT

       Bei Erfolg geben select() und pselect() die Anzahl  der  Datei-Deskriptoren  in  den  drei
       zurückgegebenen  Deskriptor-Mengen zurück. (Das entspricht der Gesamtzahl von Bits, die in
       readfds, writefds und exceptfds  gesetzt  sind.)  Der  Wert  kann  null  sein,  falls  die
       Wartezeit abläuft, ohne das irgendetwas von Bedeutung geschieht. Wenn ein Fehler auftritt,
       wird   -1   zurückgegeben   und   errno   gesetzt,   um   den   Fehler   anzugeben.    Die
       Datei-Deskriptor-Mengen bleiben unverändert und timeout wird undefiniert.

FEHLER

       EBADF  In einem der Mengen wurde ein ungültiger Dateideskriptor angegeben. (Vielleicht war
              es  ein  schon  geschlossener  Dateideskriptor  oder  einer,  bei  dem  ein  Fehler
              aufgetreten ist.) Lesen Sie aber auch FEHLER.

       EINTR  Ein Signal wurde abgefangen; siehe signal(7).

       EINVAL nfds  ist  negativ  oder  übersteigt  die Ressourcenbegrenzung RLIMIT_NOFILE (siehe
              getrlimit(2)).

       EINVAL Der Wert von timeout ist ungültig.

       ENOMEM Speicher für interne Tabellen konnte nicht bereitgestellt werden.

VERSIONEN

       pselect() wurde im Linux-Kernel 2.6.16 hinzugefügt. Vorher wurde pselect()  in  der  Glibc
       emuliert (siehe aber FEHLER).

KONFORM ZU

       select()  erfüllt  POSIX.1-2001,  POSIX.1-2008  und 4.4BSD (select() erschien erstmalig in
       4.2BSD). Im  Allgemeinen  von/nach  nicht  BSD-Systeme  portabel,  unterstützt  Klone  der
       BSD-Socket-Schicht  (einschließlich  System-V-Varianten).  Beachten  Sie  allerdings, dass
       System-V-Varianten typischerweise die Variable  »timeout«  vor  dem  Beenden  setzen,  die
       BSD-Variante aber nicht.

       pselect() ist in POSIX.1g und in POSIX.1-2001 und in POSIX.1-2008 definiert.

ANMERKUNGEN

       Ein fd_set ist ein Puffer fester Größe. Wird FD_CLR() oder FD_SET() mit einem Wert für fd,
       der negativ, gleich groß oder größer als FD_SETSIZE ist, ausgeführt, führt dies  zu  nicht
       definiertem  Verhalten.  Desweiteren  verlangt POSIX, dass fd ein gültiger Dateideskriptor
       ist.

       Das Verhalten von select() und pselect() ist von dem Schalter O_NONBLOCK nicht betroffen.

       Unter einigen UNIX-Systemen kann select() mit dem Fehler EAGAIN fehlschlagen, falls es dem
       System  nicht  gelingt,  Kernel-interne  Ressourcen  zuzuweisen.  Linux  verwendet hierbei
       ENOMEM. POSIX legt diesen Fehler für  poll(2)  aber  nicht  für  select()  fest.  Portable
       Anwendungen könnten in einer Schleife auf EAGAIN (wie auch auf EINTR) prüfen.

       Auf Systemen, auf denen pselect() fehlt, kann ein zuverlässiges (und portableres) Abfangen
       von Signalen mit dem Selbst-Pipe-Trick erreicht werden. Bei dieser  Technik  schreibt  ein
       Signal-Handler  ein  Byte  in eine Pipe, dessen anderes Ende von select() im Hauptprogramm
       überwacht wird. (Um mögliches Blockieren beim  Schreiben  in  eine  Pipe,  die  voll  sein
       könnte,  oder  Lesen  aus  einer  Pipe,  die  leer  sein  könnte, zu vermeiden, wird nicht
       blockierende E/A beim Auslesen und Schreiben in die Pipe verwandt.)

       Im Hinblick auf die beteiligten Typen ist die klassische Situation, dass zwei Felder einer
       Struktur  timeval  vom  Typ  long  (wie  gezeigt)  sind  und  die Struktur in <sys/time.h>
       definiert ist. Die POSIX.1-Situation ist

           struct timeval {
               time_t         tv_sec;     /* Sekunden */
               suseconds_t    tv_usec;    /* Mikrosekunden */
           };

       wobei die Struktur in <sys/select.h> definiert und die Datentypen time_t  und  suseconds_t
       in <sys/types.h> definiert sind.

       Im  Hinblick  auf  Prototypen  ist  die  klassische  Situation, dass <time.h> für select()
       eingebunden werden sollte. Die  Situation  unter  POSIX.1  ist,  dass  <sys/select.h>  für
       select() und pselect() eingebunden werden sollte.

       Unter  Glibc  2.0 gibt <sys/select.h> den falschen Prototyp für pselect(). Unter Glibc 2.1
       bis 2.2.1 gibt er pselect(), wenn _GNU_SOURCE definiert ist. Seit Glibc 2.2.2  gelten  die
       in ÜBERSICHT gezeigten Anforderungen.

   Korrespondenz zwischen den Benachrichtigungen select() und poll()
       Innerhalb   der   Linux-Kernelquellen   finden   wir  die  folgende  Definition,  die  die
       Korrespondenz    zwischen    den    lesbaren,    schreibbaren    und     außerordentlichen
       Zustandsbenachrichtigungen   von   select()   und   den   durch   poll(2)  (und  epoll(7))
       bereitgestellten Ereignisbenachrichtigungen zeigt:

           #define POLLIN_SET (POLLRDNORM | POLLRDBAND | POLLIN | POLLHUP |
                               POLLERR)
                              /* Bereit zum Lesen */
           #define POLLOUT_SET (POLLWRBAND | POLLWRNORM | POLLOUT | POLLERR)
                              /* Bereit zum Schreiben */
           #define POLLEX_SET (POLLPRI)
                              /* Außergewöhnliche Bedingung */

   Multithreaded Anwendungen
       Falls ein Dateideskriptor, der durch select() überwacht  wird,  in  einem  anderen  Thread
       geschlossen wird, ist das Ergebnis nicht spezifiziert. Auf einigen UNIX-Systemen entblockt
       select() und kehrt mit einer Information zurück, dass der Dateideskriptor bereit ist (eine
       nachfolgende  E/A-Aktion  wird  wahrscheinlich  mit  einem  Fehler fehlschlagen, außer ein
       anderer  Prozess  hat  den  Dateideskriptor  zwischen  dem  Zeitpunkt,  zu  dem   select()
       zurückkehrte,  und  dem  Zeitpunkt,  zu  der die E/A-Aktion stattfindet, wieder geöffnet).
       Unter Linux (und einigen anderen Systemen) hat das Schließen des Dateideskriptors in einem
       anderen Thread keinen Effekt auf select(). Zusammenfassend sollte jede Anwendung, die sich
       auf ein bestimmtes Verhalten  in  diesem  Szenario  abstützt,  als  fehlerhaft  betrachtet
       werden.

   Unterschiede C-Bibliothek/Kernel
       Der Linux-Kernel erlaubt Dateideskriptormengen beliebiger Größe und bestimmt die Größe der
       zu prüfenden Mengen durch den Wert von nfds. In  der  Glibc-Implementierung  ist  der  Typ
       fd_set allerdings von fester Größe. Siehe auch FEHLER.

       Die   in   dieser   Seite  beschriebene  Schnittstelle  von  pselect()  wird  durch  Glibc
       implementiert. Der darunterliegende Systemaufruf heißt pselect6(). Dieser Systemaufruf hat
       ein etwas anderes Verhalten als die Glibc-Wrapper-Funktion.

       Der   Systemaufruf   pselect6()   von   Linux   verändert   das   Argument   timeout.  Die
       Glibc-Wrapper-Funktion versteckt dieses Verhalten durch Verwendung einer lokalen Variablen
       für  das  Argument  »timeout«, die an den Systemaufruf übergeben wird. Daher verändert die
       Glibc-Funktion pselect() nicht  ihr  Argument  timeout;  dies  ist  das  von  POSIX.1-2001
       verlangte Verhalten.

       Das  finale Argument des Systemaufrufs pselect6() ist kein sigset_t *-Zeiger, sondern eine
       Struktur der folgenden Form:

           struct {
               const kernel_sigset_t *ss;  /* Zeiger auf Signalgruppe */
               size_t ss_len;              /* Größe (in Bytes) des Objekts,
                                              auf das durch »ss« gezeigt wird */
           };

       Dies erlaubt es dem Systemaufruf, sowohl einen Zeiger auf die Signalgruppe als auch  seine
       Größe  zu  ermitteln  und  dabei  zu  berücksichtigen, dass die meisten Architekturen eine
       maximale Anzahl von 6 Argumenten für einen Systemaufruf erlauben. Siehe sigprocmask(2) für
       eine Diskussion der Unterschiede zwischen der Ansicht des Kernels und der Ansicht der Libc
       bezüglich der Singalmenge.

FEHLER

       POSIX  erlaubt  einer  Implementierung,  eine  oberer  Begrenzung  für  den  Bereich   von
       Dateideskriptoren,  die  in  einer  Dateideskriptorenmenge  festgelegt  werden  können, zu
       definieren. Diese Begrenzung  soll  mittels  der  Konstanten  FD_SETSIZE  bekannt  gemacht
       werden.  Der  Linux-Kernel erzwingt keine feste Begrenzung, aber die Glibc-Implementierung
       macht fd_set zu einem Typ fester Größe, wobei FD_SETSIZE als 1024 definiert  ist  und  die
       Makros  FD_*()  arbeiten  entsprechend  dieser Begrenzung. Um Dateideskriptoren größer als
       1024 zu überwachen verwenden Sie stattdessen poll(2).

       Die Implementierung der Argumente fd_set als Wert-Ergebnis-Argumente  bedeutet,  dass  sie
       bei  jedem  Aufruf von select() neu initialisiert werden müssen. Dieser Design-Fehler wird
       von poll(2) vermieden, der getrennte Strukturfelder für die Ein- und Ausgabe  des  Aufrufs
       verwendet.

       Laut   POSIX   sollte   select()   alle   festgelegten   Dateideskriptoren   in  den  drei
       Dateideskriptorenmengen bis zur Grenze nfds-1 prüfen. Allerdings  ignoriert  die  aktuelle
       Implementierung  jeden  Dateideskriptor  in  diesen  Mengen,  der  größer als die maximale
       Dateideskriptorennummer ist, die der Prozess derzeit offen hat. Laut  POSIX  sollte  jeder
       solcher  Dateideskriptoren,  der  in einem der drei Mengen festgelegt ist, zu einem Fehler
       EBADF führen.

       Glibc 2.0 stellte eine Version von  pselect()  bereit,  die  das  Argument  sigmask  nicht
       akzeptierte.

       Beginnend  mit  Version  2.1 stellt Glibc eine Emulation von pselect() bereit, die mittels
       sigprocmask(2) und select() implementiert  wurde.  Diese  Implementierung  blieb  für  den
       starken Ressourcenwettlauf verwundbar, der durch das Design von pselect() vermieden werden
       sollte.   Moderne   Versionen   der   Glibc   verwenden   den   (ressourcenwettlauffreien)
       pselect()-Systemaufruf auf Kerneln, die ihn bereitstellen.

       Unter  Linux  könnte  select() einen Socket-Dateideskriptor als »bereit zum Lesen« melden,
       obwohl trotzdem ein folgendes Lesen blockiert. Dies könnte beispielsweise passieren,  wenn
       Daten  angekommen  sind,  aber bei genauerer Prüfung die falsche Prüfsumme haben und daher
       verworfen  werden.  Es  mag  andere  Umstände  geben,   in   denen   ein   Dateideskriptor
       fälschlicherweise  als  bereit  berichtet  werden  könnte.  Daher  mag  es  sicherer sein,
       O_NONBLOCK bei Sockets zu benutzen, die nicht blockieren sollen.

       Unter Linux verändert select() auch timeout falls  der  Aufruf  durch  ein  Signal-Handler
       unterbrochen  wird  (d.h.  den  Fehler  EINTR  zurückliefert). Dies wird von POSIX.1 nicht
       erlaubt.  Der  Linux-Systemaufruf  pselect()  zeigt  das  gleiche  Verhalten,   aber   der
       Glibc-Wrapper  versteckt  das  Verhalten,  indem er intern timeout in eine lokale Variable
       kopiert und diese Variable an den Systemaufruf übergibt.

BEISPIEL

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

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

           /* Beobachte 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);
           /* Verlassen Sie sich jetzt nicht auf den Wert von tv! */

           if (retval == -1)
               perror("select()");
           else if (retval)
               printf("Daten sind jetzt verfügbar.\n");
               /* FD_ISSET(0, &rfds) werden wahr sein. */
           else
               printf("Innerhalb von fünf Sekunden keine Daten.\n");

           exit(EXIT_SUCCESS);
       }

SIEHE AUCH

       accept(2),   connect(2),   poll(2),   read(2),   recv(2),   restart_syscall(2),   send(2),
       sigprocmask(2), write(2), epoll(7), time(7)

       Für eine Anleitung mit Diskussionen und Beispielen lesen Sie select_tut(2).

KOLOPHON

       Diese  Seite  ist  Teil  der  Veröffentlichung  5.03  des  Projekts  Linux-man-pages. Eine
       Beschreibung des Projekts, Informationen, wie Fehler  gemeldet  werden  können  sowie  die
       aktuelle Version dieser Seite finden sich unter https://www.kernel.org/doc/man-pages/.

ÜBERSETZUNG

       Die    deutsche    Übersetzung    dieser    Handbuchseite   wurde   von   Martin   Schulze
       <joey@infodrom.org>,   Daniel   Kobras   <kobras@linux.de>,   Martin   Eberhard    Schauer
       <Martin.E.Schauer@gmx.de>,  Mario  Blättermann  <mario.blaettermann@gmail.com>  und  Helge
       Kreutzmann <debian@helgefjell.de> erstellt.

       Diese Übersetzung ist Freie Dokumentation;  lesen  Sie  die  GNU  General  Public  License
       Version   3  oder  neuer  bezüglich  der  Copyright-Bedingungen.  Es  wird  KEINE  HAFTUNG
       übernommen.

       Wenn Sie Fehler in der Übersetzung dieser Handbuchseite finden, schicken Sie bitte eine E-
       Mail an <debian-l10n-german@lists.debian.org>.