Trying to pass an argument to the argument argument ioctl call zeros out

I am trying to call the ioctl function in a toy file system module. I just would like this ioctl to set a variable that is passed to the caller. So far, I have created an ioctl framework that allows me to make ioctl calls. I have this function in my module for processing ioctl.

int ospfs_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg) { if(cmd == OSPFSIOCRASH) { eprintk("crash: %ld\n", arg); return 0; } else return -ENOTTY; } 

And my test function looks like this.

 #include <stdio.h> #include <fcntl.h> #include <sys/ioctl.h> #define OSPFSIOCRASH 42 int main() { int fd = open("/tmp/cs111/lab3-thief/test/hello.txt", O_RDWR); printf("ioctl call: %d\n", ioctl(fd, OSPFSIOCRASH, 100)); close(fd); } 

I expect the conclusion to be

 crash: 100 ioctl call: 0 

but actually conclusion

 crash: 0 ioctl call: 0 

I bet I'm doing something simple wrong. Can someone help and point out what the problem is? Thank you.

+4
source share
2 answers

It may not be a solution that solves your problem, but based on limited information from your question and comments, this is what I could collect.

Based on the question and comments, it looks like you defined the struct file_operations structure like this:

 struct file_operations fops = { .ioctl=ospfs_ioctl }; 

And the signature of your ospfs_ioctl suggests that you are using an older ioctl.

With the latest kernels (at least after 2.6.35+ or something else) it is recommended to use .unlocked_ioctl instead of .ioctl .

 struct file_operations fops = { .unlocked_ioctl=ospfs_ioctl }; 

And the definition of the ospfs_ioctl function ospfs_ioctl change to:

 long ospfs_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) 

The differences between unlocked_ioctl and regular ioctl can be found here here . In short, it does not accept the dreaded BKL before invoking ioctl.

And also at the suggestion of Chris Dodd you should double check how you define your OSPFIOCRASH . The recommended way is to use _IO(magic, some_num_for_ioctl)

0
source

As suggested by Chris Dodd, I changed #define OSPFIOCRASH 42 to #define OSPFSIOCRASH _IO(magic, 0) and have since received the desired behavior.

0
source