summaryrefslogtreecommitdiff
path: root/kworm.c
blob: 7709a05ad9152e0faa3e01bf8e0878c22fad25f0 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
#include <linux/init.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/fs.h>
#include <linux/delay.h>
#include <linux/uaccess.h>

#define NAME "worm"

MODULE_DESCRIPTION("worm");
MODULE_LICENSE("BSD-3-Clause");
MODULE_VERSION("1.0");

int worm_phase = 0;
static int major;

static int dev_open(struct inode*, struct file*);
static int dev_release(struct inode*, struct file*);
static ssize_t dev_read(struct file*, char*, size_t, loff_t*);
static ssize_t dev_write(struct file*, const char*, size_t, loff_t*);

static struct file_operations fops = {
    .open = dev_open,
    .read = dev_read,
    .write = dev_write,
    .release = dev_release
};

static int __init kworm_init(void)
{
    major = register_chrdev(0, NAME, &fops);

    if(major < 0)
    {
        printk(KERN_ALERT "kworm init failed\n");
        return major;
    }

    printk(KERN_INFO "kworm init (%d)\n", major);
    return 0;
}

static void __exit kworm_exit(void)
{
    unregister_chrdev(major, NAME);
    printk(KERN_INFO "kworm exit\n");
}

static int dev_open(struct inode* inodep, struct file* filep)
{
    printk(KERN_INFO "kworm opened\n");
    return 0;
}


static ssize_t dev_write(struct file* filep, const char* buffer, size_t len, loff_t* offset)
{
    printk(KERN_INFO "kworm read-only\n");
    return -EFAULT;
}

static int dev_release(struct inode* inodep, struct file* filep)
{
    printk(KERN_INFO "kworm closed\n");
    return 0;
}

static ssize_t dev_read(struct file* filep, char* buffer, size_t len, loff_t* offset)
{
    int errors = 0;
    char *worm = "|\r(\r|\r)\r";
    int worm_len = 2;
    worm_phase = (worm_phase % 4) + 1;

    mdelay(100);

    errors = copy_to_user(buffer, worm + ((worm_phase - 1) * 2), worm_len);

    return errors == 0 ? worm_len : -EFAULT;
}

module_init(kworm_init);
module_exit(kworm_exit);