Check block extra_len in checkb()
[akaros.git] / kern / src / devfs.c
index 4a6817a..7bcdb51 100644 (file)
@@ -14,6 +14,7 @@
 #include <smp.h>
 #include <umem.h>
 #include <kmalloc.h>
+#include <console.h>
 
 /* These structs are declared again and initialized farther down */
 struct file_operations dev_f_op_stdin;
@@ -49,7 +50,7 @@ void devfs_init(void)
 struct file *make_device(char *path, int mode, int type,
                          struct file_operations *fop)
 {
-       struct file *f_dev = do_file_open(path, O_CREAT, mode);
+       struct file *f_dev = do_file_open(path, O_CREAT | O_RDWR, mode);
        assert(f_dev);
        /* Overwrite the f_op with our own f_ops */
        f_dev->f_dentry->d_inode->i_fop = fop;
@@ -61,8 +62,7 @@ struct file *make_device(char *path, int mode, int type,
 /* We provide a separate set of f_ops for devices (char and block), and the fops
  * is the only thing that differs from the regular KFS.  We need to do some
  * ghetto-overriding of these ops after we create them. */
-
-off_t dev_c_llseek(struct file *file, off_t offset, int whence)
+int dev_c_llseek(struct file *file, off64_t offset, off64_t *ret, int whence)
 {
        set_errno(EINVAL);
        return -1;
@@ -75,27 +75,27 @@ int dev_mmap(struct file *file, struct vm_region *vmr)
        return -1;
 }
 
+/* this is really /dev/console, and will need some tty work.  for now, no matter
+ * how much they ask for, we return one character at a time. */
 ssize_t dev_stdin_read(struct file *file, char *buf, size_t count,
-                       off_t *offset)
+                       off64_t *offset)
 {
-       int read_amt;
-       char *kbuf = kmalloc(count, 0);
-       memset(kbuf, 0, count);// TODO REMOVE ME
-       read_amt = readline(kbuf, count, 0);
-       assert(read_amt <= count);
-       /* applications (ash) expect a \n instead of a \r */
-       if (kbuf[read_amt - 1] == '\r')
-               kbuf[read_amt - 1] = '\n';
+       char c;
+       extern struct kb_buffer cons_buf;
+
+       if (!count)
+               return 0;
+       kb_get_from_buf(&cons_buf, &c, 1);
        /* TODO UMEM */
        if (current)
-               memcpy_to_user_errno(current, buf, kbuf, read_amt);
+               memcpy_to_user_errno(current, buf, &c, 1);
        else
-               memcpy(buf, kbuf, read_amt);
-       return read_amt;
+               memcpy(buf, &c, 1);
+       return 1;
 }
 
 ssize_t dev_stdout_write(struct file *file, const char *buf, size_t count,
-                         off_t *offset)
+                         off64_t *offset)
 {
        char *t_buf;
        struct proc *p = current;
@@ -105,7 +105,14 @@ ssize_t dev_stdout_write(struct file *file, const char *buf, size_t count,
                t_buf = (char*)buf;
        if (!t_buf)
                return -1;
-       printk("%s", t_buf);
+       /* TODO: tty hack.  they are sending us an escape sequence, and the keyboard
+        * would try to print it (which it can't do yet).  The hack is even dirtier
+        * in that we only detect it if it is the first char, and we ignore
+        * everything else. */
+       if (t_buf[0] != '\033') /* 0x1b */
+               cputbuf(t_buf, count);
+       if (p)
+               user_memdup_free(p, t_buf);
        return count;
 }
 
@@ -144,16 +151,22 @@ struct file_operations dev_f_op_stdout = {
        kfs_check_flags,
 };
 
+ssize_t dev_null_read(struct file *file, char *buf, size_t count,
+                      off64_t *offset)
+{
+       return 0;
+}
+
 /* /dev/null: just take whatever was given and pretend it was written */
 ssize_t dev_null_write(struct file *file, const char *buf, size_t count,
-                       off_t *offset)
+                       off64_t *offset)
 {
        return count;
 }
 
 struct file_operations dev_f_op_null = {
        dev_c_llseek,
-       0,      /* read - can't read null */
+       dev_null_read,
        dev_null_write,
        kfs_readdir,    /* this will fail gracefully */
        dev_mmap,