/* procfsreadxtime.c * Variation of Ch 5.1 proc file module from * Linux Kernel Module Programmer's Guide for 2.4 Kernel * * Create /proc/xtime and supply xtime.tv_sec and xtime.tv_uxec upon read */ /* 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 and externs*/ /* For the proper signaure of this function see the * /usr/src/linux/include/procfs.h with the definition * of the proc_dir_entry structure * and the read_proc function field in that structure */ 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); /* I'm not sure where this really is. sched.h has this extern reference */ extern struct timeval xtime; /* 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: 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: leaving via EOF simulator.\n"); return 0; } len = sprintf(my_buffer, "count: %d xtime.tv_sec: %ld xtime.tv_usec: %ld\n", count, xtime.tv_sec, xtime.tv_usec); count++; *user_buffer = my_buffer; printk(KERN_ALERT "my_read_proc: 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 "/proc/xtime module loaded\n"); my_proc_file = create_proc_read_entry( "xtime", /* 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 "/proc/xtime module unloaded\n"); remove_proc_entry("xtime", NULL); /* file name and parent */ } MODULE_LICENSE("GPL");