.\" -*- coding: UTF-8 -*-
.\" This manpage is copyright (C) 1992 Drew Eckhardt,
.\"     copyright (C) 1995 Michael Shields,
.\"     copyright (C) 2001 Paul Sheer,
.\"     copyright (C) 2006, 2019 Michael Kerrisk <mtk.manpages@gmail.com>
.\"
.\" SPDX-License-Identifier: Linux-man-pages-copyleft
.\"
.\" Modified 1993-07-24 by Rik Faith <faith@cs.unc.edu>
.\" Modified 1995-05-18 by Jim Van Zandt <jrv@vanzandt.mv.com>
.\" Sun Feb 11 14:07:00 MET 1996  Martin Schulze  <joey@linux.de>
.\"	* layout slightly modified
.\"
.\" Modified Mon Oct 21 23:05:29 EDT 1996 by Eric S. Raymond <esr@thyrsus.com>
.\" Modified Thu Feb 24 01:41:09 CET 2000 by aeb
.\" Modified Thu Feb  9 22:32:09 CET 2001 by bert hubert <ahu@ds9a.nl>, aeb
.\" Modified Mon Nov 11 14:35:00 PST 2002 by Ben Woodard <ben@zork.net>
.\" 2005-03-11, mtk, modified pselect() text (it is now a system
.\"     call in Linux 2.6.16.
.\"
.\"*******************************************************************
.\"
.\" This file was generated with po4a. Translate the source file.
.\"
.\"*******************************************************************
.TH select 2 "15 czerwca 2024 r." "Linux man\-pages 6.9.1" 
.SH NAZWA
select, pselect, FD_CLR, FD_ISSET, FD_SET, FD_ZERO, fd_set \- synchronicznie
zwielokrotnia wejście/wyjście
.SH BIBLIOTEKA
Standardowa biblioteka C (\fIlibc\fP, \fI\-lc\fP)
.SH SKŁADNIA
.nf
\fB#include <sys/select.h>\fP
.P
\fBtypedef\fP /* ... */ \fBfd_set;\fP
.P
\fBint select(int \fP\fInfds\fP\fB, fd_set *_Nullable restrict \fP\fIreadfds\fP\fB,\fP
\fB           fd_set *_Nullable restrict \fP\fIwritefds\fP\fB,\fP
\fB           fd_set *_Nullable restrict \fP\fIexceptfds\fP\fB,\fP
\fB           struct timeval *_Nullable restrict \fP\fItimeout\fP\fB);\fP
.P
\fBvoid FD_CLR(int \fP\fIfd\fP\fB, fd_set *\fP\fIset\fP\fB);\fP
\fBint  FD_ISSET(int \fP\fIfd\fP\fB, fd_set *\fP\fIset\fP\fB);\fP
\fBvoid FD_SET(int \fP\fIfd\fP\fB, fd_set *\fP\fIset\fP\fB);\fP
\fBvoid FD_ZERO(fd_set *\fP\fIset\fP\fB);\fP
.P
\fBint pselect(int \fP\fInfds\fP\fB, fd_set *_Nullable restrict \fP\fIreadfds\fP\fB,\fP
\fB           fd_set *_Nullable restrict \fP\fIwritefds\fP\fB,\fP
\fB           fd_set *_Nullable restrict \fP\fIexceptfds\fP\fB,\fP
\fB           const struct timespec *_Nullable restrict \fP\fItimeout\fP\fB,\fP
\fB           const sigset_t *_Nullable restrict \fP\fIsigmask\fP\fB);\fP
.fi
.P
.RS -4
Wymagane ustawienia makr biblioteki glibc (patrz \fBfeature_test_macros\fP(7)):
.RE
.P
\fBpselect\fP():
.nf
    _POSIX_C_SOURCE >= 200112L
