randpup.git
kernel.c

/* randpup - ngram text generator kernel module
* Copyright (C) 2025 ArcNyxx
* see LICENCE.MIT file for licensing information */
#include <linux/cdev.h>
#include <linux/fs.h>
#include <linux/init.h>
#include <linux/module.h>
#include "act.h"
MODULE_LICENSE("Dual MIT/GPL");
MODULE_AUTHOR("ArcNyxx");
MODULE_DESCRIPTION("puppygirl nonsense generator");
static int
pup_device_open(struct inode *inode, struct file *fp)
{
if ((fp->private_data = kmalloc(sizeof(pup_state_t),
GFP_KERNEL)) == NULL)
return -ENOMEM;
((pup_state_t *)(fp->private_data))->last = -1;
pup_reset(fp->private_data);
return 0;
}
static int
pup_device_close(struct inode *inode, struct file *fp)
{
kfree(fp->private_data);
fp->private_data = NULL;
return 0;
}
static ssize_t
pup_device_read(struct file *fp, char __user *buffer, size_t length,
loff_t *offset)
{
return pup_write(fp->private_data, buffer, length);
}
static struct file_operations fops = {
.open = pup_device_open,
.release = pup_device_close,
.read = pup_device_read
};
static dev_t pup_dev;
static struct cdev pup_cdev;
static struct class *pup_class;
static int
pup_module_uevent(const struct device *dev, struct kobj_uevent_env *env)
{
return add_uevent_var(env, "DEVMODE=%#o", 0666);
}
static int __init
pup_module_init(void)
{
if (alloc_chrdev_region(&pup_dev, 0, 1, "randpup") != 0)
return 1;
cdev_init(&pup_cdev, &fops);
pup_cdev.owner = THIS_MODULE;
if (cdev_add(&pup_cdev, pup_dev, 1) < 0) {
unregister_chrdev_region(pup_dev, 1);
return 1;
}
if (IS_ERR(pup_class = class_create("randpup"))) {
unregister_chrdev_region(pup_dev, 1);
cdev_del(&pup_cdev);
return 1;
}
pup_class->dev_uevent = pup_module_uevent;
if (IS_ERR(device_create(pup_class, NULL, pup_dev, NULL, "randpup"))) {
class_destroy(pup_class);
cdev_del(&pup_cdev);
unregister_chrdev_region(pup_dev, 1);
return 1;
}
return 0;
}
static void __exit
pup_module_exit(void)
{
device_destroy(pup_class, pup_dev);
class_destroy(pup_class);
cdev_del(&pup_cdev);
unregister_chrdev_region(pup_dev, 1);
}
module_init(pup_module_init);
module_exit(pup_module_exit);