diff --git a/copy_of_klist_android_kernel.c b/copy_of_klist_android_kernel.c new file mode 100644 index 0000000000000000000000000000000000000000..526d4c444fc8fb6d110562df38537e8bf863b47e --- /dev/null +++ b/copy_of_klist_android_kernel.c @@ -0,0 +1,199 @@ +#include <linux/module.h> +#include <linux/kernel.h> +#include <linux/miscdevice.h> +#include <linux/init.h> +#include <linux/mutex.h> +#include <linux/fs.h> +#include <linux/rbtree.h> +#include <linux/hashtable.h> +#include <linux/list.h> +#include <linux/slab.h> +#include <linux/uaccess.h> +#include <linux/tty.h> +#include <asm/errno.h> +#include <linux/miscdevice.h> + +#define ERR(...) printk(KERN_ERR __VA_ARGS__) + +/* #define DEBUG */ +#ifdef DEBUG +#define LOG(...) printk(KERN_INFO __VA_ARGS__) +#else +#define LOG(...) +#endif + +/* klist functions */ +#define LIST_CMD 0x1337 +#define LIST_ADD (LIST_CMD + 0) +#define LIST_INSERT (LIST_CMD + 1) +#define LIST_SET (LIST_CMD + 2) +#define LIST_GET (LIST_CMD + 3) +#define LIST_DELETE (LIST_CMD + 4) + +/* consts */ +#define MAX_SIZE 0x400 + +static volatile struct k_list { + long values[MAX_SIZE]; + unsigned long size; +} list; + +struct index_val_t { + unsigned long index; + long value; +}; + +long add_item(long arg) +{ + if (list.size >= MAX_SIZE) + return -EINVAL; + list.values[list.size] = arg; + list.size++; + + return 0; +} + +long insert_item(long arg) +{ + struct index_val_t io; + unsigned long i; + if (copy_from_user((void *)&io, (void __user *)arg, sizeof(struct index_val_t))) + return -EINVAL; + + if (list.size >= MAX_SIZE) + return -EINVAL; + if (io.index > list.size) + return -EINVAL; + + for(i = list.size; i > io.index; i--) + { + list.values[i] = list.values[i-1]; + } + list.values[io.index] = io.value; + list.size++; + + return 0; +} + +long set_item(long arg) +{ + struct index_val_t io; + if (copy_from_user((void *)&io, (void __user *)arg, sizeof(struct index_val_t))) + return -EINVAL; + + if (io.index >= list.size) + return -EINVAL; + + list.values[io.index] = io.value; + + return 0; +} + +long get_item(long arg) +{ + struct index_val_t io; + if (copy_from_user((void *)&io, (void __user *)arg, sizeof(struct index_val_t))) + return -EINVAL; + + if (io.index >= list.size) + return -EINVAL; + + io.value = list.values[io.index]; + if (copy_to_user((void __user *)arg, (void *)&io, sizeof(struct index_val_t))) + return -EINVAL; + + return 0; +} + +long delete_item(long arg) +{ + unsigned long index = arg; + + if (index >= list.size) + return -EINVAL; + + for(; index < list.size-1; index++) + { + list.values[index] = list.values[index+1]; + } + list.size--; + + return 0; +} + +static long list_ioctl(struct file *file, unsigned int cmd, unsigned long arg) +{ + long ret; + + switch(cmd) { + case LIST_ADD: + ret = add_item(arg); + break; + case LIST_INSERT: + ret = insert_item(arg); + break; + case LIST_SET: + ret = set_item(arg); + break; + case LIST_GET: + ret = get_item(arg); + break; + case LIST_DELETE: + ret = delete_item(arg); + break; + default: + ret = -EINVAL; + break; + } + + return ret; +} + +static int list_open(struct inode *inode, struct file *file) +{ + LOG("open device\n"); + + return 0; +} + +static int list_release(struct inode *inode, struct file *file) +{ + LOG("close device\n"); + + return 0; +} + +struct file_operations list_fops = { + owner: THIS_MODULE, + open: list_open, + release: list_release, + unlocked_ioctl: list_ioctl, +}; + +static struct miscdevice klist = { + .minor = MISC_DYNAMIC_MINOR, + .name = "klist", + .fops = &list_fops, +}; + +static int __init init_list(void) +{ + int ret; + + ret = misc_register(&klist); + LOG("register device: %d\n", ret); + list.size = 0; + + return ret; +} + +static void __exit exit_list(void) +{ + misc_deregister(&klist); + LOG("exit.\n"); +} + +module_init(init_list); +module_exit(exit_list); + +MODULE_LICENSE("GPL");