.fi
.SH OPIS
\fBOSTRZEŻENIE\fP: \fBselect\fP() potrafi monitorować deskryptory plików o
numerach mniejszych niż \fBFD_SETSIZE\fP (1024) \[em] limit nierozsądnie
niewielki dla wielu współczesnych aplikacji \[em] i ograniczenie to nie
zmieni się. Wszystkie współczesne aplikacje powinny w zamian korzystać z
\fBpoll\fP(2) lub \fBepoll\fP(7), które nie mają tego ograniczenia.
.P
.\"
\fBselect\fP() umożliwia programowi monitorowanie wielu deskryptorów plików i
oczekiwanie aż jeden lub więcej deskryptorów będzie \[Bq]gotowy\[rq] na
wykonanie pewnej klasy operacji wejścia/wyjścia (np. możliwy
odczyt). Deskryptor pliku jest uważany za gotowy, jeżeli możliwe jest
wykonanie odpowiadającej operacji wejścia/wyjścia (np. \fBread\fP(2) lub
odpowiednio małe \fBwrite\fP(2)) bez blokowania.
.SS fd_set
.\"
Typ struktury mogącej reprezentować zbiór deskryptorów pliku. Zgodnie z
POSIX, maksymalną liczbą deskryptorów pliku w strukturze \fIfd_set\fP jest
wartość makra \fBFD_SETSIZE\fP.
.SS "Zbiory deskryptorów pliku"
Podstawowymi argumentami \fBselect\fP() są trzy \[Bq]zbiory\[rq] deskryptorów
pliku (zadeklarowane jako typ \fIfd_set\fP), pozwalające wywołującemu na
oczekiwanie na trzy klasy zdarzeń na zadanym zbiorze deskryptorów
pliku. Każdy argument \fIfd_set\fP można podać jako NULL, jeśli dla
odpowiadającej klasy zdarzeń nie mają być monitorowane deskryptory pliku.
.P
\fBProszę zwrócić szczególną uwagę\fP: Po powrocie, każdy ze zbiorów
deskryptorów pliku jest modyfikowany w miejscu, aby wskazać, które z
deskryptorów pliku są aktualnie \[Bq]gotowe\[rq]. Z tego względu, jeśli
\fBselect\fP() jest używany w pętli, zbiory \fImuszą być zainicjowane ponownie\fP
przed każdym wywołaniem.
.P
Zawartością zbiorów deskryptorów pliku można manipulować za pomocą
następujących makr:
.TP 
\fBFD_ZERO\fP()
Makro czyści (usuwa z niego wszystkie deskryptory pliku) \fIset\fP. Powinno być
użyte jako pierwszy krok w inicjowaniu zbiorów deskryptorów pliku.
.TP 
\fBFD_SET\fP()
Makro dodaje deskryptor pliku \fIfd\fP do zbioru \fIset\fP. Dodanie deskryptora
pliku, który jest już obecny w zbiorze, jest instrukcją pustą i nie powoduje
błędu.
.TP 
\fBFD_CLR\fP()
Makro usuwa deskryptor pliku \fIfd\fP z zbioru \fIset\fP. Usunięcie deskryptora
pliku, który nie jest obecny w zbiorze jest instrukcją pustą i nie powoduje
błędu.
.TP 
\fBFD_ISSET\fP()
.\"
\fBselect\fP() modyfikuje zawartość zbiorów, zgodnie z regułami opisanymi
niżej. Po wywołaniu \fBselect\fP(), można skorzystać z makra \fBFD_ISSET\fP(), aby
sprawdzić, czy deskryptor pliku jest wciąż obecny w zbiorze. \fBFD_ISSET\fP()
zwraca wartość niezerową, jeśli deskryptor pliku \fIfd\fP jest obecny w zbiorze
\fIset\fP i zero, gdy nie jest.
.SS Argumenty
Argumenty \fBselect\fP() są następujące:
.TP 
\fIreadfds\fP
Deskryptory pliku w tym zbiorze są monitorowane, aby sprawdzić, czy są
gotowe do odczytu. Deskryptor pliku jest gotowy do odczytu, jeśli operacja
odczytu nie będzie blokowała; w szczególności, deskryptor pliku jest również
gotowy na końcu pliku.
.IP
Po powrocie \fBselect\fP(), \fIreadfds\fP zostanie wyczyszczone ze wszystkich
deskryptorów pliku, poza gotowymi do odczytu.
.TP 
\fIwritefds\fP
Deskryptory pliku w tym zbiorze są monitorowane, aby sprawdzić, czy są
gotowe do zapisu. Deskryptor pliku jest gotowy do zapisu, jeśli wszystkie
operacje zapisu nie będą blokowały. Jednak nawet gdy deskryptor pliku jest
wskazywany jako zapisywalny, duży zapis może wciąż blokować.
.IP
Po powrocie \fBselect\fP(), \fIwritefds\fP zostanie wyczyszczone ze wszystkich
deskryptorów pliku, poza gotowymi do zapisu.
.TP 
\fIexceptfds\fP
Deskryptory pliku w tym zbiorze są monitorowane pod kątem \[Bq]szczególnych
okoliczności\[rq]. Przykłady takich szczególnych okoliczności opisano w
podręczniku \fBpoll\fP(2) odnośnie \fBPOLLPRI\fP.
.IP
Po powrocie \fBselect\fP(), \fIexceptfds\fP zostanie wyczyszczone ze wszystkich
deskryptorów pliku, poza tymi, dla których zaszły szczególne okoliczności.
.TP 
\fInfds\fP
Argument ten powinien być ustawiony na najwyższy numer deskryptora z
wszystkich trzech zbiorów plus 1. Sprawdzany jest wskazany deskryptor pliku
w każdym zbiorze, do tego limitu (lecz zob. USTERKI).
.TP 
\fItimeout\fP
Argument \fItimeout\fP jest strukturą \fItimeval\fP (pokazaną niżej), określającą
interwał, który powinien blokować \fBselect\fP(), czekając na gotowość
deskryptora plików. Wywołanie będzie skutkowało blokadą do momentu aż:
.RS
.IP \[bu] 3
deskryptor pliku stanie się dostępny
.IP \[bu]
lub wywołanie zostanie przerwane procedurą obsługi sygnału
.IP \[bu]
albo wywołanie przeterminuje się
.RE
.IP
Proszę zauważyć, że interwał zostanie zaokrąglony w górę do dokładności
zegara, a występowanie opóźnienia planisty jądra oznacza, że ten interwał
może być nieznacznie przekroczony.
.IP
Jeśli oba pola struktury \fItimeval\fP mają wartość zero, \fBselect\fP()
niezwłocznie zakończy pracę (jest to przydatne przy odpytywaniu).
.IP
.\"
Jeśli \fItimeout\fP jest równe NULL, \fBselect\fP() może blokować w
nieskończoność, czekając na gotowość deskryptora pliku.
.SS pselect()
Wywołanie systemowe \fBpselect\fP() pozwala aplikacjom na bezpieczne
oczekiwanie, do momentu uzyskania gotowości przez deskryptor plików lub do
momentu przechwycenia sygnału.
.P
Funkcjonalność funkcji \fBselect\fP() i \fBpselect\fP() jest identyczna, jeśli
pominąć trzy różnice:
.IP \[bu] 3
Funkcja \fBselect\fP() używa dla parametru \fItimeout\fP typu \fIstruct timeval\fP (z
sekundami i mikrosekundami), podczas gdy \fBpselect\fP() używa typu \fIstruct timespec\fP (z sekundami i nanosekundami).
.IP \[bu]
Funkcja \fBselect\fP() może aktualizować parametr \fItimeout\fP, aby wskazać, jak
dużo czasu minęło. Funkcja \fBpselect\fP() nie zmienia tego parametru.
.IP \[bu]
Funkcja \fBselect\fP() nie przyjmuje parametru \fIsigmask\fP i zachowuje się, jak
\fBpselect\fP() wywołane z NULL\-em przekazanym w \fIsigmask\fP.
.P
\fIsigmask\fP jest wskaźnikiem do maski sygnałów (zobacz
\fBsigprocmask\fP(2)). Jeśli nie jest równe NULL, to \fBpselect\fP() najpierw
zastępuje bieżącą maskę sygnałów maską wskazywaną przez \fIsigmask\fP, a
następnie wywołuje funkcję \[Bq]select\[rq], a po jej zakończeniu odtwarza
oryginalną maskę sygnałów (jeśli \fIsigmask\fP wynosi NULL, to maska sygnałów
nie jest modyfikowana podczas wywołania \fBpselect\fP()).
.P
Poza różnicą w precyzji argumentu \fItimeout\fP, następujące wywołanie
\fBpselect\fP():
.P
.in +4n
.EX
ready = pselect(nfds, &readfds, &writefds, &exceptfds,
                timeout, &sigmask);
