Provided by: manpages-nl-dev_4.27.0-1_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

       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.

VOLDOET AAN

       POSIX.1-2008.

GESCHIEDENIS

       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>

       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 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.9.1                          15 juni 2024                                         select(2)