Provided by: manpages-de-dev_2.5-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) ohne zu blockieren oder ein
       hinreichend kleines write(2)) 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  Zeitbegrenzungen  (timeouts)  eine  struct  timeval  (mit
              Sekunden und Mikrosekunden), während pselect()  stattdessen  eine  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 (timeout) 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 (kein timeout), 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);

       äquivalent  zur  atomaren  (unterbrechungsfreien,  aufeinanderfolgenden)  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.

       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  jemand
       anders  hat  den Dateideskriptor zwischen dem Zeitpunkt, zu dem select() zurückkehrte, und
       dem Zeitpunkt, zu der die E/A-Aktion stattfand, 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  Arguemnt  »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).

       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  4.15  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>, Helge Kreutzmann <debian@helgefjell.de> und  Mario  Blättermann
       <mario.blaettermann@gmail.com> 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>.