aboutsummaryrefslogtreecommitdiff
path: root/linux/fs/char_dev.c
diff options
context:
space:
mode:
Diffstat (limited to 'linux/fs/char_dev.c')
-rw-r--r--linux/fs/char_dev.c50
1 files changed, 50 insertions, 0 deletions
diff --git a/linux/fs/char_dev.c b/linux/fs/char_dev.c
new file mode 100644
index 0000000..e974242
--- /dev/null
+++ b/linux/fs/char_dev.c
@@ -0,0 +1,50 @@
+#include <errno.h>
+
+#include <linux/sched.h>
+#include <linux/kernel.h>
+
+extern int tty_read(unsigned minor,char * buf,int count);
+extern int tty_write(unsigned minor,char * buf,int count);
+
+static int rw_ttyx(int rw,unsigned minor,char * buf,int count);
+static int rw_tty(int rw,unsigned minor,char * buf,int count);
+
+typedef (*crw_ptr)(int rw,unsigned minor,char * buf,int count);
+
+#define NRDEVS ((sizeof (crw_table))/(sizeof (crw_ptr)))
+
+static crw_ptr crw_table[]={
+ NULL, /* nodev */
+ NULL, /* /dev/mem */
+ NULL, /* /dev/fd */
+ NULL, /* /dev/hd */
+ rw_ttyx, /* /dev/ttyx */
+ rw_tty, /* /dev/tty */
+ NULL, /* /dev/lp */
+ NULL}; /* unnamed pipes */
+
+static int rw_ttyx(int rw,unsigned minor,char * buf,int count)
+{
+ return ((rw==READ)?tty_read(minor,buf,count):
+ tty_write(minor,buf,count));
+}
+
+static int rw_tty(int rw,unsigned minor,char * buf,int count)
+{
+ if (current->tty<0)
+ return -EPERM;
+ return rw_ttyx(rw,current->tty,buf,count);
+}
+
+int rw_char(int rw,int dev, char * buf, int count)
+{
+ crw_ptr call_addr;
+
+ if (MAJOR(dev)>=NRDEVS)
+ panic("rw_char: dev>NRDEV");
+ if (!(call_addr=crw_table[MAJOR(dev)])) {
+ printk("dev: %04x\n",dev);
+ panic("Trying to r/w from/to nonexistent character device");
+ }
+ return call_addr(rw,MINOR(dev),buf,count);
+}