.EE
.in
.P
jest odpowiednikiem \fIniepodzielnego\fP wykonania następujących funkcji:
.P
.in +4n
.EX
sigset_t origmask;
\&
pthread_sigmask(SIG_SETMASK, &sigmask, &origmask);
ready = select(nfds, &readfds, &writefds, &exceptfds, timeout);
pthread_sigmask(SIG_SETMASK, &origmask, NULL);
.EE
.in
.P
Idea \fBpselect\fP() polega na tym, że gdy chce się oczekiwać na zdarzenie
będące sygnałem lub czymś na deskryptorze pliku, potrzebny jest atomowy test
zapobiegający sytuacjom wyścigu. (Przypuśćmy, że procedura obsługi sygnału
ustawia globalny znacznik i kończy działanie. Wówczas, test tego znacznika
globalnego, po którym następuje wywołanie \fBselect\fP() może wisieć w
nieskończoność, gdyby sygnał przybył natychmiast po teście, ale przed
wywołaniem. Inaczej mówiąc, \fBpselect\fP zezwala na, najpierw, zablokowanie
sygnałów, następnie obsłużenie dostarczonych sygnałów, aby wreszcie wywołać
\fBpselect\fP() z pożądanym \fIsigmask\fP, unikając wyścigu).
.SS Przeterminowanie
Argument \fItimeout\fP do \fBselect\fP() jest strukturą następującego typu:
.P
.in +4n
.EX
struct timeval {
    time_t      tv_sec;         /* sekundy */
    suseconds_t tv_usec;        /* mikrosekundy */
};
.EE
.in
.P
Odpowiadającym argumentem \fBpselect\fP() jest struktura \fBtimespec\fP(3).
.P
.\" .P - it is rumored that:
.\" On BSD, when a timeout occurs, the file descriptor bits are not changed.
.\" - it is certainly true that:
.\" Linux follows SUSv2 and sets the bit masks to zero upon a timeout.
Pod Linuksem funkcja \fBselect\fP() modyfikuje \fItimeout\fP, aby odzwierciedlić
ilość nieprzespanego czasu; większość innych implementacji tego nie robi
(POSIX.1 dopuszcza oba te zachowania). Powoduje to problemy, zarówno gdy kod
linuksowy odczytujący \fItimeout\fP zostanie przeniesiony na inne systemy
operacyjne, jak i gdy kod przeniesiony pod Linuksa z innych systemów używa
ponownie struktury \fItimeval\fP dla wielu wywołań \fBselect\fP() w pętli, bez
powtórnej inicjacji. Prosimy rozważyć traktowanie wartości \fItimeout\fP jako
niezdefiniowanej po zakończeniu funkcji \fBselect\fP().
.SH "WARTOŚĆ ZWRACANA"
Po pomyślnym zakończeniu, \fBselect\fP() i \fBpselect\fP() zwracają liczbę
deskryptorów w zbiorach deskryptorów (to jest całkowitą liczbę bitów
ustawioną w \fIreadfds\fP, \fIwritefds\fP, \fIexceptfds\fP). Wartość zwracana może
wynosić zero, jeśli czas oczekiwania upłynął zanim jakiś deskryptor plików
stał się gotowy.
.P
Po błędzie zwracane jest \-1 i ustawiane \fIerrno\fP, wskazując błąd; zbiory
deskryptorów nie są modyfikowane, a \fItimeout\fP staje się niezdefiniowane.
.SH BŁĘDY
.TP 
\fBEBADF\fP
W jednym ze zbiorów przekazano niepoprawny deskryptor pliku (być może
deskryptor ten został już zamknięty lub wystąpił na nim inny
błąd). Zob. jednak BŁĘDY.
.TP 
\fBEINTR\fP
Przechwycono sygnał, patrz \fBsignal\fP(7).
.TP 
\fBEINVAL\fP
\fInfds\fP jest ujemne lub przekracza limit zasobów \fBRLIMIT_NOFILE\fP
(zob. \fBgetrlimit\fP(2)).
.TP 
\fBEINVAL\fP
Wartość \fItimeout\fP jest nieprawidłowa.
.TP 
\fBENOMEM\fP
Nie można było przydzielić pamięci dla wewnętrznych tablic.
.SH WERSJE
.\" Darwin, according to a report by Jeremy Sequoia, relayed by Josh Triplett
Na niektórych innych systemach Uniksowych \fBselect\fP() może zwrócić błąd
\fBEAGAIN\fP jeśli systemowi nie uda się przydzielić wewnątrzjądrowych zasobów,
zamiast \fBENOMEM\fP, tak jak robi to Linux. POSIX przewiduje ten błąd dla
\fBpoll\fP(2), lecz nie dla \fBselect\fP(). Przenośne programy mogą chcieć
sprawdzać \fBEAGAIN\fP w pętli, tak jak dla \fBEINTR\fP.
.SH STANDARDY
POSIX.1\-2008.
.SH HISTORIA
.TP 
\fBselect\fP()
POSIX.1\-2001, 4.4BSD (pojawiło się pierwotnie w 4.2BSD).
.IP
W ogólności jest przenośne do/z systemów nie\-BSD wspierających sklonowaną
warstwę gniazd BSD (włączając warianty Systemu\ V). Jednakże należy
zauważyć, że warianty Systemu\ V zasadniczo ustawiają zmienną
przeterminowania przed powrotem, ale wariant BSD tego nie robi.
.TP 
\fBpselect\fP()
Linux 2.6.16.  POSIX.1g, POSIX.1\-2001.
.IP
Wcześniej był on emulowany w glibc (patrz również USTERKI).
.TP 
\fBfd_set\fP
POSIX.1\-2001.
.SH UWAGI
Następujący nagłówek zapewnia również typ \fIfd_set\fP:
\fI<sys/time.h>\fP.
.P
\fIfd_set\fP jest buforem o stałym rozmiarze. Wykonanie \fBFD_CLR\fP() lub
\fBFD_SET\fP() z ujemną wartością \fIfd\fP albo z wartością większą lub równą
\fBFD_SETSIZE\fP spowoduje zachowanie niezdefiniowane. Ponadto POSIX wymaga, by
\fIfd\fP był prawidłowym deskryptorem pliku.
.P
.\"
Na działanie \fBselect\fP() i \fBpselect\fP() nie wpływa znacznik \fBO_NONBLOCK\fP.
.SS "Sztuczka \[Bq]potoku do siebie\[rq]"
.\"
W systemach, które nie mają \fBpselect\fP() niezawodne (i bardziej przenośne)
przechwytywanie sygnałów można osiągnąć, używając sztuczki w postaci
\[Bq]potoku do siebie\[rq]. W tej technice procedura obsługi sygnału
zapisuje bajt do potoku, którego drugi koniec jest monitorowany przez
\fBselect\fP() w głównym programie. Aby uniknąć możliwego zablokowania przy
pisaniu do potoku który może być pełny lub czytaniu z potoku który może być
pusty, przy czytaniu z i pisaniu do potoku używane jest nieblokujące
wejście/wyjście.
.SS "Emulowanie usleep(3)"
.\"
Przed powstaniem \fBusleep\fP(3) niektóre programy używały wywołania
\fBselect\fP() z wszystkimi trzema zbiorami pustymi, z \fInfds\fP równym zeru i
niezerowym \fItimeout\fP. Jest to całkiem przenośny sposób pauzowania z
dokładnością subsekundową.
.SS "Relacja pomiędzy powiadomieniami select() i poll()"
.\" fs/select.c
W źródłach jądra Linux można znaleźć następujące definicje pokazujące
relację pomiędzy powiadomieniami o warunkach: odczytu, zapisu i szczególnych
okoliczności \fBselect\fP(), a powiadomieniami zdarzeń zapewnianymi przez
\fBpoll\fP(2) i \fBepoll\fP(7):
.P
.in +4n
.EX
#define POLLIN_SET  (EPOLLRDNORM | EPOLLRDBAND | EPOLLIN |
                     EPOLLHUP | EPOLLERR)
                   /* Gotowość do odczytu */
