Provided by: manpages-nl-dev_4.15.0-9_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 *restrict leesbi,
                  fd_set *restrict schrijfbi, fd_set *restrict uitzondbi,
                  struct timeval *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 *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\men  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.

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

       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 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.13  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
       ⟨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⟩.