Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- https://github.com/BoiseState/CS453-resources/tree/master
- #include <linux/module.h>
- #include <linux/kernel.h>
- #include <linux/init.h>
- #include <linux/slab.h>
- #include <linux/fs.h>
- #include <linux/uaccess.h>
- #include <linux/cdev.h>
- MODULE_LICENSE("GPL");
- MODULE_DESCRIPTION("BSU CS452 HW5");
- MODULE_AUTHOR("<axelmurillo@u.boisestate.edu>");
- typedef struct {
- dev_t devno;
- struct cdev cdev;
- char *seperatorList;
- } Device;
- typedef struct {
- char *s;
- char *separatorList;
- size_t inputSize;
- int ioctl;
- size_t separatorListLength;
- size_t inputProcessedChars;
- } Scanner;
- static Device device;
- static int open(struct inode *inode, struct file *filep) {
- Scanner *scanner = (Scanner *)kmalloc(sizeof(*scanner), GFP_KERNEL);
- if (!scanner) {
- printk(KERN_ERR "%s: kmalloc() failed\n",DEVNAME);
- return -ENOMEM;
- }
- scanner->seperatorList = kmalloc(strlen(device.separatorList) + 1, DEVNAME);
- if (!scanner->separatorList) {
- printk(KERN_ERR "%s: kmalloc() failed for seperatorList\n",DEVNAME);
- kfree(scanner);
- return -ENOMEM;
- }
- strcpy(scanner->seperatorList, device.separatorList);
- scanner->separatorListLength = strlen(device.separatorList);
- scanner->ioctl = 1;
- filp->private_data=scanner;
- return 0;
- }
- static int release(struct inode *inode, struct file *filp) {
- Scanner *scanner = filp->private_data;
- kfree(scanner->seperatorList);
- kfree(scanner);
- return 0;
- }
- static int isCharSeparator(Scanner *scan, char cmp) {
- int i;
- for (i = 0; i < scan->separatorListLength; i++) {
- if (scan->separatorList[i] == cmp) {
- return 1;
- }
- }
- return 0;
- }
- extern ssize_t read(struct file *filp, char *buf, size_t charRequested, loff_t *f_pos) {
- Scanner *scan = filp->private_data;
- size_t numCProcessed = 0;
- int isSeparator = 0;
- char *currToken = kmalloc(sizeof(char) * (charRequested + 1), GFP_KERNEL);
- memset(currToken, 0, sizeof(char) * (charRequested + 1));
- if (!currToken) {
- printk(KERN_ERR "%s: kmalloc failed", DEVNAME);
- return -ENOMEM;
- }
- while (numCProcessed < charRequested && !isSeparator && scan->inputProcessedChars < scan->inputSize) {
- char currChar = scan->s[scan->inputProcessedChars];
- isSeparator = isCharSeparator(scan, currChar);
- if (!isSeparator) {
- currToken[numCProcessed] = currChar;
- currToken[numCProcessed + 1] = '\0';
- numCProcessed++;
- scan->inputProcessedChars++;
- }
- }
- if (copy_to_user(buf, currToken, numCProcessed))
- {
- printk(KERN_ERR "%s: copy_to_user() failed\n", DEVNAME);
- return 0;
- }
- kfree(currToken); //free memory allocated for currToken
- if (scan->inputProcessedChars == scan->inputSize && numCProcessed == 0)
- {
- numCProcessed = -1;
- kfree(scan->s);
- }
- if (isSeparator && numCharsProcessed == 0)
- {
- scan->inputProcessedChars++;
- }
- return numCProcessed;
- }
- static long ioctl(struct file *filp, unsigned int cmd, unsigned long arg) {
- Scanner *scan = filp->private_data;
- if (cmd == 0 && arg == 0) {
- scan->ioctl = 0;
- }
- return 0;
- }
- extern ssize_t write(struct file *filp, const char *line, size_t len, loff_t *f_pos) {
- Scanner *scan = filp->private_data;
- if (!scan->ioctl) {
- //free any existing lists
- kfree(scan->separatorList);
- //allocate memory
- scan->separatorList = kmalloc(sizeof(char) * (len + 1), GFP_KERNEL);
- scan->separatorList = memset(scan->separatorList, 0, sizeof(char) * (len + 1));
- //copy user data to kernel space
- if (copy_from_user(scan->separatorList, line, len) != 0) {
- printk(KERN_ERR "%s: write separators failed", DEVNAME);
- len = -1;
- }
- scan->separatorListLength = len;
- scan->ioctl = 1;
- } else {
- //allocate memory
- scan->s = kmalloc(sizeof(char) * (len + 1), GFP_KERNEL);
- scan->s = memset(scan->s, 0, sizeof(char) * (len + 1)); //INPUT BUFFER INSTEAD!
- //copy user data to kernel space
- if (copy_from_user(scan->s, line, len) != 0) {
- printk(KERN_ERR "%s: write failed", DEVNAME);
- len = -1;
- }
- scan->inputSize = len;
- scan->inputProcessedChars = 0;
- }
- return len;
- }
- static struct file_operations ops = {
- .open = open,
- .release = release,
- .read = read,
- .write = write,
- .unlocked_ioctl = ioctl,
- .owner = THIS_MODULE
- };
- static int __init my_init(void) {
- const char *defaultSep = " \t\n:;,+-=!@./#$%&*";
- int err;
- device.separatorList = (char *)kmalloc(strlen(defaultSep) + 1, GFP_KERNEL);
- if (!device.separatorList) {
- printk(KERN_ERR "%s: kmalloc failed\n", DEVNAME);
- return -ENOMEM;
- }
- strcpy(device.separatorList, defaultSep);
- err = alloc_chrdev_region(&device.devno, 0, 1, DEVNAME);
- if (err < 0)
- {
- printk(KERN_ERR "%s: alloc_chrdev_region() failed\n", DEVNAME);
- return err;
- }
- cdev_init(&device.cdev, &ops);
- device.cdev.owner = THIS_MODULE;
- err = cdev_add(&device.cdev, device.devno, 1);
- if (err)
- {
- printk(KERN_ERR "%s: cdev_add() failed\n", DEVNAME);
- return err;
- }
- printk(KERN_INFO "%s: init\n", DEVNAME);
- return 0;
- }
- static void __exit my_exit(void) {
- cdev_del(&device.cdev);
- unregister_chrdev_region(device.devno, 1);
- kfree(device.seperatorList);
- printk(KERN_INFO "%s: exit\n", DEVNAME);
- }
- module_init(my_init);
- module_exit(my_exit);
- Dr. Buffenbarger
- Axel Murillo
- CS452 Operating Systems F24
- 19 November 2024
- ## Overview
- ## How to compile and run
- ### Prerequisites
- ### Compilation
- obj-m += my_module.o
- all:
- make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules
- clean:
- make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean
- make
- sudo insmod scanner_device.ko
- dmesg
- sudo rmmod scanner_device
- ///////
- sudo insmod my_module.ko
- ## Reflection
- ## Valgrind
- ### My valgrind output:
- ==12345== Memcheck, a memory error detector
- ==12345== HEAP SUMMARY:
- ==12345== in use at exit: 0 bytes in 0 blocks
- ==12345== total heap usage: 3 allocs, 3 frees, 36,960 bytes allocated
- ==12345==
- ==12345== All heap blocks were freed -- no leaks are possible
- ==12345==
- ==12345== For counts of detected and suppressed errors, rerun with: -v
- ==12345== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement