How does Linux know which ioctl function to call?

Here is the ioctl call in user space:

 int ioctl(int fd, int cmd, ...); 

As far as I know, when we want to perforate I / O operations, we define our own ioctl function with a set of requests (commands), assign our ioctl file_operations :

 struct file_operations fops = { .read = device_read, .write = device_write, .ioctl = device_ioctl, // device_ioctl is our function .open = device_open, .release = device_release, }; 

And the device_ioctl function device_ioctl defined differently compared to the user space interface:

 static long device_ioctl(struct file *f, unsigned int cmd, unsigned long arg) 

I think that based on the file descriptor, the kernel can get the appropriate file structure and calls the ioctl device.

Is this just an assumption because I cannot find this definition of a generic function when the kernel selects the appropriate ioctl function based on the file descriptor fd passed to the generic ioctl interface? There are only 3 ioctl definitions that I can find, but apparently these are just device definitions, not the kernel: ioctl

+6
source share
4 answers

Check out the Linux source code, fs / ioctl.c ( http://lxr.free-electrons.com/source/fs/ioctl.c )
There you will see syscall for ioctl:

 SYSCALL_DEFINE3(ioctl, unsigned int, fd, unsigned int, cmd, unsigned long, arg) 

This in turn calls do_vfs_ioctl (), which calls vfs_ioctl (), which then calls the unlocked_ioctl function defined for this file system in the file_operations structure.
This will be your device_ioctl function that you registered.

+5
source

device_ioctl is a pointer to a function. The kernel simply accepts fd as the index of the struct file_operations and calls the .ioctl corresponding element. The kernel should never know what a function is, what device it belongs to.

This is the basis of the "Everything is File", which is Unix moto.

+2
source

When you call ioctl , you pass the file descriptor. You got a file descriptor from opening the device file, for example /dev/tty0 :

 $ ls -l /dev/tty0 crw--w---- 1 root tty 4, 0 Mar 6 10:47 /dev/tty0 $ 

The number 4 here is the main number of the device that is encoded into the driver module that the kernel should use.

+1
source

The kernel knows which ioctl function to call because of the file descriptor. To be able to call ioctl () from user space, you will need to open the file to get fd , typically a / dev / [some_device], whose driver will implement the file_operations structure, as you indicated.

0
source

Source: https://habr.com/ru/post/969651/


All Articles