#include <sys.time.h>
#include <sys.socket.h>
Kernighan-Ritchie-C:
int select(nfds, readfds, writefds, exceptfds, timeout);
int nfds;
fd_set *readfds, *writefds, *exceptfds;
struct timeval *timeout;
FD_SET(fd, &fdset);
FD_CLR(fd, &fdset);
FD_ISSET(fd, &fdset);
FD_ZERO(&fdset);
int fd;
fd_set fdset;
ANSI-C:
int select(int nfds, fd_set* readfds, fd_set* writefds, fd_set* exceptfds,
struct timeval* timeout);
FD_SET(fd, &fdset);
FD_CLR(fd, &fdset);
FD_ISSET(fd, &fdset);
FD_ZERO(&fdset);
int fd;
fd_set fdset;
Beschreibung
Die Funktion select() überprüft drei verschiedene Mengen von Socket-Deskriptoren, die mit den Parametern readfds, writefds und exceptfds übergeben werden. select() stellt dabei fest,
welche Deskriptoren der mit readfds übergebenen Menge bereit zum Lesen sind,
welche Deskriptoren der mit writefds übergebenen Menge bereit zum Schreiben sind,
für welche Deskriptoren der mit exceptfds übergebenen Menge eine noch nicht ausgewertete Ausnahmebedingung vorliegt.
Der Parameter exceptfds wird von SOCKETS(BS2000) derzeit nicht ausgewertet.
Die Bitmasken zu den einzelnen Deskriptormengen werden als Bitfelder in Integer-Reihungen abgespeichert. Die maximale Größe der Bitfelder ermitteln Sie mit der Funktion getdtablesize() (siehe Abschnitt "getdtablesize() - Größe der Deskriptortabelle abfragen"). Der benötigte Speicher sollte dynamisch vom System angefordert werden.
Der Parameter nfds gibt an, wie viele Bits in jeder Bitmaske zu prüfen sind. select() prüft in den einzelnen Bitmasken die Bits 0 bis nfds-1.
select() ersetzt die beim Aufruf übergebenen Deskriptormengen durch entsprechende Untermengen. Diese Untermengen enthalten jeweils alle Deskriptoren, die für die betreffende Operation bereit sind.
Mit den folgenden Makros kann der Benutzer Bitmasken bzw. Deskriptormengen manipulieren:
FD_SET(fd, &fdset)
erweitert die Deskriptormenge fdset um den Deskriptor fd.
FD_CLR(fd, &fdset)
entfernt den Deskriptor fd aus der Deskriptormenge fdset.
FD_ISSET(fd, &fdset)
prüft, ob der Deskriptor fd ein Element der Deskriptormenge fdset ist:
Rückgabewert !=0:
Rückgabewert =0:
FD_ZERO(&fdset)
entfernt alle Deskriptoren aus der Deskriptormenge fdset.
Das Verhalten dieser Makros ist undefiniert, wenn der Deskriptor-Wert kleiner als 0 oder größer als die mit getdtablesize() ermittelte maximale Größe für die Bitfelder ist.
Der Parameter timeout legt die maximale Zeitspanne fest, die der Funktion select() für die vollständige Auswahl der bereiten Deskriptoren zur Verfügung steht. Wenn timeout der Null-Zeiger ist, blockiert select() auf unbestimmte Zeit. Die maximale Zeitspanne, die akzeptiert wird, beträgt ~ 24,85 Tage. Bei einem größeren Wert wird solange gewartet, bis ein Ereignis eintritt.
Ein zyklisches Auswählen (Polling) können Sie veranlassen, wenn Sie für timeout einen Zeiger auf ein timeval-Objekt übergeben, dessen Komponenten sämtlich den Wert 0 haben.
Wenn die Deskriptoren nicht von Interesse sind, kann als aktueller Parameter für readfds, writefds und exceptfds der Null-Zeiger übergeben werden.
Stellt select() nach einem Aufruf von listen() die Lesebereitschaft eines Socket-Deskriptors fest, so zeigt dies an, dass ein folgender accept()-Aufruf für diesen Deskriptor nicht blockieren wird.
Returnwert
>0:
Der positive Wert gibt die Anzahl der bereiten Deskriptoren in den Deskriptormengen an.
0:
gibt an, dass das Timeout-Limit überschritten wurde. Die Deskriptormengen sind dann undefiniert.
-1:
bei Fehler. errno wird gesetzt, um den Fehler anzuzeigen. Die Deskriptormengen sind dann undefiniert.
7F000000:
Trace-Event für User-Sockets-Trace
Fehleranzeige durch
errno
EBADF
Eine der Deskriptormengen spezifiziert einen ungültigen Deskriptor.
EINTR
Der select()-Aufruf wurde von soc_wake() unterbrochen.
ENETDOWN
Die Verbindung zum Netzwerk ist nicht mehr aktiv.
Wenn virtuelle Hosts genutzt werden, hat ENETDOWN nicht unbedingt die Bedeutung, dass das gesamte Netzwerk ausgefallen ist. Es kann auch bedeuten, dass nur das Netzwerk eines virtuellen Hosts ausgefallen ist.
Hinweis
Unter seltenen Umständen kann select() anzeigen, dass ein Deskriptor bereit zum Schreiben ist, während ein Schreibversuch tatsächlich aber blockieren würde. Das kann vorkommen, wenn für das Schreiben notwendige System-Ressourcen erschöpft oder nicht vorhanden sind. Wenn es für die Anwendung kritisch ist, dass Schreiboperationen auf einen Datei-Deskriptor nicht blockieren, sollte der Benutzer den Deskriptor mit einem soc_ioctl()-Aufruf auf nicht-blockierende Ein-/Ausgabe setzen.
Siehe auch
accept(), connect(), listen(), recv(), send(), soc_ioctl(), soc_write(), soc_writev()