2014-07-04 14 views
8

Sto progettando un driver di dispositivo di carattere Linux. Voglio impostare errno quando si verifica un errore nella chiamata di sistema ioctl().Come impostare errno nel driver di periferica Linux?

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; 
} 

Cosa devo fare per raggiungere questo obiettivo? Grazie in anticipo!


Per favore permettimi di spiegare la mia domanda con maggiori dettagli.

Il mio dispositivo si trova in/dev/myCharDev. La mia applicazione utente è simile a questo:

#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; 
} 

Come ho già detto nei commenti di cui sopra, come devo impostare il "errno" nei miei propri codici dei driver di dispositivo e renderlo leggibile da applicazione utente?

risposta

9

Bella domanda!

Ok, si potrebbe pensare a errno come variabile globale (essere honnest, è un extern int). errno ha un sacco di macro predefinite per i codici di errore nella libreria errno.h. Puoi dare un'occhiata a here. È molto probabile che alcuni di questi codici di errore descrivano ciò che si desidera mostrare. Prendi quello giusto, impostalo come se fosse una variabile che hai definito e (importante!) Esci immediatamente!

È possibile chiedersi se impostare errno è l'approccio giusto al problema. È sempre possibile definire un (* int) e sviluppare i propri codici di errore e il meccanismo di gestione degli errori. Lo scopo di Errno è mostrare e spiegare gli errori di sistema. Considera il tuo codice parte del "sistema" (come posso vedere che sviluppi la tua propria chiamata di sistema, quindi potrebbe essere il caso)? Quindi vai avanti e usa errno per spiegare il tuo "errore di sistema".

Modifica (aggiornamento domanda): Ok maggiori informazioni. Come ho detto errno è un extern int ed è impostato dal kernel. Il valore al quale viene impostato errno è semplicemente il valore di ritorno della chiamata di sistema. Il kernel Linux interpreta quindi questo valore negativo attraverso la libreria errno.h. Quindi un messaggio di errore di esempio viene impostato semplicemente restituendo (EBUSY è solo un esempio - è possibile utilizzare tutti i tipi di errore predeterminati) il messaggio di errore che si desidera dalla chiamata di sistema. Esempio:

return -EBUSY 

Speranza che aiuta

+0

Aggiungo qualche spiegazione nella mia domanda. –

+0

@AndrewChang ha aggiornato la mia risposta – sestus

+0

Bello, grazie !!! –

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

dove, errno è il valore di ritorno di qualche funzione.

Il driver del dispositivo deve sempre restituire uno stato per una richiesta ricevuta. Si consiglia di utilizzare sempre codici di ritorno numerati e codici di ritorno normale . Restituire 0 = passare 1 o -1 = fallito è vago e potrebbe essere fuorviante.

Leggere il capitolo 3.1 Efficient error handling, reporting and recovery: per ulteriori informazioni

+0

Come ho capito, vuole generare errori e impostare errno di conseguenza. Hai appena letto errno. Ma la chiamata di sistema che sviluppa non imposta errno di default. Ha bisogno di impostarlo. – sestus

+0

Sì, quello che ho chiesto è di impostare errno in "driver di dispositivo" invece di applicazioni di spazio utente. –

6

Ritorna il numero di errore negativo dal ioctl. La libreria c interpreta questo e fornisce un codice di ritorno -1 e imposta errno all'errore positivo. Ad esempio, il tuo esempio originale imposterà errno a 1.

Per inciso, il tuo prototipo per una funzione ioctl nel kernel sembra sbagliato. Quale versione del kernel stai usando?

+0

Grazie! Combino le tue e le risposte di sestus e capisco cosa dovrei fare. Ma la risposta di sestus è più dettagliata. Che peccato che solo una risposta potesse essere accettata. –

Problemi correlati