From: Thadeu Lima de Souza Cascardo Date: Wed, 19 May 2010 16:11:35 +0000 (-0400) Subject: Write function. X-Git-Url: http://git.cascardo.info/?p=cascardo%2Fkernel%2Fsamples%2Fchar2%2F.git;a=commitdiff_plain;h=0bd3205aa20ff03e41783a79665443c7d05ffdb1 Write function. --- diff --git a/hellochar.c b/hellochar.c index c95100e..1649fe3 100644 --- a/hellochar.c +++ b/hellochar.c @@ -20,9 +20,11 @@ #include #include #include +#include MODULE_LICENSE("GPL"); +#define MAXLEN 4000 static dev_t devnum; static struct cdev *dev; static const char default_greeting[] = "Hello, World!\n"; @@ -34,17 +36,43 @@ struct hello_buffer { static int hello_open(struct inode *ino, struct file *fp) { - struct hello_buffer *hello = kmalloc(sizeof(*hello) + 4000, GFP_KERNEL); + struct hello_buffer *hello = kzalloc(sizeof(*hello) + MAXLEN, GFP_KERNEL); if (!hello) return -ENOMEM; - hello->private_data = hello; + memcpy(hello->buffer, default_greeting, sizeof(default_greeting)); + hello->len = sizeof(default_greeting); + fp->private_data = hello; return 0; } static ssize_t hello_read(struct file *fp, char __user *buf, size_t sz, loff_t *pos) { - return 0; + struct hello_buffer *hello = fp->private_data; + int r; + if (sz + *pos > hello->len) + sz = hello->len - *pos; + r = copy_to_user(buf, hello->buffer + *pos, sz); + if (r) + return -EFAULT; + *pos += sz; + return sz; +} + +static ssize_t hello_write(struct file *fp, const char __user *buf, size_t sz, + loff_t *pos) +{ + struct hello_buffer *hello = fp->private_data; + int r; + if (sz + *pos > MAXLEN) + sz = MAXLEN - *pos; + r = copy_from_user(hello->buffer + *pos, buf, sz); + if (r) + return -EFAULT; + *pos += sz; + if (hello->len < *pos) + hello->len = *pos; + return sz; } static int hello_release(struct inode *ino, struct file *fp) @@ -58,6 +86,7 @@ static const struct file_operations hello_fops = { .open = hello_open, .release = hello_release, .read = hello_read, + .write = hello_write, }; static int __init ch_init(void)