Provided by: manpages-de-dev_0.5-2_all bug
 

BEZEICHNUNG

        select, pselect, FD_CLR, FD_ISSET, FD_SET, FD_ZERO - Synchrone I/O-Mul‐
        tiplexsteuerung
 
    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 Mikrosekun‐
               den), 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  behan‐
        delt.   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 Sta‐
        tus 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 pse     
        lect-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 verstre‐
        ichen 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  Pro‐
        gramm 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 ver‐
        strichenen Teil des Zeitlimits entspricht.  Die meisten Implementierun‐
        gen  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);
        }
        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 typ‐
        ischerweise 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 Funk‐
        tion dieses Namens, die jedoch keinen Parameter sigmask verwendet.
        accept(2), connect(2), poll(2),  read(2),  recv(2),  send(2),  sigproc     
        mask(2), write(2).