Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to set errno in Linux device driver?

I am designing a Linux character device driver. I want to set errno when error occurs in ioctl() system call.

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

What should I do to achieve that? Thank you at advance!


Please allow me to explain my application with more detail.

My device is located in /dev/myCharDev. My user space application is like this:

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

As I mentioned in the comments above, How should I set the "errno" in my own device driver codes and make it readable by user space application?

like image 812
Andrew Chang Avatar asked Jul 04 '14 05:07

Andrew Chang


People also ask

What is errno in Linux?

Errno is a value that you get when the command you run returns the value of the call indicating an error. There is a header file that defines the integer variable errno, which is set by the system calls and some library function in the event of an error to let the developer know what's wrong.

Do I need to set errno to 0?

Initializing ErrnoYour program should always initialize errno to 0 (zero) before calling a function because errno is not reset by any library functions. Check for the value of errno immediately after calling the function that you want to check. You should also initialize errno to zero after an error has occurred.

Where is errno declared?

The errno is defined in cerrno header file.

How do I register a character driver in Linux?

The classic way to register a char device driver is with: int register_chrdev(unsigned int major, const char *name, struct file_operations *fops); Here, major is the major number of interest, name is the name of the driver (it appears in /proc/devices), and fops is the default file_operations structure.


2 Answers

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

where, errno is the return value of some function.

Your device driver should always return a status for a request it received. It is advocated you always use enumerated return codes as well as normal return codes. Returning 0 = pass 1 or -1 = failed is vague and could be misleading.

Read section 3.1 Efficient error handling, reporting and recovery: for more information

like image 146
Sagar Jain Avatar answered Oct 06 '22 15:10

Sagar Jain


Return the negative error number from the ioctl. The c library interprets this and gives a -1 return code and sets errno to the positive error. For instance your original example will set errno to 1.

As an aside your prototype for an ioctl function in the kernel looks wrong. Which kernel version are you using?

like image 36
slobobaby Avatar answered Oct 06 '22 14:10

slobobaby