2014-07-04 53 views
8

Linux karakter aygıtı sürücüsü tasarlıyorum. Ioctl() sistem çağrısında hata oluştuğunda errno ayarlamak istiyorum.Linux aygıt sürücüsünde errno nasıl ayarlanır?

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

Bunu başarmak için ne yapmalıyım? Şimdiden teşekkür ederim!


Lütfen uygulamamı daha ayrıntılı açıklamama izin verin.

Cihazım/dev/myCharDev konumunda bulunuyor. Benim kullanıcı uzay uygulama şu şekildedir:

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

yukarıdaki yorumlar belirtildiği gibi, nasıl kendi aygıt sürücüsü kodlarında "errno" olarak ayarlayın ve kullanıcı uzay uygulama tarafından okunabilir yapmalıdır?

cevap

9

Güzel soru! Tamam, errno'yu global değişken olarak düşünebilirsiniz (dürüst olmak gerekirse, bu bir extern int'dir.). errno, errno.h kitaplığındaki hata kodları için önceden tanımlı makrolar içerir. here'a bakabilirsiniz. Bu hata kodlarından bazılarının göstermek istediğiniz şeyi açıklaması çok olasıdır. Doğru olanı seçin, tanımladığınız bir değişken olsaydı, ve (önemli!) Hemen çıkın!

Sorun errno'nun probleminize doğru bir yaklaşım olup olmadığını kendinize sorabilirsiniz. Her zaman bir (* int) tanımlayabilir ve kendi hata kodlarınızı ve hata işleme mekanizmanızı geliştirebilirsiniz. Errno'nun amacı sistem hatalarını göstermek ve açıklamaktır. Kod bölümünüzü "sistem" olarak düşünün (kendi sistem çağrınızı geliştirdiğinizi görebildiğim gibi, bu durum böyle olabilir)? Bu yüzden devam edin ve "sistem hatasını" açıklamak için errno kullanın.

Düzenleme (On request update): Tamam daha fazla bilgi. Errno'nun bir extern int olduğunu ve çekirdeğin belirlediğini söylediğim gibi. Errno'nun ayarlandığı değer, sistem çağrısının sadece geri dönüş değeridir. Linux çekirdeği daha sonra bu negatif değeri errno.h kütüphanesi aracılığıyla yorumlar. Bu nedenle, bir örnek hata mesajı basitçe geri dönerek ayarlanır (EBUSY sadece bir örnektir - önceden tanımlanmış tüm hata türlerini kullanabilirsiniz) sistem çağrınızdan istediğiniz hata mesajını. Örnek:

return -EBUSY 

, bu

+0

Soruma bir açıklama ekledim. –

+0

@AndrewChang benim cevabımı – sestus

+0

güncellendi Nice, teşekkürler! –

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

yardımcı Umut errno bazı fonksiyonun dönüş değeridir.

Aygıt sürücünüz, aldığı bir istek için her zaman bir durum döndürmelidir. Her zaman numaralandırılmış dönüş kodlarını ve normal geri dönüş kodlarını kullanmanız önerilir. Dönen 0 = 1 ya da -1 = başarısız belirsiz ve yanıltıcı olabilir. Daha fazla bilgi

+0

Anladığım kadarıyla, hata üretmek istiyor ve buna göre errno ayarlıyor. Sen sadece errno oku. Ancak geliştirdiği sistem, varsayılan olarak errno ayarlamamıştır. Ayarlaması gerekiyor. – sestus

+0

Evet, ne istediğim kullanıcı alanı uygulamaları yerine "aygıt sürücüsü" nde errno ayarlamak. –

6

İade ioctl negatif hata numarası için

Okuma bölüm 3.1 Efficient error handling, reporting and recovery:. C kütüphanesi bunu yorumlar ve -1 dönüş kodu verir ve pozitif hatayı errno olarak ayarlar. Örneğin, orijinal örneğiniz errno değerini 1 olarak ayarlayacaktır.

Çekirdeğinizde bir ioctl işlevi için prototipiniz bir kenara yanlış görünüyor. Hangi çekirdek sürümünü kullanıyorsunuz?

+0

Teşekkürler! Senin ve sestusun cevaplarını birleştiririm ve ne yapmam gerektiğini anlarım. Ama sestus'un cevabı daha ayrıntılı. Sadece bir cevabın kabul edilebilmesi ne yazık ki. –