Энциклопедия разработчика модулей ядра 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);