#define POLLOUT_SET (EPOLLWRBAND | EPOLLWRNORM | EPOLLOUT |
                     EPOLLERR)
                   /* Gotowość do zapisu */
#define POLLEX_SET  (EPOLLPRI)
                   /* Szczególne okoliczności */
.EE
.in
.\"
.SS "Aplikacje wielowątkowe"
.\"
Jeśli deskryptor plików monitorowany przez \fBselect\fP() zostanie zamknięty w
innym wątku, to rezultat jest nieokreślony. Na niektórych systemach
uniksowych \fBselect\fP() odblokuje go i powróci wskazując, że dany deskryptor
plików jest gotowy (kolejne operacje wyjścia/wyjścia prawdopodobnie zakończą
się błędem, chyba że inny proces otworzy ponownie deskryptor plików w czasie
pomiędzy powrotem \fBselect\fP() a wykonanie operacji wejścia/wyjścia. W
systemie Linux (i części innych) zamknięcie deskryptora pliku w innym wątku
nie wpłynie na \fBselect\fP(). Podsumowując, każda aplikacja polegająca na
konkretnym zachowaniu w takim przypadku musi być uznana za błędną.
.SS "Różnice biblioteki C/jądra"
Jądro Linux pozwala deskryptorowi pliku ustawić dowolny rozmiar, na
podstawie długości zbiorów do sprawdzenia z wartości \fInfds\fP. Jednak w
implementacji glibc, typ \fIfd_set\fP ma stały rozmiar. Zob. też USTERKI.
.P
Interfejs \fBpselect\fP() opisany w niniejszym podręczniku jest
zaimplementowany w glibc. Stojące za nim linuksowe wywołanie systemowe
nazywa się \fBpselect6\fP(). Cechuje go nieco inne zachowanie od opisywanej
funkcji opakowującej glibc.
.P
Wywołanie systemowe \fBpselect6\fP() pod Linuksem modyfikuje argument
\fItimeout\fP. Jednakże funkcja glibc ukrywa to zachowanie przez użycie dla
argumentu timeout lokalnej zmiennej, która jest przekazywana do wywołania
systemowego. Dlatego \fBpselect\fP() z glibc nie zmienia argumentu \fItimeout\fP,
co jest zachowaniem wymaganym przez POSIX.1\-2001.
.P
Ostatnim argumentem wywołania systemowego \fBpselect6\fP() nie jest wskaźnik
\fIsigset_t\ *\fP lecz struktura postaci:
.P
.in +4n
.EX
struct {
    const kernel_sigset_t *ss;   /* Wskaźnik do zestawu sygnałów */
    size_t ss_len;               /* Rozmiar (w bajtach) obiektu, na
                                    który wskazuje \[aq]ss\[aq] */
};
.EE
.in
.P
.\"
Pozwala to wywołaniu systemowemu pobrać oba wskaźniki do zestawu sygnałowego
wraz z rozmiarem, biorąc pod uwagę, że większość architektur obsługuje
maksymalnie 6 argumentów do wywołania systemowego. Opis różnic pomiędzy
podejściem jądra i libc do zestawu sygnałów znajduje się w podręczniku
\fBsigprocmask\fP(2).
.SS "Historyczne detale glibc"
glibc 2.0 dostarczała niepoprawną wersję \fBpselect\fP(), która nie przyjmowała
argumentu \fIsigmask\fP.
.P
Od glibc 2.1 do glibc 2.2.1 konieczne było zdefiniowanie \fB_GNU_SOURCE\fP, aby
uzyskać deklarację \fBpselect\fP() z \fI<sys/select.h>\fP.
.SH USTERKI
POSIX pozwala implementacji zdefiniować górny limit zakresu deskryptorów
plików, które można podać w zbiorze deskryptora pliku, rozgłaszany stałą
\fBFD_SETSIZE\fP. Jądro Linux nie wymusza stałego limitu, lecz implementacja
glibc czyni \fIfd_set\fP typem o stałym rozmiarze, z \fBFD_SETSIZE\fP
zdefiniowanym jako 1024 i makrami \fBFD_*\fP() działającymi zgodnie z tym
limitem. Aby monitorować deskryptory plików większe niż 1023, należy w
zamian użyć \fBpoll\fP(2) lub \fBepoll\fP(7).
.P
Implementacja argumentów \fIfd_set\fP jako argumentów wartość\-wynik jest błędem
projektowym, którego uniknięto w \fBpoll\fP(2) i \fBepoll\fP(7).
.P
Zgodnie z POSIX, \fBselect\fP() powinien sprawdzać wszystkie podane deskryptory
pliku w trzech zbiorach deskryptorów pliku, do limitu \fInfds\-1\fP. Jednak
bieżąca implementacja ignoruje wszelkie deskryptory pliku w tych zbiorach,
które są wyższe od maksymalnego numeru aktualnie otwartego przez proces
deskryptora pliku. Zgodnie z POSIX, w przypadku wystąpienia takiego
deskryptora pliku w jednym z zbiorów, powinien wystąpić błąd \fBEBADF\fP.
.P
Od glibc 2.1, glibc dostarczała emulację \fBpselect\fP(), która była
zaimplementowana przy użyciu \fBsigprocmask\fP(2) i \fBselect\fP(). Implementacja
ta pozostaje podatna na wiele błędów wyścigów (race conditions), których
uniknięcie stanowiło ideę funkcji \fBpselect\fP(). Nowsze wersje glibc używają
(wolnego od wyścigów) wywołania systemowego, jeśli tylko jądro dostarcza
takiego wywołania.
.P
.\" Stevens discusses a case where accept can block after select
.\" returns successfully because of an intervening RST from the client.
.\" Maybe the kernel should have returned EIO in such a situation?
W Linuksie \fBselect\fP() może raportować deskryptory plików gniazd jako
\[Bq]dostępne do czytania\[rq], podczas gdy kolejne czytania zostaną
zablokowane. Może to się zdarzyć na przykład wtedy, gdy dane nadeszły, ale
podczas sprawdzania okazało się, że mają złą sumę kontrolną i zostały
odrzucone. Mogą wystąpić także inne sytuacje, w których deskryptor pliku
jest błędnie raportowany jako gotowy. Dlatego używanie \fBO_NONBLOCK\fP na
gniazdach, które nie powinny się blokować może być bezpieczniejsze.
.P
Pod Linuksem wywołanie \fBselect\fP() zmienia wartość \fItimeout\fP także wtedy,
gdy zostanie przerwane przez procedurę obsługi sygnału (tj. zostanie
zwrócony błąd \fBEINTR\fP). POSIX.1 nie pozwala na takie zachowanie. Wywołanie
systemowe \fBpselect\fP() pod Linuksem zachowuje się tak samo, ale funkcja
opakowująca biblioteki glibc ukrywa to zachowanie, kopiując wartość
\fItimeout\fP do wewnętrznej lokalnej zmiennej i przekazując tę zmienną do
wywołania systemowego.
.SH PRZYKŁADY
.\" SRC BEGIN (select.c)
.EX
#include <stdio.h>
#include <stdlib.h>
#include <sys/select.h>
\&
int
main(void)
{
    int             retval;
    fd_set          rfds;
    struct timeval  tv;
\&
    /* Obserwacja stdin (fd 0) i sprawdzanie kiedy ma wejście. */
\&
    FD_ZERO(&rfds);
    FD_SET(0, &rfds);
\&
    /* Czekanie do pięciu sekund. */
\&
    tv.tv_sec = 5;
    tv.tv_usec = 0;
\&
    retval = select(1, &rfds, NULL, NULL, &tv);
    /* Nie należy już polegać na wartości tv! */
\&
    if (retval == \-1)
        perror("select()");
    else if (retval)
        printf("Dane są już dostępne.\[rs]n");
        /* FD_ISSET(0, &rfds) będzie prawdziwy. */
    else
        printf("Brak danych w ciągu pięciu sekund.\[rs]n");
\&
    exit(EXIT_SUCCESS);
}
.EE
.\" SRC END
.SH "ZOBACZ TAKŻE"
\fBaccept\fP(2), \fBconnect\fP(2), \fBpoll\fP(2), \fBread\fP(2), \fBrecv\fP(2),
\fBrestart_syscall\fP(2), \fBsend\fP(2), \fBsigprocmask\fP(2), \fBwrite\fP(2),
\fBtimespec\fP(3), \fBepoll\fP(7), \fBtime\fP(7)
.P
Samouczek z dyskusją i przykładami znajduje się w \fBselect_tut\fP(2).
.PP
.SH TŁUMACZENIE
Autorami polskiego tłumaczenia niniejszej strony podręcznika są:
Przemek Borys <pborys@dione.ids.pl>,
Robert Luberda <robert@debian.org>
i
Michał Kułach <michal.kulach@gmail.com>
.
.PP
Niniejsze tłumaczenie jest wolną dokumentacją. Bliższe informacje o warunkach
licencji można uzyskać zapoznając się z
.UR https://www.gnu.org/licenses/gpl-3.0.html
GNU General Public License w wersji 3
.UE
lub nowszej. Nie przyjmuje się ŻADNEJ ODPOWIEDZIALNOŚCI.
.PP
Błędy w tłumaczeniu strony podręcznika prosimy zgłaszać na adres listy
dyskusyjnej
.MT manpages-pl-list@lists.sourceforge.net
.ME .