.\" This manpage is copyright (C) 1992 Drew Eckhardt, .\" copyright (C) 1995 Michael Shields. .\" .\" %%%LICENSE_START(VERBATIM) .\" Permission is granted to make and distribute verbatim copies of this .\" manual provided the copyright notice and this permission notice are .\" preserved on all copies. .\" .\" Permission is granted to copy and distribute modified versions of this .\" manual under the conditions for verbatim copying, provided that the .\" entire resulting derived work is distributed under the terms of a .\" permission notice identical to this one. .\" .\" Since the Linux kernel and libraries are constantly changing, this .\" manual page may be incorrect or out-of-date. The author(s) assume no .\" responsibility for errors or omissions, or for damages resulting from .\" the use of the information contained herein. The author(s) may not .\" have taken the same level of care in the production of this manual, .\" which is licensed free of charge, as they might when working .\" professionally. .\" .\" Formatted or processed versions of this manual, if unaccompanied by .\" the source, must acknowledge the copyright and authors of this work. .\" %%%LICENSE_END .\" .\" Modified 1993-07-24 by Rik Faith .\" Modified 1995-05-18 by Jim Van Zandt .\" Sun Feb 11 14:07:00 MET 1996 Martin Schulze .\" * layout slightly modified .\" .\" Modified Mon Oct 21 23:05:29 EDT 1996 by Eric S. Raymond .\" Modified Thu Feb 24 01:41:09 CET 2000 by aeb .\" Modified Thu Feb 9 22:32:09 CET 2001 by bert hubert , aeb .\" Modified Mon Nov 11 14:35:00 PST 2002 by Ben Woodard .\" 2005-03-11, mtk, modified pselect() text (it is now a system .\" call in 2.6.16. .\" .\"******************************************************************* .\" .\" This file was generated with po4a. Translate the source file. .\" .\"******************************************************************* .\" This file is distributed under the same license as original manpage .\" Copyright of the original manpage: .\" Copyright © 1992 Drew Eckhardt, 1995 Michael Shields .\" Copyright © of Polish translation: .\" Przemek Borys (PTM) , 1999. .\" Robert Luberda , 2006, 2012, 2013. .\" Michał Kułach , 2013, 2014, 2016. .TH SELECT 2 2016\-03\-15 Linux "Podręcznik programisty Linuksa" .SH NAZWA select, pselect, FD_CLR, FD_ISSET, FD_SET, FD_ZERO \- synchroniczne zwielokrotnianie wejście/wyjście .SH SKŁADNIA .nf /* Zgodnie z POSIX.1\-2001, POSIX.1\-2008 */ .br \fB#include \fP .sp /* Zgodnie z wcześniejszymi standardami */ .br \fB#include \fP .br \fB#include \fP .br \fB#include \fP .sp \fBint select(int \fP\fInfds\fP\fB, fd_set *\fP\fIreadfds\fP\fB, fd_set *\fP\fIwritefds\fP\fB,\fP \fB fd_set *\fP\fIexceptfds\fP\fB, struct timeval *\fP\fItimeout\fP\fB);\fP .sp \fBvoid FD_CLR(int \fP\fIfd\fP\fB, fd_set *\fP\fIset\fP\fB);\fP .br \fBint FD_ISSET(int \fP\fIfd\fP\fB, fd_set *\fP\fIset\fP\fB);\fP .br \fBvoid FD_SET(int \fP\fIfd\fP\fB, fd_set *\fP\fIset\fP\fB);\fP .br \fBvoid FD_ZERO(fd_set *\fP\fIset\fP\fB);\fP .sp \fB#include \fP .sp \fBint pselect(int \fP\fInfds\fP\fB, fd_set *\fP\fIreadfds\fP\fB, fd_set *\fP\fIwritefds\fP\fB,\fP \fB fd_set *\fP\fIexceptfds\fP\fB, const struct timespec *\fP\fItimeout\fP\fB,\fP \fB const sigset_t *\fP\fIsigmask\fP\fB);\fP .fi .sp .in -4n Wymagane ustawienia makr biblioteki glibc (patrz \fBfeature_test_macros\fP(7)): .in .sp \fBpselect\fP(): _POSIX_C_SOURCE\ >=\ 200112L .SH OPIS \fBselect\fP() i \fBpselect\fP() umożliwiają programowi monitorowanie wielu deskryptorów plików i oczekiwanie aż jeden lub więcej deskryptorów będzie "gotowy" 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) bez blokowania lub odpowiednio małe \fBwrite\fP(2)). .PP \fBselect\fP() może monitorować wyłącznie numery deskryptorów plików mniejsze niż \fBFD_SETSIZE\fP; \fBpoll\fP(2) nie posiada tego ograniczenia. Zob. BŁĘDY. .PP Funkcjonalność funkcji \fBselect\fP() i \fBpselect\fP() jest identyczna, jeśli pominąć trzy różnice: .TP (i) 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). .TP (ii) Funkcja \fBselect\fP() może aktualizować parametr \fItimeout\fP, aby wskazać, jak dużo czasu minęło. Funkcja \fBpselect\fP() nie zmienia tego parametru. .TP (iii) Funkcja \fBselect\fP() nie przyjmuje parametru \fIsigmask\fP i zachowuje się, jak \fBpselect\fP() wywołane z NULL\-em przekazanym w \fIsigmask\fP. .PP Podglądane są trzy niezależne zestawy deskryptorów. Te, które są wymienione w \fIreadfds\fP, będą obserwowane w celu dowiedzenia się, czy nie ma tam jakichś znaków dostępnych do czytania (dokładniej, aby dowiedzieć się, czy read nie spowoduje zablokowania, deskryptor pliku jest również przygotowany na koniec pliku). Deskryptory wymienione w \fIwritefds\fP będą obserwowane w celu dowiedzenia się, czy jest dostępna przestrzeń do zapisu (choć duże zapisy wciąż mogą być blokowane), a deskryptory wymienione w \fIexceptfds\fP będą obserwowane w celu dowiedzenia się, czy nie ma na nich wyjątku. Przy wyjściu, zbiory te są modyfikowane, wskazując, które z deskryptorów zmieniły status. Każdy z tych trzech zbiorów deskryptorów plików może być przekazany jako NULL, jeżeli dla żadnego deskryptora pliku na ma potrzeby obserwowania odpowiedniej klasy zdarzeń. .PP Do obsługi tych zbiorów udostępnione są cztery makra: \fBFD_ZERO\fP() czyści zbiór; \fBFD_SET\fP() i \fBFD_CLR\fP() dodają lub usuwają ze zbioru podany deskryptor; \fBFD_ISSET\fP() sprawdza, czy deskryptor jest częścią zbioru. Jest to przydatne po zakończeniu \fBselect\fP(). .PP \fInfds\fP jest najwyższym numerem deskryptora z wszystkich trzech zbiorów plus 1. .PP Argument \fItimeout\fP określa interwał, który powinien blokować \fBselect\fP(), czekając na gotowość deskryptora plików. Wywołanie będzie skutkowało blokadą do momentu aż: .IP * 3 deskryptor pliku stanie się dostępny .IP * lub wywołanie zostanie przerwane procedurą obsługi sygnału .IP * albo wywołanie przeterminuje się .PP 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. Jeśli oba pola struktury \fItimeval\fP mają wartość zero, \fBselect\fP() zakończy pracę natychmiast jest to przydatne w uwspólnianiu). Jeśli \fItimeout\fP jest równe NULL (brak czasu przeterminowania), \fBselect\fP() może blokować w nieskończoność. .PP \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ę "select", a po jej zakończeniu odtwarza oryginalną maskę sygnałów. .PP Poza różnicą w precyzji argumentu \fItimeout\fP, następujące wywołanie \fBpselect\fP(): .nf ready = pselect(nfds, &readfds, &writefds, &exceptfds, timeout, &sigmask); .fi jest odpowiednikiem \fIniepodzielnego\fP wykonania następujących funkcji: .nf sigset_t origmask; pthread_sigmask(SIG_SETMASK, &sigmask, &origmask); ready = select(nfds, &readfds, &writefds, &exceptfds, timeout); pthread_sigmask(SIG_SETMASK, &origmask, NULL); .fi .PP 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 Struktury czasu, których to dotyczy, są zdefiniowane w \fI\fP i wyglądają następująco .in +4n .nf struct timeval { long tv_sec; /* sekundy */ long tv_usec; /* mikrosekundy */ }; .fi .in i .in +4n .nf struct timespec { long tv_sec; /* sekundy */ long tv_nsec; /* nanosekundy */ }; .fi .in (Jednakże zobacz poniżej uwagi dotyczące POSIX.1). .PP Niektóre programy wywołują \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ą. .PP .\" .PP - 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). Może ona być zerowa, jeśli nastąpi przeterminowanie, nim coś ciekawego się zdarzy. Po błędzie, zwracane jest \-1 i odpowiednio ustawiane \fIerrno\fP aby wskazać 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). .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 \fBpselect\fP() został dodany w wersji 2.6.16 jądra Linuksa. Wcześniej \fBpselect\fP() był emulowany w glibc (patrz również BŁĘDY IMPLEMENTACJI). .SH "ZGODNE Z" \fBselect\fP() jest zgodny z POSIX.1\-2001, POSIX.1\-2008 i BSD 4.4 (funkcja \fBselect\fP() pojawiła się pierwotnie w BSD 4.2). 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ą timeout przed zakończeniem, ale wariant BSD tego nie robi. .PP \fBpselect\fP() jest zdefiniowany w POSIX.1g, w POSIX.1\-2001 i w POSIX.1\-2008. .SH UWAGI \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. .\" 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. Jeśli chodzi o używane typy, klasyczna sytuacja polega na tym, że oba pola struktury \fItimeval\fP są typu \fIlong\fP (jak pokazano powyżej), a sama struktura jest zdefiniowana w \fI\fP. W POSIX.1 wygląda to następująco: .in +4n .nf struct timeval { time_t tv_sec; /* sekundy */ suseconds_t tv_usec; /* mikrosekundy */ }; .fi .in przy czym struktura jest zdefiniowana w \fI\fP, a typy \fItime_t\fP i \fIsuseconds_t\fP zdefiniowano w \fI\fP. .LP Jeśli chodzi o prototypy opisywanych funkcji, to klasyczna sytuacja polega na tym, że dla \fBselect\fP() należy włączyć \fI\fP, natomiast sytuacja z POSIX.1 polega na tym, że dla \fBselect\fP() i \fBpselect\fP() należy włączyć \fI\fP. W glibc 2.0 \fI\fP udostępnia bezwarunkowo błędny prototyp dla \fBpselect\fP(). W glibc 2.1 aż do 2.2.1 udostępnia on \fBpselect\fP(), jeżeli zdefiniowane jest \fB_GNU_SOURCE\fP. Od glibc 2.2.2 wymagania są takie, jak pokazano powyżej w rozdziale SKŁADNIA. .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 otwarty zostanie inny 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 zestawów do sprawdzenia z wartości \fInfds\fP. Jednak w implementacji glibc, typ \fIfd_set\fP ma stały rozmiar. Zob. też\ BŁĘDY. 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. 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. Ostatnim argumentem wywołania systemowego \fBpselect6\fP() nie jest wskaźnik \fIsigset_t\ *\fP lecz struktura postaci: .in +4 .nf struct { const sigset_t *ss; /* Pointer to signal set */ size_t ss_len; /* Size (in bytes) of object pointed to by 'ss' */ }; .fi .in 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. .SH "BŁĘDY IMPLEMENTACJI" POSIX pozwala implementacji zdefiniować górny limit zakresu deskryptorów plików, które można podać w zestawie 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). Glibc 2.0 dostarczała wersję \fBpselect\fP(), która nie przyjmowała argumentu \fIsigmask\fP. Od wersji 2.1 glibc dostarczał 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. 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 "potoku do siebie". 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. .\" 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? Pod Linuksem \fBselect\fP() może raportować deskryptory plików gniazd jako "dostępne do czytania", 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. 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ŁAD .nf #include #include #include #include #include int main(void) { fd_set rfds; struct timeval tv; int retval; /* Obserwacja stdin (fd 0) i sprawdzanie kiedy ma wejście. */ FD_ZERO(&rfds); FD_SET(0, &rfds); /* Czekanie nie dłużej niż 5 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.\en"); /* FD_ISSET(0, &rfds) będzie prawdziwy. */ else printf("Brak danych w ciągu 5 sekund.\en"); exit(EXIT_SUCCESS); } .fi .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), \fBepoll\fP(7), \fBtime\fP(7) Samouczek z dyskusją i przykładami znajduje się w \fBselect_tut\fP(2). .SH "O STRONIE" Angielska wersja tej strony pochodzi z wydania 4.07 projektu Linux \fIman\-pages\fP. Opis projektu, informacje dotyczące zgłaszania błędów, oraz najnowszą wersję oryginału można znaleźć pod adresem \%https://www.kernel.org/doc/man\-pages/. .SH TŁUMACZENIE Autorami polskiego tłumaczenia niniejszej strony podręcznika man są: Przemek Borys (PTM) , Robert Luberda i Michał Kułach . .PP Polskie tłumaczenie jest częścią projektu manpages-pl; uwagi, pomoc, zgłaszanie błędów na stronie http://sourceforge.net/projects/manpages-pl/. Jest zgodne z wersją \fB 4.07 \fPoryginału.