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



> If something is unknown about the kernel, this is usually the way to go. In Linux we have the great advantage of having the kernel source code for free - use it.

>*/


>int procfile_read(char *buffer, char **buffer_location, off_t offset, int buffer_length, int zero) {

> int len; /* The number of bytes actually used */

> /* This is static so it will still be in memory> when we leave this function */

> static char my_buffer[80];

> static int count = 1;

> /* We give all of our information in one go, so if the

> * user asks us if we have more information the

> * answer should always be no.

> *

> * This is important because the standard read

> * function from the library would continue to issue

> * the read system call until the kernel replies

> * that it has no more information, or until its * buffer is filled. */

> if (offset > 0) return 0;

> /* Fill the buffer and get its length */

> len = sprintf(my_buffer, "For the %d%s time, go away!\n", count,

>  (count % 100 > 10 && count % 100 < 14) ? "th" :

>  (count % 10 == 1) ? "st" : (count % 10 == 2) ? "nd" :

>  (count % 10 == 3) ? "rd" : "th" );

> count++;

> /* Tell the function which called us where the buffer is */

> *buffer_location = my_buffer;

> /* Return the length */

> return len;

>}


>struct proc_dir_entry Our_Proc_File = {

> 0, /* Inode number - ignore, it will be filled by proc_register[_dynamic] */

> 4, /* Length of the file name */

> "test", /* The file name */

> S_IFREG | S_IRUGO, /* File mode - this is a regular file which can be read by its owner, its group, and everybody else */

> 1, /* Number of links (directories where the file is referenced) */

> 0, 0, /* The uid and gid for the file - we give it * to root */

> 80, /* The size of the file reported by ls. */

> NULL, /* functions which can be done on the inode (linking, removing, etc.) - we don't support any. */

> procfile_read, /* The read function for this file, the function called when somebody tries to read something from it. */

> NULL /* We could have here a function to fill the file's inode, to enable us to play with permissions, ownership, etc. */

>};


>/* Initialize the module - register the proc file */

>int init_module() {

> /* Success if proc_register[_dynamic] is a success, failure otherwise. */

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

> /* In version 2.2, proc_register assign a dynamic

> * inode number automatically if it is zero in the

> * structure, so there's no more need for

> * proc_register_dynamic */

> return proc_register(&proc_root, &Our_Proc_File);