#include <linux/version.h> #include <linux/module.h> #include <linux/init.h> #include <linux/fs.h> #include <linux/cdev.h> #include <linux/slab.h> #include <asm/uaccess.h> // thx http://lwn.net/Kernel/LDD3/ static char* txt[] = { "Welcome to my new blog; perhaps you have visisted my former blog at spin.de, too. This is it's successor!\n" "Have a lot of fun, btwotch\n", "http://twitter.com/btwotch\n", "http://btwotch.soup.io\n", "http://mister-wong.de/user/btwotch\n" }; static dev_t d; static struct cdev* c; struct txt_msg { size_t written; char *txt; size_t txt_len; }; static int btwotch_open(struct inode* i, struct file* f) { int minor = iminor(f->f_dentry->d_inode); struct txt_msg *tm = kmalloc(sizeof(struct txt_msg), GFP_KERNEL); tm->written = 0; if (minor > 4) minor = 0; tm->txt = txt[minor]; tm->txt_len = strlen(tm->txt); f->private_data = tm; return 0; } static int btwotch_close(struct inode* i, struct file* f) { kfree(f->private_data); return 0; } static ssize_t btwotch_read(struct file* f, char __user *user, size_t count, loff_t *offset) { size_t len, leftwrite, written; struct txt_msg *tm = (struct txt_msg*)f->private_data; if (tm->txt_len == tm->written) // that's how we do EOF! return 0; leftwrite = tm->txt_len-tm->written; len = (count < leftwrite) ? count : leftwrite; written = copy_to_user(user, tm->txt+tm->written, len); tm->written += len-written; return len-written; } static struct file_operations fops = { .owner = THIS_MODULE, .read = btwotch_read, .open = btwotch_open, .release = btwotch_close }; static void register_driver(void) { c = cdev_alloc(); cdev_init(c, &fops); alloc_chrdev_region(&d, 0, 5, "btwotch-drv"); cdev_add(c, d, 1); cdev_add(c, d, 2); cdev_add(c, d, 3); cdev_add(c, d, 4); printk("btwotch-mod: major: %d minor: %d\n", MAJOR(d), MINOR(d)); } static void unregister_driver(void) { cdev_del(c); unregister_chrdev_region(d, 5); } static int __init init_btwotch(void) { register_driver(); return 0; } static void __exit cleanup_btwotch(void) { unregister_driver(); } module_init(init_btwotch); module_exit(cleanup_btwotch); MODULE_AUTHOR("btwotch"); MODULE_LICENSE("GPL"); MODULE_DESCRIPTION("the btwotch virtual device"); MODULE_SUPPORTED_DEVICE("none");
btwotch_open(struct inode *i, struct file *f)
Leave a reply