Provided by: manpages-nl-dev_4.13-4_all bug

NAAM

       select, pselect, FD_CLR, FD_ISSET, FD_SET, FD_ZERO - gelijktijdige In/Uit verdeling

SAMENVATTING

       #include <sys/select.h>

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

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

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

   Test Macro´s in glibc (zie feature_test_macros(7)):

       pselect(): _POSIX_C_SOURCE >= 200112L

BESCHRIJVING

       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.

       select()  kan  alleen  bestandsindicator  nummers  monitoren die kleiner zijn dan FD_SETSIZE ; poll(2) en
       epoll(7) hebben deze beperking niet. Zie BUGS.

   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  implementatie  van  de  fd_set
       argumenten als waarde-resultaat argumenten is een ontwerp fout die werd vermeden in poll(2)   epoll(7).

       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() heeft het volgende type:

           struct timespec {
               time_t      tv_sec;         /* seconden */
               long        tv_nsec;        /* nanoseconden */
           };

       Op Linux, wijzigt select() tijdslimiet om  de  niet  geslapen  tijd  weer  te  geven;  de  meeste  andere
       implementaties  doen  dit  niet.   (POSIX.1 staat beide gedragingen toe.) Dit veroorzaakt problemen zowel
       wanneer Linux code die tijdslimiet leest, wordt overgezet op andere besturingssystemen, als wanneer  code
       wordt  overgezet naar Linux, die struct timeval hergebruikt voor meerdere select() in een lus zonder deze
       te her-initialiseren. Beschouw tijdslimiet niet gedefinieerd nadat select terugkeert

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

       pselect()  werd  toegevoegd aan Linux in kernel 2.6.16. Voordien werd pselect() geëmuleerd in glibc (maar
       zie BUGS)

VOLDOET AAN

       select() voldoet aan POSIX.1-2001,  POSIX.1-2008,  and  4.4BSD  (select()  verscheen  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()  is gedefineerd in POSIX.1g, en in POSIX.1-2001 en POSIX.1-2008.

OPMERKINGEN

       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.

       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.

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

       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  versie  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>

       int
       main(void)
       {
           fd_set lbesb;
           struct timeval tw;
           int terugwrd;

           /* Beloer stdin (bi 0) om te kijken wanneer het invoer heeft. */

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

           /* Wacht maximaal vijf seconden. */

           tw.tv_sec = 5;
           tw.tv_usec = 0;

           retval = select(1, &rfds, NULL, NULL, &tv);
           /* Vertrouw nu de waarde van tv niet! */

           if (terugwrd == -1)
               perror("select()");
           else if (terugwrd)
               printf("Gegevens zijn nu beschikbaar.\n");
               /* FD_ISSET(0, &lbesb) zal waar zijn. */
           else
               printf("Geen gegevens binnen vijf seconden.\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),
       epoll(7), time(7)

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

COLOFON

       Deze  pagina  is  onderdeel  van  release  5.10 van het Linux man-pages-project. Een beschrijving van het
       project,  informatie  over  het  melden  van  bugs  en  de  nieuwste  versie  van  deze  pagina  zijn  op
       https://www.kernel.org/doc/man-pages/ te vinden.

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  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                                            1 november 2020                                       SELECT(2)