Manned.org

pselect

select(2)                      System Calls Manual                     select(2)

NAAM
       select, pselect, FD_CLR, FD_ISSET, FD_SET, FD_ZERO fd_set- synchrone
       Invoer/Uitvoer multiplexing

BIBLIOTHEEK
       Standaard C bibliotheek (libc, -lc)

SAMENVATTING
       #include <sys/select.h>

       typedef /* ... */ fd_set;

       int select(int nfds, fd_set *restrict leesbi,
                  fd_set *restrict schrijfbi, fd_set *restrict uitzondbi,
                  struct timeval *_NULL_baar restrict tijdslimiet);

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

       int select(int nfds, fd_set *restrict leesbi,
                  fd_set *restrict schrijfbi, fd_set *restrict uitzondbi,
                  const struct timespec *restrict tijdslimiet,
                  const sigset_t *_NULL_baar restrict sigmask);

   Feature Test Macro Requirements voor glibc (zie feature_test_macros(7)):

       pselect():
           _POSIX_C_SOURCE >= 200112L

BESCHRIJVING
       WAARSCHUWING: select() kan alleen bestandsindicator nummers monitoren die
       kleiner zijn dan FD_SETSIZE (1024)—een onmogelijk kleine limiet voor veel
       moderne applicaties—en deze limiet zal niet veranderen. Alle moderne
       applicaties gebruiken daarom beter poll(2)  of epoll(7), die geen last
       hebben van deze beperking.

       select() staat een programma toe meerdere bestandsindicators te
       monitoren, het wacht totdat een of meer bestandsindicators "gereed"
       worden voor een aantal klassen van Invoer/Uitvoer operaties (b.v. invoer
       mogelijk). Een bestandsindicator wordt gereed geacht als het mogelijk is
       de overeenkomende Invoer/Uitvoer operatie uit te voeren (b.v. read(2), of
       een voldoende kleine write(2))  zonder blokkering.

   fd_set
       Een structure type dat een verzameling bestandsindicatoren kan
       representeren. Volgens POSIX, is de waarde van de macro FD_SETSIZE het
       maximum aantal bestandsindicatoren dat een fd_set structure kan bevatten.

   Bestandsindicator verzamelingen
       Het hoofdargument van select() zijn drie "verzamelingen" van
       bestandsindicators (gedeclareerd met het type fd_set), dat de aanroeper
       toestaat te wachten op drie klassen van gebeurtenissen op de
       gespecificeerde verzameling van bestandsindicators. Elk van de fd_set
       argumenten mag als NULL worden opgegeven als geen bestandsindicators
       moeten in de gaten worden gehouden voor de overeenkomende klasse van
       gebeurtenissen.

       Let op:  Bij terugkeer wordt elke bestandsindicator verzameling ter
       plekke gemodificeerd om aan te geven welke bestandsindicator op dat
       moment "gereed" is. Daarom, als select() in een lus wordt gebruikt moeten
       de verzamelingen geinitialiseerd worden voorafgaand aan elke aanroep.

       De inhoud van een bestandsindicator verzameling kan aangepast worden door
       de volgende macro´s te gebruiken:

       FD_ZERO()
              Deze macro wist (verwijdert alle bestandsindicators van)
              verzameling. Hij moet worden gebruikt als een eerste stap bij het
              initialiseren van een bestandsindicator verzameling.

       FD_SET()
              Deze macro voegt een bestandsindicator bi toe aan verzameling. Het
              toevoegen van een reeds bestaande indicator aan een verzameling
              doet niets, en produceert geen fout.

       FD_CLR()
              Deze macro verwijderd een bestandsindicator bi van een
              verzameling. Het verwijderen van een niet-aanwezige indicator in
              de verzameling doet niks, en produceert geen fout.

       FD_ISSET()
              select() modificeert de inhoud van verzamelingen volgens de
              hieronder beschreven regels. Na het aanroepen van select() kan de
              FD_ISSET() macro  worden gebruikt om te testen of een
              bestandsindicator nog aanwezig is in de verzameling. FD_ISSET()
              retourneert niet-nul als de bestandsindicator bi aanwezig is in
              verzameling, en nul als hij niet aanwezig is.

   Argumenten
       De argumenten van select() zij als volgt:

       leesbi De bestandsindicators in deze verzameling worden bekeken om te
              zien of deze gereed zijn om te lezen. Een bestandsindicator is
              gereed om te lezen als een lees operatie niet zal blokkeren; in
              het bijzonder is een bestandsindicator ook gereed bij het
              bestand-einde.

              Nadat select() is teruggekeerd zullen alle bestandsindicators in
              leesbi worden gewist behalve die, die gereed zijn om te lezen.

       schrijfbi
              De bestandsindicators in deze verzameling worden bekeken om te
              zien of deze gereed zijn om te schrijven. Een bestandsindicator is
              gereed om te schrijven als een schrijf operatie niet zal
              blokkeren. Hoewel zelfs als een bestandsindicator aangeeft
              schrijfbaar te zijn, kan een grote schrijfactie toch blokkeren .

              Nadat select() is teruggekeerd zullen alle bestandsindicators in
              schrijfbi worden gewist behalve die, die gereed zijn om te
              schrijven.

       uitzondbi
              De bestandsindicators in deze verzameling worden bekeken op
              "uitzonderlijke condities". Voor e

              Nadat select() is teruggekeerd zullen alle bestandsindicators in
              uitzondbi worden gewist behalve die, waarvoor een uitzonderlijke
              conditie is opgetreden.

       nfds   Dit argument dient gezet te worden op de hoogst-genummerde
              bestandsindicator in enige van de drie verzamelingen, plus 1. De
              aangegeven bestandsindicators in elke verzameling worden
              gecontroleerd, tot deze limiet (let op, zie BUGS).

       tijdslimiet
              Het tijdslimiet argument is een timeval structure (hieronder) die
              het interval specificeert dat select() moet blokkeren terwijl hij
              wacht op een bestandsindicator om "gereed" te worden. De aanroep
              zal blokkeren totdat ofwel:

              •  een bestandsindicator wordt gereed;

              •  een aanroep werd onderbroken door een signaal afhandelaar; of

              •  de tijdslimiet verliep.

              Let op dat het tijdslimiet interval wordt afgerond op de systeem
              klok korrel, en de vertraging door het schedulen van de kernel
              betekent dat het blokkeer interval kan worden overschreden met een
              kleine hoeveelheid.

              Als beide velden van de tijdslimiet structure nul zijn, dan keert
              select() meteen terug. (Dit is bruikbaar om te pollen)

              Als tijdslimiet werd opgegeven als NULL, dan wacht select()
              oneindig lang totdat een bestandsindicator "gereed" wordt.

   pselect()
       De pselect() systeem aanroep staat een applicatie toe om veilig te
       wachten totdat een bestandsindicator gereed wordt of een signaal wordt
       ontvangen.

       De werking van  select()  en pselect()  is identiek, anders dan deze drie
       verschillen:

       •  select() gebruikt een tijdslimiet welk een struct timeval (met
          seconden en microseconden) is, terwijl pselect()  een struct timespec
          is (met seconden en nanosecondsen).

       •  select() kan het tijdslimiet argument updaten om aan te geven hoeveel
          tijd er overbleef. pselect() verandert dit argument niet.

       •  select() heeft geen sigmask argument en gedraagt zich als een
          pselect() aanroep met sigmask gelijk aan NULL.

       sigmask is een wijzer naar een signaal masker (zie sigprocmask(2)); als
       het niet NULL is, dan vervangt pselect() eerst het huidige sigmaal masker
       door het masker aangewezen door sigmask, voert vervolgens de "select"
       functie uit, en hersteld het het originele signaal masker. (Als sigmask
       is NULL, dan wordt het signaal masker niet gewijzigd door de pselect()
       aanroep.

       Anders dan het verschil in de precisie van het tijdslimiet argument, is
       de volgende pselect() aanroep:

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

       equivalent aan het atomair uitvoeren van de volgende aanroepen:

           sigset_t origmask;

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

       De reden dat pselect() nodig is, is dat als men wil wachten op ofwel een
       signaal of het "gereed" worden van een  bestandsindicator, dan voorkomt
       een atomaire test race-condities. (Veronderstel dat de signaal
       afhandelaar een globale vlag zet en terug keert. Dan zou een test van
       deze globale vlag gevolgd door een aanroep van select() oneindig lang
       hangen als het signaal precies na de test aankwam maar precies vóór de
       aanroep. In tegenstelling hiermee staat pselect() toe om eerst het
       signaal te blokkeren, het ontvangen signaal af te handelen, en dat
       pselect() aan te roepen, met het gewenste sigmask, daarmee de race te
       voorkomen.

   De tijdslimiet
       Het tijdslimiet argument van select() is een structure van het volgende
       type:

           struct timeval {
               time_t      tv_sec;         /* seconden */
               suseconds_t tv_usec;        /* microseconden */
           };

       Het overeenkomende argument voor pselect() is een timespec(3) structure:

       On Linux, select()  modifies timeout to reflect the amount of time not
       slept; most other implementations do not do this.  (POSIX.1 permits
       either behavior.)  This causes problems both when Linux code which reads
       timeout is ported to other operating systems, and when code is ported to
       Linux that reuses a struct timeval for multiple select()s in a loop
       without reinitializing it.  Consider timeout to be undefined after
       select() returns.

EIND WAARDE
       Bij succes geven select() en pselect() het aantal bestandsindicators
       terug die bevat zijn in de drie geretourneerde indicator verzamelingen
       (dat is, het totaal aantal bits die gezet zijn in leesbi, schrijfbi,
       uitzondbi).  De uitvoer waarde mag nul zijn als de tijdslimiet verliep
       voordat een van de indicators "gereed" werd.

       Bij een fout wordt -1 teruggegeven en errno wordt overeenkomstig gezet;
       de bestandsindicators verzamelingen blijven ongewijzigd en tijdslimiet
       wordt ongedefinieerd.

FOUTEN
       EBADF  Een ongeldige bestandsindicator werd opgegeven in een van de
              verzamelingen. (Misschien een bestandsindicator die al gesloten
              werd, of een waarop een fout is opgetreden.) Hoewel, zie BUGS.

       EINTR  Een signaal werd gevangen; zie signal(7).

       EINVAL nfds is negatief of overschrijdt de  RLIMIT_NOFILE hulpbron limiet
              (zie getrlimit(2)).

       EINVAL De waarde bevat in tijdslimiet is ongeldig.

       ENOMEM Het was niet mogelijk om voldoende geheugen de bemachtigen voor
              interne tabellen.

VERSIES
       Op sommige andere UNIX systemen, kan select() falen met de fout EAGAIN
       als het systeem faalt om kernel-interne hulpbronnen toe te kennen, in
       plaats van ENOMEM zoals Linux doet.  POSIX specificeert deze fout voor
       poll(2), maar niet voor select().  Overdraagbare programma´s controleren
       beter op EAGAIN en lussen dan, net als bij EINTR.

STANDAARDEN
       POSIX.1-2024.

HISTORIE
       select()
              POSIX.1-2001, 4.4BSD (verscheen voor het eerst in 4.2BSD).

              Algemeen overdraagbaar naar/van niet-BSD systemen daarbij de
              klonen met de BSD socket laag ondersteunend (inclusief System V
              varianten). Let op dat de System V varianten typisch de
              tijdslimiet variabele zet voor terugkeer, maar dat de BSD variant
              dit niet doet.

       pselect()
              Linux 2.6.16.  POSIX.1g, POSIX.1-2001.

              Voordien werd het geëmuleerd in glibc (echter zie BUGS)

       fd_set POSIX.1-2001.

OPMERKINGEN
       De volgende header voorziet ook in het fd_set type: <sys/time.h>.

       Als fd_set een vaste buffer grootte is. Uitvoeren van FD_CLR()  of
       FD_SET() met een waarden van bi die negatief is of groter of gelijk is
       aan FD_SETSIZE zal resulteren in onbepaald gedrag. Bovendien vereist
       POSIX dat bi een geldige bestandsindicator is.

       De werking van  select()  en pselect()  wordt niet beïnvloed door de
       O_NONBLOCK vlag.

   De zelf-pijp truc
       Op systemen waar pselect() ontbreekt, betrouwbare (en meer overdraagbare)
       signaal trapping kan worden bereikt met de zelf-pijp truc. In deze truc
       schrijft een signaal afhandelaar een byte naar een pijp wiens andere
       einde wordt gemonitord door select() in het hoofdprogramma. (Om blokkeren
       te voorkomen bij het schrijven naar een volle pijp, of lezen van een lege
       pijp, dient niet-blokkerende Invoer/Uitvoer gebruikt te worden bij het
       lezen van en schrijven naar een pijp.)

   Emuleren usleep(3)
       Voor het verschijnen van usleep(3) gebruikte sommige code de aanroep van
       select() met alle verzamelingen leeg, nfds nul, en een niet-NULL
       tijdslimiet als een enigszins overdraagbare manier om met subseconde
       precisie te slapen.

   Overeenkomsten tussen select() en poll() meldingen
       In de Linux kernel broncode vinden we de volgende definities die de
       overeenkomsten tussen de leesbare, schrijfbare en uitzondering condities
       notificaties van select() tonen en de gebeurtenis notificaties voorzien
       door poll(2) en epoll(7):

           #define POLLIN_SET  (EPOLLRDNORM | EPOLLRDBAND | EPOLLIN |
                                EPOLLHUP | EPOLLERR)
                              /* Gereed om te lezen */
           #define POLLOUT_SET (EPOLLWRBAND | EPOLLWRNORM | EPOLLOUT |
                                EPOLLERR)
                              /* Gereed om te schrijven */
           #define POLLEX_SET  (EPOLLPRI)
                              /* Uitzondering conditie */

   Multithreaded applicaties
       Als een bestandsindicator die door select() wordt gemonitord wordt
       gesloten in een andere thread, dan is het resultaat niet gespecificeerd.
       Op sommige UNIX systemen zal select() uit blokkeren gaan en terug keren
       met een indicatie dat de bestandsindicator gereed is (een opvolgende
       Invoer/Uitvoer operatie zal mogelijk falen met een fout, behalve als een
       ander proces de bestandsindicator heropent tussen het tijdstip dat
       select() terug gaf en de Invoer/Uitvoer operatie werd uitgevoerd). Op
       Linux (en sommige andere systemen) heeft het sluiten van de
       bestandsindicator in een andere thread geen effect op select().
       Samenvattend: een applicatie die vertrouwt op een specifiek gedrag in dit
       scenario moet als buggy beschouwd worden.

   C library/kernel verschillen
       De Linux kernel staat bestandsindicator verzamelingen van willekeurige
       grootte toe, waarbij de lengte van de verzamelingen kan worden bepaald
       aan de hand van de waarde van nfds. Hoewel in de glibc implementatie het
       type fs_set een vaste grootte heeft. Zie ook BUGS.

       Het pselect() interface beschreven op deze pagina is geïmplementeerd in
       glibc. De onderliggende Linux systeem aanroep is pselect6() genaamd. Deze
       systeem aanroep verschilt iet of wat in gedrag van de glibc omwikkel
       functie.

       De Linux pselect6() systeem aanroep verandert zijn tijdslimiet argument.
       Hoewel de glibc omwikkel functie dit gedrag verbergt door het gebruik van
       een lokale variabele voor het timeout argument dat wordt door gegeven aan
       de systeem aanroep. Dus modificeert de glibc pselect() functie zijn
       argument tijdslimiet niet; dit gedrag wordt ook vereist door
       POSIX.1-2001.

       Het laatste argument van de pselect6() systeem aanroep is geen sigset_t *
       wijzer, maar in plaats daarvan een structure van de vorm:

           struct {
               const kernel_sigset_t *ss;   /* Wijzer naar een signaal verzameling */
               size_t ss_len;               /* Grootte (in bytes) van het object
                                               aangewezen door 'ss' */
           };

       Dit staat de systeem aanroep toe om zowel een wijzer naar de signaal
       verzameling als ook zijn grootte te hebben, terwijl gelijkertijd wordt
       toegestaan op de meeste architecturen een maximum van 6 argumenten te
       ondersteunen voor de systeem aanroep. Zie sigprocmask(2)  voor een
       discussie over de verschillen tussen de kernel en de libc notatie van de
       signaal verzameling.

   Historische glibc details
       glibc 2.0 voorzag in een incorrecte versie van pselect() die niet om een
       sigmask argument vroeg.

       In de glibc 2.1 tot 2.2.1 moest  men _GNU_SOURCE definiëren om de
       declaratie van pselect() uit <sys/select.h> te verkrijgen.

