/* procfsread.c * Variation of Ch 5.1 proc file module from * Linux Kernel Module Programmer's Guide for 2.4 Kernel * * Each proc file access displays the current access count. */ /* kernel module programming */ #ifndef MODULE #define MODULE #endif #ifndef LINUX #define LINUX #endif #ifndef __KERNEL__ #define __KERNEL__ #endif #define MAX_BUF 80 #include /* needed by all modules */ #include /* needed for KERN_ALERT */ #include /* working with the proc fs */ /* prototypes */ /* For the proper signaures of these functions see the * /usr/src/linux/include/procfs.h with the definition * of the proc_dir_entry structure * and these function fields in that structure */ int my_get_info(char *sys_buf, char **user_buf, off_t file_pos, /* position in user_buf */ int buf_len); /* for system buf_len ?? */ int my_read_proc(char *sys_buffer, /* system supplied buffer */ char **user_buffer, /* user provided buffer */ off_t file_pos, /* position in proc file read */ int buflen, /* for system buf_len ?? */ int *eof, /* I could guess */ void *data); /* no clue */ int init_module(void); void cleanup_module(void); /* My function to supply the proc file read information */ int my_read_proc(char *sys_buffer, /* system supplied buffer */ char **user_buffer, /* user provided buffer */ off_t file_pos, /* position in proc file read */ int buflen, /* buffer size (system buffer?) */ int *eof, /* I could guess */ void *data) /* no clue */ { int len; /* number of bytes actually used */ static char my_buffer[MAX_BUF]; static int count = 1; /* access count */ printk(KERN_ALERT "my_read_proc of proc module: entering.\n"); /* Make sure we only respond once to a read call from the user. If we * are called directly from a user program that knows what this proc * file is intended to produce, then we won't get called twice. But * if we are called from a standard file read (such as doing a cat * on a proc file) then the standard file reading system code will * continue to issue a read until an EOF is returned. An EOF is * signaled by a return of a 0 (zero) length for the read. We can * use any indicator to determine if we have already been called * once. This example from the LKMPG just checks to see if the * file_pos has been moved at all. Simpler here might have been * just to see if our count was greater than zero. */ if (file_pos > 0) { printk(KERN_ALERT "my_read_proc of proc module: leaving via EOF simulator.\n"); return 0; } len = sprintf(my_buffer, "count: %d\n", count); count++; *user_buffer = my_buffer; printk(KERN_ALERT "my_read_proc of proc module: leaving.\n"); return len; /* return the length of the string returned */ } /* Directory structure for proc files (a psuedo inode?) * This is created dynamically in kernel 2.4, see init_module below */ struct proc_dir_entry *my_proc_file; /* create_proc_read_entry registers the read function. See proc_fs.h */ int init_module(void) { printk(KERN_ALERT "procfile module loaded\n"); my_proc_file = create_proc_read_entry( "test", /* proc file name */ 0444, /* uid gid mode */ NULL, /* dir entry base */ my_read_proc, /* read function */ NULL); /* data for function ?? */ /* A non-zero return means init_module failed; module can't be loaded */ if (my_proc_file == NULL) return -ENOMEM; return 0; } void cleanup_module(void) { printk(KERN_ALERT "procfile module unloaded\n"); remove_proc_entry("test", NULL); /* file name and parent */ } MODULE_LICENSE("GPL");