int fcntl(int fildes, int cmd, ...);
Mit der Funktion fcntl()werden Optionen oder Operationen auf einer geöffneten Datei durchgeführt. Beispielsweise kann eine Datei für einen Prozess blockiert werden, um dass gemeinsame Schreiben zweier Prozesse zu verhindern. Der Funktion wird als Parameter fildes der Datei-Deskriptor übergeben, bei dem ein Kommando ausgeführt werden soll. Das Kommando wird mittels des Parameters cmd angegeben. Benötigt das Kommando Parameter, so werden sie zusätzlich angegeben. Der Rückgabewert liefert das Ergebnis des Kommandos. Da Sockets auch wie Dateien behandelt werden, bietet die Funktion fcntl() auch Optionen für Sockets. Eine dieser Optionen ist, ob der Socket im blockierenden oder nicht-blockierenden Modus arbeitet:
- Blockierend
In diesem Fall wird der gerade laufende Prozess unterbrochen, wenn auf das Ende einer Funktion zur Bearbeitung eines Sockets gewartet werden muss. Wenn z. B. keine Daten für den Empfang bereit stehen, wird der aufrufende Prozess der recv()-Funktion unterbrochen bis Daten empfangen werden. Innerhalb dieser Zeit kann der Prozess keine weiteren Aktionen durchführen. Dies ist die Grundeinstellung, wenn ein Socket erzeugt wird. - Nicht-Blockierend
Um zu verhindern, dass bei einem Aufruf einer Socket-Funktion der gerade laufende Prozess unterbrochen wird, kann der Socket in den nicht-blockierenden Modus versetzt werden. In diesem Modus wird die gerade ausgeführte Socket-Funktion abgebrochen bzw. beendet, ohne dass der laufende Prozess vertagt wird. Wenn keine Daten zum Empfang bereitstehen, wird die recv()-Funktion mit einer Fehlermeldung abgebrochen. Dies hat den Vorteil, dass der laufende Prozess andere Aufgaben durchführen kann, während auf Daten gewartet wird. Erst wenn Daten zum Empfang vorhanden sind, würde beispielsweise der Aufruf der Funktion zu einem positiven Ergebnis führen.
Das folgende Beispiel zeigt, wie ein Socket in den nicht-blockierenden Mode versetzt wird.
/* zuerst wird mit dem Kommando F_GETFL ermittelt welche Eigenschaften die Datei hat. */ int flags = fcntl(fd, F_GETFL, 0); /* anschließend wird der Socket in den nicht blockierenden Mode versetzt*/ fcntl(fd, F_SETFL, flags | O_NONBLOCK);