BUGS
       POSIX staat een implementatie toe om een bovenlimiet te definiëren, die
       wordt geadverteerd door de constante FD_SETSIZE, voor de het bereik van
       bestandsindicatoren dat kan worden opgegeven in een bestandsindicator
       verzameling. De Linux kernel legt geen vaste limiet op, maar de glibc
       implementatie maakt van fd_set een type van vaste grootte, met FD_SETSIZE
       gedefinieerd als 1024, en de FD_*() macro´s werkend conform deze limiet.
       Om bestandsindicatoren te monitoren die groter dan deze limiet zijn, moet
       u poll(2) of epoll(7) gebruiken.

       De implementatie van de fd_sets argumenten als het resultaat van een
       waarde argument is een ontwerpfout die werd voorkomen in poll(2) en
       epoll(7)

       Volgens POSIX zou select() alle opgegeven bestandsindicatoren in de drie
       bestandsindicatoren verzamelingen moeten controleren, tot aan de limiet
       nfds-1. Hoewel de huidige implementatie elke bestandsindicator in deze
       verzamelingen negeert die groter is dan het maximum bestandsindicator
       getal dat het proces momenteel geopend heeft. Volgens POSIX zou elke
       bestandsindicator die werd opgegeven in een van de verzamelingen moeten
       resulteren in de EBADF fout.

       Vanaf glibc 2.1 voorzag glibc in een emulatie van pselect() die werd
       geïmplementeerd gebruikmakend van sigprocmask(2)  en select(). Deze
       implementatie was gevoelig voor dezelfde race conditie waarvoor nu
       precies pselect() ontworpen was om te voorkomen. Moderne versies van
       glibc gebruiken de (race-vrije) pselect() systeem aanroep op kernels
       waarin deze is voorzien.

       Op Linux kan select() een socket bestandsindicator rapporteren als
       "gereed om te lezen", terwijl tegelijkertijd een opeenvolgende lees-actie
       blokkeert. Dit kan bijvoorbeeld optreden wanneer data werd ontvangen maar
       bij het onderzoeken blijkt dat de controlesom verkeerd is en wordt
       verworpen. Er kunnen andere omstandigheden zijn waarin
       bestandsindicatoren ten onrechte worden gerapporteerd als gereed. Het kan
       daarom veiliger zijn om O_NONBLOCK te gebruiken op sockets die niet mogen
       blokkeren.

       Op Linux wijzigt select() ook tijdslimiet als de aanroep werd onderbroken
       door een signaal afhandelaar (m.a.w. de EINTR foutmelding). Dit wordt
       niet toegestaan door POSIX.1. De Linux pselect() systeem aanroep heeft
       hetzelfde gedrag, maar de glibc omwikkel functie verstopt dit gedrag door
       de tijdslimiet intern te kopiëren naar een lokale variabele en deze
       variabele door te geven naar de systeem aanroep.

