Provided by: manpages-nl-dev_4.21.0-2_all bug

NAAM

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

BIBLIOTHEEK

       Standard 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, 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´s eisen in  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:

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

       pselect()  is gedefinieerd in POSIX.1-2001 en later.

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.

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

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

           /* 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),
       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  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-pagina's 6.03                          5 februari 2023                                       select(2)