Skip to content
Snippets Groups Projects
Commit c5f0b521 authored by Werner Sembach's avatar Werner Sembach
Browse files

Add slightly different sourcecode for android version of klist

parent 25f8ff11
Branches master
No related tags found
No related merge requests found
#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");
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment