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?
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.
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.
The errno is defined in cerrno header file.
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.
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
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?
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With