Provided by:
manpages-de-dev_0.10-1_all 
BEZEICHNUNG
select, pselect, FD_CLR, FD_ISSET, FD_SET, FD_ZERO - Synchrone I/O-
Multiplexsteuerung
Diese Handbuchseite ist eventuell veraltet. Im Zweifelsfall ziehen Sie
die englischsprachige Handbuchseite zu Rate, indem Sie
man -LC 2 select
eingeben.
"UBERSICHT
#include <sys/time.h>
#include <sys/types.h>
#include <unistd.h>
int select(int n, fd_set *readfds, fd_set *writefds, fd_set *exceptfds,
struct timeval *timeout);
int pselect(int n, fd_set *readfds, fd_set *writefds, fd_set
*exceptfds, const struct timespec *timeout, sigset_t *sigmask);
FD_CLR(int fd, fd_set *set);
FD_ISSET(int fd, fd_set *set);
FD_SET(int fd, fd_set *set);
FD_ZERO(fd_set *set);
BESCHREIBUNG
Die Funktionen select und pselect uberwachen den Dateistatus fur eine
Reihe von Datei-Deskriptoren.
Die Funktionsweise der beiden Varianten ist identisch, abgesehen von
drei Unterschieden:
(i) The select-Funktion verwendet zur Angabe von Zeitlimits eine
Struktur vom Typ struct timeval (mit Sekunden und
Mikrosekunden), pselect hingegen den Typ struct timespec (mit
Sekunden und Nanosekunden). Die Strukturen sind uber
/usr/include/sys/time.h definiert als:
struct timeval {
long tv_sec; /* Sekunden */
long tv_usec; /* Mikrosekunden */
};
und
struct timespec {
long tv_sec; /* Sekunden */
long tv_nsec; /* Nanosekunden */
};
(ii) Wahrend select den Parameter timeout mitunter verandert, um
anzuzeigen, wie viel Zeit des Limits noch verblieben ist, lasst
pselect den Wert immer unverandert.
(iii) Die select-Funktion besitzt keinen sigmask-Parameter und verhalt
sich wie pselect, das mit einer sigmask von NULL aufgerufen
wurde.
Es werden drei voneinander unabhangige Mengen von Deskriptoren
behandelt. Bei den in readfds enthaltenen wird darauf geachtet, ob
neue Zeichen zum Lesen ankommen. (Genauer, es wird kontrolliert, ob
ein nachfolgender read-Systemaufruf sofort zuruckkehren wurde. Diese
Bedingung ist insbesondere auch dann erfullt, wenn der Deskriptor auf
das Dateiende verweist.) Bei den in writefds angegebenen Deskriptoren
wird reagiert, wenn weitere Zeichen geschrieben werden konnen, und bei
den in exceptfds angegebenen Deskriptoren, wenn etwas auBergewohnliches
passiert ist. Kehrt der Systemaufruf zuruck, sind die ubergebenen
Mengen so verandert, dass sie anzeigen, welcher Deskriptor seinen
Status geandert hat.
Vier Makros stehen bereit, um mit diesen Mengen zu arbeiten. FD_ZERO
loscht eine Menge, FD_SET und FD_CLR fugen einen Deskriptor zur Menge
hinzu bzw. loschen diesen, FD_ISSET pruft, ob der Deskriptor in der
Menge enthalten ist. Das ist insbesondere nach einem select- oder
pselect-Aufruf sinnvoll.
n entspricht der Zahl des am hochsten nummerierten Datei-Deskriptors in
allen drei Mengen, plus 1.
timeout gibt ein Zeitlimit an, das select und pselect maximal
verstreichen lassen, bevor sie zuruckkehren. Ist das Zeitlimit null,
so kehren die Funktionen sofort zuruck. Besitzt timeout selbst den
Wert NULL, so wird kein Limit gesetzt, und die Funktionen konnen
unendlich lange blockieren.
sigmask ist entweder NULL oder ein Zeiger auf eine Signalmaske wie in
sigprocmask(2) beschrieben. Im zweiten Fall ersetzt pselect die
aktuelle Signalmaske durch sigmask, fuhrt dann den select-Aufruf aus
und stellt anschlieBend die ursprungliche Maske wieder her.
Die Idee hinter pselect geht zuruck auf folgende Situation: Ein
Programm wartet gleichzeitig auf ein Signal oder eine Veranderung an
einem Datei-Deskriptor. Trifft das Signal ein, so setzt der
Signalhandler eine globale Variable. Im Hauptprogramm wird zunachst
getestet, ob die Variable gesetzt ist und andernfalls ein select-Aufruf
gestartet. Trifft das Signal zwischen dem Test und dem select-Aufruf
ein, so kann das dazu fuhren, dass das Programm nicht mehr beendet
wird. pselect hingegen erlaubt es, diese so genannte Race Condition zu
umgehen, indem das Signal zunachst geblockt, getestet und erst
unmittelbar mit dem select-Aufruf wieder freigegeben wird. Da der
Linux-Kernel bislang keinen speziellen pselect-Systemaufruf bereit
stellt, muss die aktuelle glibc2 ihn durch mehrere Aufrufe emulieren.
Die Fehlerquelle ist daher auch mit pselect nach wie vor vorhanden.
R"UCKGABEWERTE
Bei Erfolg geben select und pselect die Anzahl der Deskriptoren zuruck,
deren Status sich geandert hat. Der Ruckgabewert kann auch null sein,
wenn das Zeitlimit erreicht wurde, bevor etwas interessantes passiert
ist. Wenn ein Fehler aufgetreten ist, wird -1 zuruckgegeben und errno
entsprechend gesetzt. Die Mengen und timeout befinden sich dann in
einem undefinierten Zustand. Auf ihren Inhalt sollte man sich folglich
bei einem Fehler nicht mehr verlassen.
FEHLER
EBADF In einer der Mengen wurde ein ungultiger Datei-Deskriptor
angegeben.
EINTR Ein nicht-blockiertes Signal wurde empfangen.
EINVAL n ist negativ.
ENOMEM select war nicht in der Lage, Speicher fur die internen
Tabellen zu bekommen.
ANMERKUNGEN
Einige Programme rufen select mit drei leeren Mengen, n gleich null und
einem von null verschiedenen timeout auf, um eine portable Moglichkeit
zu haben, ein sleep mit der Prazision von Bruchteilen einer Sekunde zu
benutzen.
Bei Linux wird timeout derart verandert, dass es dem noch nicht
verstrichenen Teil des Zeitlimits entspricht. Die meisten
Implementierungen anderer Betriebssysteme unterlassen dies. Das bringt
Probleme mit sich, wenn unter Linux geschriebener Quellcode, der
timeout auswertet, auf andere Betriebssysteme portiert wird, und wenn
Quellcode von anderen Betriebssystemen auf Linux portiert wird, der das
struct timeval fur mehrere selects in einer Schleife verwendet, ohne
ihn jedesmal neu zu initialisieren. Portabler Code sollte daher
annehmen, dass timeout undefiniert ist, nachdem select beendet wurde.
Wenn der einzige Schreiber eine Named-Pipe geschlossen hat, kehrt
select zuruck und signalisiert, dass etwas von der Pipe gelesen werden
kann. Ein anschlieBender read-Aufruf liefert jedoch null zuruck, da
das Dateiende erreicht ist. Code, der annimmt, dass select in diesem
Fall blockiert, sollte die Pipe mit O_RDWR statt O_RDONLY offnen.
BEISPIEL
#include <stdio.h>
#include <sys/time.h>
#include <sys/types.h>
#include <unistd.h>
int main(void)
{
fd_set rfds;
struct timeval tv;
int retval;
/* Achte auf stdin (fd 0), um zu sehen, wenn es
* Eingaben gibt.
*/
FD_ZERO(&rfds);
FD_SET(0, &rfds);
/* Warte bis zu funf Sekunden. */
tv.tv_sec = 5;
tv.tv_usec = 0;
retval = select(1, &rfds, NULL, NULL, &tv);
/* VerlaB Dich jetzt bloB nicht auf den Wert von tv! */
if (retval)
printf("Daten sind jetzt da.\n");
/* FD_ISSET(0, &rfds) musste jetzt true sein. */
else
printf("Keine Dateien innerhalb von funf Sekunden.\n");
exit(0);
}
KONFORM ZU
4.4BSD. (Die select-Funktion trat das erste Mal in 4.2BSD auf.)
Gewohnlich auch portierbar auf Nicht-BSD-Systeme (System V-Varianten
eingeschlossen), die eine Schnittstelle vom Typ des BSD-Socketlayers
unterstutzen. Zu beachten ist jedoch, dass die System V-Varianten
typischerweise die timeout-Variable vor der Ruckkehr setzen. Bei den
BSD-Varianten ist das nicht ublich.
Die pselect-Funktion ist in IEEE Std 1003.1g-2000 (POSIX.1g) definiert.
Sie ist seit glibc2.1 implementiert. Auch glibc2.0 besitzt eine
Funktion dieses Namens, die jedoch keinen Parameter sigmask verwendet.
SIEHE AUCH
accept(2), connect(2), poll(2), read(2), recv(2), send(2),
sigprocmask(2), write(2).