VOORBEELDEN
       #include <stdio.h>
       #include <stdlib.h>
       #include <sys/select.h>
       #include <sys/time.h>

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

           /* Watch stdin (fd 0) to see when it has input.  */

           FD_ZERO(&rfds);
           FD_SET(0, &rfds);

           /* Wait up to five seconds.  */

           tv.tv_sec = 5;
           tv.tv_usec = 0;

           retval = select(1, &rfds, NULL, NULL, &tv);
           /* Don't rely on the value of tv now! */

           if (retval == -1)
               perror("select()");
           else if (retval)
               printf("Data is available now.\n");
               /* FD_ISSET(0, &rfds) will be true.  */
           else
               printf("No data within five seconds.\n");

           exit(EXIT_SUCCESS);
       }

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

       Voor een inleiding met discussie en voorbeelden zie select_tut(2).

VERTALING
       De Nederlandse vertaling van deze handleiding is geschreven door Jos
       Boersema <joshb@xs4all.nl>, Mario Blättermann
       <mario.blaettermann@gmail.com> en Luc Castermans
       <luc.castermans@gmail.com>

       Deze vertaling is vrije documentatie; lees de GNU General Public License
       Version 3 ⟨https://www.gnu.org/licenses/gpl-3.0.html⟩ of later over de
       Copyright-voorwaarden. Er is geen AANSPRAKELIJKHEID.

       Indien U fouten in de vertaling van deze handleiding zou vinden, stuur
       een e-mail naar ⟨debian-l10n-dutch@lists.debian.org⟩.

Linux man-pages 6.18             8 februari 2026                       select(2)