MODULE_DESCRIPTION("A hello world char device");
MODULE_VERSION("1.0.0");
+#define BUFFER_SIZE 4096
+
/* Message buffer we send to upstream */
-static char hello_message[] = "hello, world\n";
-static char goodbye_message[] = "goodbye, world\n";
+static char *hello_message;
+static char *goodbye_message;
struct message {
char *text;
return -ENOMEM;
if (iminor(ino) == 0) {
msg->text = hello_message;
- msg->len = sizeof(hello_message);
+ msg->len = BUFFER_SIZE;
} else {
msg->text = goodbye_message;
- msg->len = sizeof(goodbye_message);
+ msg->len = BUFFER_SIZE;
}
filp->private_data = msg;
return 0;
return len;
}
+static ssize_t helloc_write(struct file *filp, const char __user *buf,
+ size_t len, loff_t *pos)
+{
+ int r;
+ struct message *msg = filp->private_data;
+ /* do not read pass through the size of the message */
+ if (*pos >= msg->len)
+ /* return end of file */
+ return 0;
+ /* if len is bigger than the rest of the message, clamp it */
+ if (len > msg->len - *pos)
+ len = msg->len - *pos;
+ /* copy message to user space and return error if it fails */
+ r = copy_from_user(msg->text + *pos, buf, len);
+ if (r)
+ return -EFAULT;
+ /* update the file position */
+ *pos += len;
+ return len;
+}
+
/* we only implement read */
static struct file_operations helloc_fops = {
.owner = THIS_MODULE,
.open = helloc_open,
.release = helloc_release,
.read = helloc_read,
+ .write = helloc_write,
};
/* the device number and the char device struct */
static int __init helloc_init(void)
{
- int r;
+ int r = -ENOMEM;
/* allocate any major number with only one minor */
+ hello_message = kzalloc(BUFFER_SIZE, GFP_KERNEL);
+ if (!hello_message)
+ goto out_hello;
+ goodbye_message = kzalloc(BUFFER_SIZE, GFP_KERNEL);
+ if (!goodbye_message)
+ goto out_goodbye;
r = alloc_chrdev_region(&dev, 0, 2, "helloc");
if (r)
goto out_region;
/* release the device number allocated */
unregister_chrdev_region(dev, 2);
out_region:
+ kfree(goodbye_message);
+out_goodbye:
+ kfree(hello_message);
+out_hello:
return r;
}
cdev_del(cdev);
/* release the device number allocated */
unregister_chrdev_region(dev, 2);
+ kfree(goodbye_message);
+ kfree(hello_message);
}
module_init(helloc_init);