//------------------------------------------------------------------- // tcb.c // // This module creates a read-only pseudo-file ("/proc/tcb") // which allows an application program to access the current // contents of its Task Control Block (i.e., 'task_struct'). // // NOTE: Written and tested using Linux kernel version 2.4.26. // // programmer: ALLAN CRUSE // written on: 18 SEP 2004 //------------------------------------------------------------------- #include // for init_module() #include // for create_proc_entry() #include // for copy_to_user() #define PROC_DIR NULL #define PROC_MODE 0444 static char modname[] = "tcb"; static loff_t tcbsize = sizeof( struct task_struct ); static ssize_t my_read( struct file *file, char *buf, size_t count, loff_t *pos ) { struct task_struct *tsk = current; int nbytes = count; // we cannot read beyond the end of the task_struct if ( *pos >= tcbsize ) return 0; // maximum number of bytes to be transferred if ( *pos + nbytes > tcbsize ) nbytes = tcbsize - *pos; // perform the transfer, report error if unsuccessful if ( copy_to_user( buf, tsk, nbytes ) ) return -EFAULT; // report the number of bytes transferred return nbytes; } static loff_t my_seek( struct file *file, loff_t offset, int whence ) { loff_t newpos = -1; switch ( whence ) { case 0: newpos = offset; break; // SEEK_SET case 1: newpos += offset; break; // SEEK_CUR case 2: newpos = tcbsize + offset; // SEEK_END } if (( newpos < 0 )||( newpos > tcbsize )) return -EINVAL; file->f_pos = newpos; return newpos; } static struct file_operations my_fops = { owner: THIS_MODULE, llseek: my_seek, read: my_read, }; int init_module( void ) { struct proc_dir_entry *entry; entry = create_proc_entry( modname, PROC_MODE, PROC_DIR ); entry->proc_fops = &my_fops; return 0; // SUCCESS; } void cleanup_module( void ) { remove_proc_entry( modname, PROC_DIR ); } MODULE_LICENSE("GPL");