Энциклопедия разработчика модулей ядра Linux | страница 22



>#endif

>{

> int i;

>#ifdef DEBUG

> printk("device_write(%p,%s,%d)", file, buffer, length);

>#endif

> for(i=0; i

>#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,2,0)

>  get_user(Message[i], buffer+i);

>#else

>  Message[i] = get_user(buffer+i);

>#endif

> Message_Ptr = Message;

> /* Again, return the number of input characters used */

> return i;

>}


>/* This function is called whenever a process tries to

>* do an ioctl on our device file. We get two extra

>* parameters (additional to the inode and file

>* structures, which all device functions get): the number

>* of the ioctl called and the parameter given to the ioctl function.

>*

>* If the ioctl is write or read/write (meaning output

>* is returned to the calling process), the ioctl call

>* returns the output of this function. */

>int device_ioctl(struct inode *inode, struct file *file,

> unsigned int ioctl_num, /* The number of the ioctl */

> unsigned long ioctl_param) /* The parameter to it */

>{

> int i;

> char *temp;

>#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,2,0)

> char ch;

>#endif

> /* Switch according to the ioctl called */

> switch (ioctl_num) {

> case IOCTL_SET_MSG:

>  /* Receive a pointer to a message (in user space)

>  * and set that to be the device's message. */

>  /* Get the parameter given to ioctl by the process */

>  temp = (char*)ioctl_param;

>  /* Find the length of the message */

>#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,2,0)

>  get_user(ch, temp);

>  for (i=0; ch && i

>#else

>  for (i=0; get_user(temp) && i

>#endif

>  /* Don't reinvent the wheel - call device_write */

>#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,2,0)

>  device_write(file, (char*)ioctl_param, i, 0);

>#else

>  device_write(inode, file, (char*)ioctl_param, i);

>#endif

>  break;

> case IOCTL_GET_MSG:

>  /* Give the current message to the calling

>  * process - the parameter we got is a pointer, fill it. */

>#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,2,0)

>  i = device_read(file, (char*)ioctl_param, 99, 0);

>#else

>  i = device_read(inode, file, (char*)ioctl_param, 99);

>#endif

>  /* Warning - we assume here the buffer length is

>  * 100. If it's less than that we might overflow

>  * the buffer, causing the process to core dump.

>  *

>  * The reason we only allow up to 99 characters is

>  * that the NULL which terminates the string also needs room. */

>  /* Put a zero at the end of the buffer, so it will be properly terminated */

>  put_user('\0', (char*)ioctl_param+i);