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



> Device_Open++;

> /* Initialize the message. */

> sprintf(Message, "If I told you once, I told you %d times - %s", counter++, "Hello, world\n");

> /* The only reason we're allowed to do this sprintf

> * is because the maximum length of the message

> * (assuming 32 bit integers - up to 10 digits

> * with the minus sign) is less than BUF_LEN, which

> * is 80. BE CAREFUL NOT TO OVERFLOW BUFFERS,

> * ESPECIALLY IN THE KERNEL!!! */

> Message_Ptr = Message;

> /* Make sure that the module isn't removed while

> * the file is open by incrementing the usage count

> * (the number of opened references to the module, if

> * it's not zero rmmod will fail)

> */

> MOD_INC_USE_COUNT;

> return SUCCESS;

>}


>/* This function is called when a process closes the

>* device file. It doesn't have a return value in

>* version 2.0.x because it can't fail (you must ALWAYS

>* be able to close a device). In version 2.2.x it is

>* allowed to fail - but we won't let it. */

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

>static int device_release(struct inode *inode, struct file *file)

>#else

>static void device_release(struct inode *inode, struct file *file)

>#endif

>{

>#ifdef DEBUG

> printk("device_release(%p,%p)\n", inode, file);

>#endif

> /* We're now ready for our next caller */

> Device_Open--;

> /* Decrement the usage count, otherwise once you opened the file you'll never get rid of the module. */

> MOD_DEC_USE_COUNT;

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

> return 0;

>#endif

>}


>/* This function is called whenever a process which

>* have already opened the device file attempts to

>* read from it. */

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

>static ssize_t device_read(struct file *file,

> char *buffer, /* The buffer to fill with data */

> size_t length, /* The length of the buffer */

> loff_t *offset) /* Our offset in the file */

>#else

>static int device_read(struct inode *inode, struct file *file,

> char *buffer, /* The buffer to fill with the data */

> int length) /* The length of the buffer (mustn't write beyond that!) */

>#endif

>{

> /* Number of bytes actually written to the buffer */

> int bytes_read = 0;

> /* If we're at the end of the message, return 0 (which signifies end of file) */

> if (*Message_Ptr == 0) return 0;

> /* Actually put the data into the buffer */

> while (length && *Message_Ptr) {

>  /* Because the buffer is in the user data segment,

>  * not the kernel data segment, assignment wouldn't

>  * work. Instead, we have to use put_user which