2014-07-04 7 views
8

Ich entwerfe einen Linux-Zeichengerätetreiber. Ich möchte Errno setzen, wenn Fehler in ioctl() Systemaufruf auftritt.Wie errno in Linux-Gerätetreiber festlegen?

long my_own_ioctl(struct file *file, unsigned int req, unsigned long arg) 
{ 
    long ret = 0; 
    BOOL isErr = FALSE; 

    // some operation 
    // ... 

    if (isErr) { 
     // set errno 
     // ...     <--- What should I do? 
     ret = -1; 
    } 

    return ret; 
} 

Was soll ich tun, um das zu erreichen? Danke im Voraus!


Bitte erlauben Sie mir, meine Anwendung mit mehr Details zu erklären.

Mein Gerät befindet sich in/dev/myCharDev. Meine Userspace-Anwendung ist wie folgt:

#define _COMMAND     (1) 
#define _ERROR_COMMAND_PARAMETER (-1) 

int main() 
{ 
    int fd = open("/dev/myCharDec", O_RDONLY); 
    int errnoCopy; 

    if (fd) { 
     if (ioctl(fd, _COMMAND, _ERROR_COMMAND_PARAMETER) < 0) {  // should cause error in ioctl() 
      errnoCopy = errno; 
      printf("Oops, error occurred: %s\n", strerr(errnoCopy)); // I want this "errno" printed correctly 
     } 

     close(fd); 
    } 

    return 0; 
} 

Wie ich oben in den Kommentaren erwähnt, Wie soll ich die „errno“ gesetzt in meinem eigenen Gerätetreiber-Codes und durch Userspace-Applikation lesbar machen?

Antwort

9

Nette Frage!

Ok, du könntest errno als globale Variable vorstellen (um ehrlich zu sein, es ist ein externer int). errno hat viele vordefinierte Makros für Fehlercodes in der Bibliothek errno.h. Sie können einen Blick auf here werfen. Es ist sehr wahrscheinlich, dass einige dieser Fehlercodes beschreiben, was Sie zeigen möchten. Nimm das richtige auf, setze es so, als ob es eine von dir definierte Variable wäre, und (wichtig!) Verlasse es sofort!

Sie können sich fragen, ob die Einstellung errno der richtige Ansatz für Ihr Problem ist. Sie können immer ein (* int) definieren und eigene Fehlercodes und Fehlerbehandlungsmechanismen entwickeln. Errno dient dazu, Systemfehler zu zeigen und zu erklären. Betrachten Sie Ihren Code als Teil des "Systems" (wie ich sehe, entwickeln Sie Ihren eigenen Systemanruf, so könnte dies der Fall sein)? Also mach weiter und benutze errno um deinen "Systemfehler" zu erklären.

Edit (Auf Frage Update): Ok mehr Infos. Wie gesagt, errno ist ein externes int und wird vom Kernel gesetzt. Der Wert, bei dem errno gesetzt ist, ist einfach der Rückgabewert des Systemaufrufs. Der Linux-Kernel interpretiert diesen negativen Wert dann über die Bibliothek errno.h. Daher wird eine Beispielfehlermeldung einfach dadurch gesetzt, dass (die EBUSY ist nur ein Beispiel - Sie können alle vordefinierten Fehlertypen verwenden) die Fehlermeldung zurückgegeben wird, die Sie von Ihrem Systemaufruf erhalten möchten. Beispiel:

return -EBUSY 

Hoffe, dass es

+0

Ich füge eine Erklärung in meine Frage. –

+0

@AndrewChang hat meine Antwort aktualisiert – sestus

+0

Schön, danke !!! –

0
if (isErr) 
    { 
     printk(KERN_ALERT "Error %d: your description\n", errno); 
     ret = errno; 
    } 

hilft, wo errno ist der Rückgabewert einer Funktion.

Ihr Gerätetreiber sollte immer einen Status für eine empfangene Anforderung zurückgeben. Es wird empfohlen, dass Sie immer nummerierte Rückgabecodes sowie normale Rückgabecodes verwenden. Die Rückgabe von 0 = bestanden 1 oder -1 = fehlgeschlagen ist vage und könnte irreführend sein.

lesen Abschnitt 3.1 Efficient error handling, reporting and recovery: für weitere Informationen

+0

Wie ich es bekomme, will er Fehler erzeugen, und errno entsprechend setzen. Sie lesen gerade errno. Aber der Systemaufruf, den er entwickelt, setzt errno standardmäßig nicht. Er muss es einstellen. – sestus

+0

Ja, was ich gefragt habe, ist errno in "Gerätetreiber" anstelle von Benutzer-Space-Anwendungen zu setzen. –

6

Rückkehr der negative Fehlernummer der ioctl. Die c-Bibliothek interpretiert dies und gibt einen Rückgabecode von -1 zurück und setzt errno auf den positiven Fehler. Zum Beispiel wird Ihr ursprüngliches Beispiel errno auf 1 setzen.

Nebenbei sieht Ihr Prototyp für eine ioctl-Funktion im Kernel falsch aus. Welche Kernel-Version verwendest du?

+0

Vielen Dank! Ich kombiniere deine und Sestus 'Antworten und verstehe, was ich tun soll. Aber die Antwort von Sestus ist detaillierter. Schade, dass nur eine Antwort akzeptiert werden konnte. –