Schnellreferenz

In diesem Kapitel wurden die folgenden Symbole und Header-Dateien eingeführt:

#include <linux/ioctl.h>

Diese Header-Datei deklariert alle Makros, die man zur Definition von ioctl-Befehlen benötigt. Sie wird derzeit von <linux/fs.h> eingebunden.

_IOC_NRBITS, _IOC_TYPEBITS, _IOC_SIZEBITS, _IOC_DIRBITS

Die Anzahl der Bits, die in den verschiedenen Bitfeldern der ioctl-Befehle zur Verfügung stehen. Außerdem gibt es vier Makros, die die MASKen, und vier, die die SHIFTs angeben. Diese sind allerdings hauptsächlich zum internen Gebrauch gedacht. _IOC_SIZEBITS ist ein wichtiger Wert, den es zu überprüfen gilt, weil er in unterschiedlichen Architekturen unterschiedlich ist.

_IOC_NONE, _IOC_READ, _IOC_WRITE

Die möglichen Werte für das “direction”-Bitfeld. Zum Lesen und Schreiben gibt es verschiedene Bits, die ODER-verknüpft werden können, um gleichzeitigen Lese- und Schreibzugriff anzuzeigen. Die Werte sind 0-basiert.

_IOC(dir,type,nr,size), _IO(type,nr), _IOR(type,nr,size), _IOW(type,nr,size), _IOWR(type,nr,size)

Makros, mit denen ein ioctl-Befehl erzeugt werden kann.

_IOC_DIR(nr), _IOC_TYPE(nr), _IOC_NR(nr), _IOC_SIZE(nr)

Makros, die zum Decodieren eines Befehls verwendet werden. _IOC_TYPE(nr) ist eine ODER-Kombination aus IOC_READ und _IOC_WRITE.

#include <asm/uaccess.h>, int access_ok(int type, const void *addr, unsigned long size);

Diese Funktion überprüft, ob ein Zeiger in den User-Space auch wirklich verwendet werden kann. access_ok gibt einen von Null verschiedenen Wert zurück, wenn der Zugriff erlaubt ist.

VERIFY_READ, VERIFY_WRITE

Die möglichen Werte für das mode-Argument in access_ok. VERIFY_WRITE ist eine Obermenge von VERIFY_READ.

#include <asm/uaccess.h>, int put_user(datum,ptr);, int get_user(ptr);, int __put_user(datum,ptr);, int __get_user(ptr);

Makros, mit denen ein einzelnes Datum in den User-Space geschrieben oder von dort gelesen werden kann. Die Anzahl der übertragenen Bytes hängt von sizeof(*ptr) ab. Die normalen Versionen rufen zunächst access_ok auf, während die Versionen mit den Unterstrichen vorweg annehmen, daß access_ok bereits aufgerufen worden ist.

#include <linux/capability.h>

Definiert die diversen CAP_-Symbole für Capabilities ab Linux 2.2.

int capable(int capability);

Gibt einen von Null verschiedenen Wert zurück, wenn der Prozeß die angegebene Capability hat.

#include <linux/wait.h>, typedef struct { /* ... */ } wait_queue_head_t;, void init_waitqueue_head(wait_queue_head_t *queue);, DECLARE_WAIT_QUEUE_HEAD(queue);

Der definierte Typ für Linux-Warteschlangen. Ein wait_queue_head_t muß explizit initialisiert werden; entweder mit init_waitqueue_head zur Laufzeit oder mit declare_wait_queue_head zur Kompilierzeit.

#include <linux/sched.h>, void interruptible_sleep_on(struct wait_queue **q);, void sleep_on(struct wait_queue **q);, void interruptible_sleep_on_timeout(wait_queue_head_t *q, long timeout);, void sleep_on_timeout(wait_queue_head_t *q, long timeout);

Rufen Sie eine dieser Funktionen auf, um den aktuellen Prozeß in einer Warteschlange schlafen zu legen. Normalerweise werden Sie die interruptible-Form verwenden, um blockierendes Lesen oder Schreiben zu implementieren.

void wake_up(struct wait_queue **q);, void wake_up_interruptible(struct wait_queue **q);, void wake_up_sync(struct wait_queue **q);, void wake_up_interruptible_sync(struct wait_queue **q);

Diese Funktionen wecken Prozesse, die gerade in der Warteschlange q schlafen. Die interruptible-Form weckt nur unterbrechbare Prozesse auf. Die _sync-Versionen rufen den Scheduler vor dem Rücksprung nicht auf.

typedef struct { /* ... */ } wait_queue_t;, init_waitqueue_entry(wait_queue_t *entry, struct task_struct *task);

Der Typ wait_queue_t wird verwendet, wenn ohne Aufruf von sleep_on geschlafen wird. Warteschlangen-Einträge müssen immer vor ihrer Verwendung initialisiert werden; das Argument task ist fast immer current.

void add_wait_queue(wait_queue_head_t *q, wait_queue_t *wait);, void add_wait_queue_exclusive(wait_queue_head_t *q, wait_queue_t *wait);, void remove_wait_queue(wait_queue_head_t *q, wait_queue_t *wait);

Diese Funktionen fügen einen Eintrag zu einer Warteschlange hinzu; add_wait_queue_exclusive hängt den Eintrag am Ende der Schlange an (für exklusives Warten). Einträge sollten nach dem Schlafen mit remove_wait_queue entfernt werden.

void wait_event(wait_queue_head_t q, int condition);, int wait_event_interruptible(wait_queue_head_t q, int condition);

Diese beiden Makros legen den Prozeß so lange in der angegebenen Warteschlange schlafen, bis die angegebene Bedingung condition zu true evaluiert.

void schedule(void);

Diese Funktion wählt einen Prozeß aus der Schlange der startbereiten Prozesse aus. Der gewählte Prozeß kann entweder current oder ein anderer sein. Normalerweise müssen Sie schedule nicht direkt aufrufen, weil die sleep_on-Funktionen das schon intern selbst machen.

#include <linux/poll.h>, void poll_wait(struct file *filp, wait_queue_head_t *q, poll_table *p)

Diese Funktion stellt den aktuellen Prozeß in eine Warteschlange, ohne direkt die Auswahl eines neuen Prozesses zu veranlassen. Sie ist für die Verwendung in poll-Methoden von Gerätetreibern gedacht.

int fasync_helper(struct inode *inode, struct file *filp, int mode, struct fasync_struct **fa);

Diese Funktion ist eine “Hilfsfunktion” für die Implementierung der Geräte-Methode fasync. Das mode-Argument ist der gleiche Wert wie der, der an die Methode übergeben wurde; fa zeigt auf eine gerätespezifische fasync_struct *.

void kill_fasync(struct fasync_struct *fa, int sig, int band);

Wenn der Treiber die asynchrone Benachrichtigung unterstützt, dann kann diese Funktion dazu verwendet werden, um an die in fa registrierten Prozesse ein Signal zu schicken.

#include <linux/spinlock.h>, typedef struct { /* ... */ } spinlock_t;, void spin_lock_init(spinlock_t *lock);

Der Typ spinlock_t definiert ein Spinlock, das vor der Verwendung mit spin_lock_init initialisiert werden muß.

spin_lock(spinlock_t *lock);, spin_unlock(spinlock_t *lock);

spin_lock sperrt die angegebene Sperre und wartet gegebenenfalls, bis sie verfügbar wird. Die Sperre kann dann mit spin_unlock wieder freigegeben werden.