doesnt work (not for my kernel version at least)
authorJann Horn <jann@thejh.net>
Sat, 18 May 2013 22:58:26 +0000 (00:58 +0200)
committerJann Horn <jann@thejh.net>
Sat, 18 May 2013 22:58:26 +0000 (00:58 +0200)
Makefile [new file with mode: 0644]
README [new file with mode: 0644]
moctel_mod.c [new file with mode: 0644]

diff --git a/Makefile b/Makefile
new file mode 100644 (file)
index 0000000..ac7b8da
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,9 @@
+obj-m := moctel_mod.o
+KDIR := /lib/modules/$(shell uname -r)/build
+PWD := $(shell pwd)
+all:
+       $(MAKE) -C $(KDIR) M=$(PWD) modules
+clean:
+       $(MAKE) -C $(KDIR) M=$(PWD) clean
diff --git a/README b/README
new file mode 100644 (file)
index 0000000..3e5ad18
--- /dev/null
+++ b/README
@@ -0,0 +1 @@
+master io-c-te-el-s. but moctel sounds better than mocteel.
diff --git a/moctel_mod.c b/moctel_mod.c
new file mode 100644 (file)
index 0000000..bb0652e
--- /dev/null
@@ -0,0 +1,76 @@
+#undef __KERNEL__
+#define __KERNEL__
+#undef MODULE
+#define MODULE
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/file.h>
+#include <linux/fs.h>
+#include <linux/ioctl.h>
+#include <linux/uaccess.h>
+#include <linux/miscdevice.h>
+
+struct fetch_fops_args {
+  int fd;
+  u64 retp;
+};
+
+#define MOCTEL_FETCH_FOPS _IOR('m', 1, struct fetch_fops_args)
+
+static int ioctl_open(struct inode *nodp, struct file *filp) {
+  return 0;
+}
+
+static const struct file_operations dummy_fops = {};
+
+static long ioctl_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) {
+  struct fetch_fops_args args;
+  struct fd f;
+  const struct file_operations *fops;
+
+  if (cmd != MOCTEL_FETCH_FOPS) return -EINVAL;
+  if (copy_from_user(&args, (struct fetch_fops_args __user *)arg, sizeof(args))) return -EINVAL;
+  f = fdget(args.fd);
+  if (!f.file) return -EBADF;
+  fops = f.file->f_op;
+  if (!fops) fops = dummy_fops;
+  fdput(f);
+  if (copy_to_user((struct file_operations __user *)args.retp, fops, sizeof(*fops))) return -EINVAL;
+  return 0;
+}
+
+static int ioctl_release(struct inode *nodp, struct file *filp) {
+  return 0;
+}
+
+static const struct file_operations ioctl_fops = {
+  .owner = THIS_MODULE,
+  .ioctl = ioctl_ioctl, /* I have no idea about locking,
+                           so just take the Big Kernel Lock implicitly. */
+  .open = ioctl_open,
+  .release = ioctl_release
+};
+
+static struct miscdevice ioctl_miscdev = {
+  .minor = 0,
+  .name = "ioctl_info",
+  .fops = &ioctl_fops
+};
+
+static int __init init_ioctl() {
+  int ret;
+  printk(KERN_INFO "loading ioctl helper\n");
+
+  ret = misc_register(&ioctl_miscdev);
+  return ret;
+}
+
+static void __exit cleanup_ioctl() {
+  printk(KERN_INFO "unloading ioctl helper\n");
+  misc_deregister(&ioctl_miscdev);
+}
+
+module_init(init_ioctl);
+module_exit(cleanup_ioctl);