Split input and output sides of the device model
authorhpa <hpa>
Tue, 23 Nov 2004 23:43:02 +0000 (23:43 +0000)
committerhpa <hpa>
Tue, 23 Nov 2004 23:43:02 +0000 (23:43 +0000)
24 files changed:
com32/include/console.h
com32/include/dev.h [new file with mode: 0644]
com32/include/unistd.h
com32/lib/Makefile
com32/lib/sys/close.c
com32/lib/sys/err_read.c [moved from com32/lib/sys/rawcon.c with 77% similarity]
com32/lib/sys/err_write.c [moved from com32/lib/sys/stdcon.c with 77% similarity]
com32/lib/sys/file.h
com32/lib/sys/fileclose.c
com32/lib/sys/fileread.c
com32/lib/sys/isatty.c
com32/lib/sys/line_input.c
com32/lib/sys/null_read.c [new file with mode: 0644]
com32/lib/sys/null_write.c [new file with mode: 0644]
com32/lib/sys/open.c
com32/lib/sys/openconsole.c
com32/lib/sys/opendev.c
com32/lib/sys/rawcon_read.c
com32/lib/sys/rawcon_write.c
com32/lib/sys/read.c
com32/lib/sys/stdcon_read.c
com32/lib/sys/stdcon_write.c
com32/lib/sys/write.c
com32/modules/hello.c

index 5db9165..5590427 100644 (file)
 #define _CONSOLE_H
 
 #include <klibc/extern.h>
+#include <dev.h>
 
-struct dev_info;
-__extern int openconsole(const struct dev_info *);
+__extern int openconsole(const struct input_dev *, const struct output_dev *);
 
 /* Standard line-oriented console */
-extern const struct dev_info dev_stdcon;
+extern const struct input_dev  dev_stdcon_r;
+extern const struct output_dev dev_stdcon_w;
 /* Raw character-oriented console */
-extern const struct dev_info dev_rawcon;
+extern const struct input_dev  dev_rawcon_r;
+extern const struct output_dev dev_rawcon_w;
 
 #endif /* _CONSOLE_H */
 
diff --git a/com32/include/dev.h b/com32/include/dev.h
new file mode 100644 (file)
index 0000000..a8cea76
--- /dev/null
@@ -0,0 +1,54 @@
+#ident "$Id$"
+/* ----------------------------------------------------------------------- *
+ *   
+ *   Copyright 2004 H. Peter Anvin - All Rights Reserved
+ *
+ *   Permission is hereby granted, free of charge, to any person
+ *   obtaining a copy of this software and associated documentation
+ *   files (the "Software"), to deal in the Software without
+ *   restriction, including without limitation the rights to use,
+ *   copy, modify, merge, publish, distribute, sublicense, and/or
+ *   sell copies of the Software, and to permit persons to whom
+ *   the Software is furnished to do so, subject to the following
+ *   conditions:
+ *   
+ *   The above copyright notice and this permission notice shall
+ *   be included in all copies or substantial portions of the Software.
+ *   
+ *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *   OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *   OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * console.h
+ *
+ * Alternative consoles
+ */
+
+#ifndef _DEV_H
+#define _DEV_H
+
+#include <klibc/extern.h>
+#include <stdint.h>
+
+struct input_dev;
+struct output_dev;
+
+__extern int opendev(const struct input_dev *, const struct output_dev *, int);
+
+/* Common generic devices */
+extern const struct input_dev  dev_null_r;
+extern const struct output_dev dev_null_w;
+
+extern const struct input_dev  dev_error_r;
+extern const struct output_dev dev_error_w;
+
+#endif /* _DEV_H */
+
index 76ce33a..84120d3 100644 (file)
@@ -13,8 +13,6 @@
 __extern __noreturn _exit(int);
 
 __extern int open(const char *, int, ...);
-struct dev_info;
-__extern int opendev(const struct dev_info *, int);
 __extern int close(int);
 
 __extern ssize_t read(int, void *, size_t);
index 0c1634a..0503459 100644 (file)
@@ -20,9 +20,11 @@ LIBOBJS = abort.o atexit.o atoi.o atol.o atoll.o calloc.o creat.o    \
        libgcc/__moddi3.o sys/entry.o sys/exit.o sys/fileinfo.o         \
        sys/opendev.o sys/read.o sys/write.o sys/close.o sys/open.o     \
        sys/fileread.o sys/fileclose.o sys/isatty.o sys/openconsole.o   \
-       sys/line_input.o sys/stdcon.o sys/stdcon_write.o                \
-       sys/stdcon_read.o sys/rawcon.o sys/rawcon_write.o               \
-       sys/rawcon_read.o
+       sys/line_input.o                                                \
+       sys/stdcon_read.o sys/stdcon_write.o                            \
+       sys/rawcon_read.o sys/rawcon_write.o                            \
+       sys/err_read.o    sys/err_write.o                               \
+       sys/null_read.o   sys/null_write.o                              \
 
 
 all: libcom32.a
index 9837d4b..765641f 100644 (file)
@@ -40,13 +40,19 @@ int close(int fd)
   struct file_info *fp = &__file_info[fd];
   int rv = 0;
 
-  if ( fd >= NFILES || !fp->ops ) {
+  if ( fd >= NFILES || !fp->iop || !fp->oop ) {
     errno = EBADF;
     return -1;
   }
 
-  if ( fp->ops->close ) {
-    rv = fp->ops->close(fp);
+  if ( fp->iop->close ) {
+    rv = fp->iop->close(fp);
+    if ( rv )
+      return rv;
+  }
+  
+  if ( fp->oop->close ) {
+    rv = fp->oop->close(fp);
     if ( rv )
       return rv;
   }
similarity index 77%
rename from com32/lib/sys/rawcon.c
rename to com32/lib/sys/err_read.c
index 4f168c0..c980889 100644 (file)
  * ----------------------------------------------------------------------- */
 
 /*
- * rawcon.c
+ * err_read.c
  *
- * Raw console
+ * Reading from a device which doesn't support reading
  */
 
 #include <errno.h>
 #include <string.h>
 #include <com32.h>
 #include <minmax.h>
-#include <fcntl.h>
-#include <console.h>
 #include "file.h"
 
-extern ssize_t __rawcon_read(struct file_info *, void *, size_t);
-extern ssize_t __rawcon_write(struct file_info *, const void *, size_t);
+static ssize_t __err_read(struct file_info *fp, void *buf, size_t count)
+{
+  (void)fp; (void)buf; (void)count;
+  errno = -EINVAL;
+  return -1;
+}
 
-const struct dev_info dev_rawcon = {
-  .dev_magic  = __DEV_MAGIC,
-  .flags      = __DEV_TTY,
-  .fileflags  = O_RDWR|O_CREAT|O_TRUNC|O_APPEND,
-  .read       = __rawcon_read,
-  .write      = __rawcon_write,
-  .close      = NULL,
+const struct input_dev dev_error_r = {
+  .dev_magic = __DEV_MAGIC,
+  .flags     = __DEV_INPUT | __DEV_ERROR,
+  .fileflags = O_RDONLY,
+  .read      = __err_read,
+  .close     = NULL,
 };
similarity index 77%
rename from com32/lib/sys/stdcon.c
rename to com32/lib/sys/err_write.c
index 7a83592..b0191c8 100644 (file)
  * ----------------------------------------------------------------------- */
 
 /*
- * stdcon.c
+ * err_write.c
  *
- * Default console
+ * Writing to a device which doesn't support writing
  */
 
 #include <errno.h>
 #include <string.h>
 #include <com32.h>
 #include <minmax.h>
-#include <fcntl.h>
-#include <console.h>
 #include "file.h"
 
-extern ssize_t __stdcon_read(struct file_info *, void *, size_t);
-extern ssize_t __stdcon_write(struct file_info *, const void *, size_t);
+static ssize_t __err_write(struct file_info *fp, const void *buf, size_t count)
+{
+  (void)fp; (void)buf; (void)count;
+  errno = -EINVAL;
+  return -1;
+}
 
-const struct dev_info dev_stdcon = {
-  .dev_magic  = __DEV_MAGIC,
-  .flags      = __DEV_TTY,
-  .fileflags  = O_RDWR|O_CREAT|O_TRUNC|O_APPEND,
-  .read       = __stdcon_read,
-  .write      = __stdcon_write,
-  .close      = NULL,
+const struct output_dev dev_error_w = {
+  .dev_magic = __DEV_MAGIC,
+  .flags     = __DEV_OUTPUT | __DEV_ERROR,
+  .fileflags = O_WRONLY | O_CREAT | O_TRUNC | O_APPEND,
+  .write     = __err_write,
+  .close     = NULL,
 };
index aae8e60..0096e8a 100644 (file)
@@ -1,7 +1,7 @@
 #ident "$Id$"
 /* ----------------------------------------------------------------------- *
  *   
- *   Copyright 2003 H. Peter Anvin - All Rights Reserved
+ *   Copyright 2003-2004 H. Peter Anvin - All Rights Reserved
  *
  *   Permission is hereby granted, free of charge, to any person
  *   obtaining a copy of this software and associated documentation
@@ -38,6 +38,8 @@
 #include <inttypes.h>
 #include <stdlib.h>
 #include <sys/types.h>
+#include <dev.h>
+#include <fcntl.h>
 
 /* Device structure; contains the relevant operations */
 
@@ -46,11 +48,22 @@ struct file_info;
 #define __DEV_MAGIC    0xf4e7
 #define __DEV_TTY      0x0001  /* TTY - must be bit 0 */
 #define __DEV_FILE     0x0002  /* Ordinary file */
-struct dev_info {
+#define __DEV_OUTPUT   0x0004  /* This is an output device */
+#define __DEV_INPUT    0       /* Dummy */
+#define __DEV_ERROR    0x0008  /* This is the error device */
+#define __DEV_NULL     0x0010  /* This is the null device */
+
+struct input_dev {
   uint16_t dev_magic;          /* Magic number */
   uint16_t flags;              /* Flags */
   int fileflags;               /* Permitted file flags */
   ssize_t (*read)(struct file_info *, void *, size_t);
+  int (*close)(struct file_info *);
+};
+struct output_dev {
+  uint16_t dev_magic;          /* Magic number */
+  uint16_t flags;              /* Flags */
+  int fileflags;
   ssize_t (*write)(struct file_info *, const void *, size_t);
   int (*close)(struct file_info *);
 };
@@ -61,21 +74,20 @@ struct dev_info {
 #define MAXBLOCK 16384         /* Defined by ABI */
 
 struct file_info {
-  const struct dev_info *ops;  /* Operations structure */
+  const struct input_dev *iop; /* Input operations */
+  const struct output_dev *oop;        /* Output operations */
 
-  union {
-    /* Structure used for ordinary files */
-    struct {
-      int blocklg2;            /* Blocksize log 2 */
-      size_t offset;           /* Current file offset */
-      size_t length;           /* Total file length */
-      uint16_t filedes;                /* File descriptor */
-      uint16_t _filler;                /* Unused */
-      size_t nbytes;           /* Number of bytes available in buffer */
-      char *datap;             /* Current data pointer */
-      char buf[MAXBLOCK];
-    } f;
-  } p;
+  /* Structure used for input blocking */
+  struct {
+    int blocklg2;              /* Blocksize log 2 */
+    size_t offset;             /* Current file offset */
+    size_t length;             /* Total file length */
+    uint16_t filedes;          /* File descriptor */
+    uint16_t _filler;          /* Unused */
+    size_t nbytes;             /* Number of bytes available in buffer */
+    char *datap;               /* Current data pointer */
+    char buf[MAXBLOCK];
+  } i;
 };
 
 extern struct file_info __file_info[NFILES];
index 5fb89f3..c35cad8 100644 (file)
@@ -41,10 +41,10 @@ int __file_close(struct file_info *fp)
 {
   com32sys_t regs;
 
-  if ( fp->p.f.filedes ) {
+  if ( fp->i.filedes ) {
     memset(&regs, 0, sizeof regs);
     regs.eax.w[0] = 0x0008;    /* Close file */
-    regs.esi.w[0] = fp->p.f.filedes;
+    regs.esi.w[0] = fp->i.filedes;
 
     __com32.cs_intcall(0x22, &regs, NULL);
   }
index 44609f2..b9cc0d0 100644 (file)
@@ -51,12 +51,12 @@ ssize_t __file_read(struct file_info *fp, void *buf, size_t count)
   ireg.es = SEG(__com32.cs_bounce);
 
   while ( count ) {
-    if ( fp->p.f.nbytes == 0 ) {
-      if ( fp->p.f.offset >= fp->p.f.length || !fp->p.f.filedes )
+    if ( fp->i.nbytes == 0 ) {
+      if ( fp->i.offset >= fp->i.length || !fp->i.filedes )
        return n;               /* As good as it gets... */
 
-      ireg.esi.w[0] = fp->p.f.filedes;
-      ireg.ecx.w[0] = MAXBLOCK >> fp->p.f.blocklg2;
+      ireg.esi.w[0] = fp->i.filedes;
+      ireg.ecx.w[0] = MAXBLOCK >> fp->i.blocklg2;
       
       __intcall(0x22, &ireg, &oreg);
 
@@ -65,21 +65,21 @@ ssize_t __file_read(struct file_info *fp, void *buf, size_t count)
        return -1;
       }
 
-      fp->p.f.filedes = ireg.esi.w[0];
-      fp->p.f.nbytes = min(fp->p.f.length-fp->p.f.offset, (unsigned)MAXBLOCK);
-      fp->p.f.datap = fp->p.f.buf;
-      memcpy(fp->p.f.buf, __com32.cs_bounce, fp->p.f.nbytes);
+      fp->i.filedes = ireg.esi.w[0];
+      fp->i.nbytes = min(fp->i.length-fp->i.offset, (unsigned)MAXBLOCK);
+      fp->i.datap = fp->i.buf;
+      memcpy(fp->i.buf, __com32.cs_bounce, fp->i.nbytes);
     }
 
-    ncopy = min(count, fp->p.f.nbytes);
-    memcpy(bufp, fp->p.f.datap, ncopy);
+    ncopy = min(count, fp->i.nbytes);
+    memcpy(bufp, fp->i.datap, ncopy);
 
     n += ncopy;
     bufp += ncopy;
     count -= ncopy;
-    fp->p.f.datap += ncopy;
-    fp->p.f.offset += ncopy;
-    fp->p.f.nbytes -= ncopy;
+    fp->i.datap += ncopy;
+    fp->i.offset += ncopy;
+    fp->i.nbytes -= ncopy;
   }
 
   return n;
index 8a8e646..39146c7 100644 (file)
@@ -44,10 +44,10 @@ int isatty(int fd)
 {
   struct file_info *fp = &__file_info[fd];
 
-  if ( fd >= NFILES || !fp->ops ) {
+  if ( fd >= NFILES || !fp->iop ) {
     errno = EBADF;
     return -1;
   }
 
-  return (fp->ops->flags & __DEV_TTY);
+  return (fp->iop->flags & __DEV_TTY);
 }
index c4dd8a5..e0de58b 100644 (file)
@@ -39,6 +39,8 @@ ssize_t __line_input(struct file_info *fp, char *buf, size_t bufsize,
 {
   size_t n = 0;
   char ch;
+  ssize_t (* const Write)(struct file_info *, const void *, size_t) =
+    fp->oop->write;
 
   for(;;) {
     if ( get_char(fp, &ch, 1) != 1 )
@@ -47,27 +49,27 @@ ssize_t __line_input(struct file_info *fp, char *buf, size_t bufsize,
     switch ( ch ) {
     case '\r':
       *buf = '\n';
-      fp->ops->write(fp, "\n", 1);
+      Write(fp, "\n", 1);
       return n+1;
     
     case '\b':
       if ( n > 0 ) {
        n--; buf--;
-       fp->ops->write(fp, "\b \b", 3);
+       Write(fp, "\b \b", 3);
       }
       break;
 
     case '\x15':               /* Ctrl-U */
       while ( n ) {
        n--; buf--;
-       fp->ops->write(fp, "\b \b", 3);
+       Write(fp, "\b \b", 3);
       }
       break;
       
     default:
       if ( n < bufsize-1 ) {
        *buf = ch;
-       fp->ops->write(fp, buf, 1);
+       Write(fp, buf, 1);
        n++;
        buf++;
       }
diff --git a/com32/lib/sys/null_read.c b/com32/lib/sys/null_read.c
new file mode 100644 (file)
index 0000000..8121fae
--- /dev/null
@@ -0,0 +1,53 @@
+#ident "$Id$"
+/* ----------------------------------------------------------------------- *
+ *   
+ *   Copyright 2004 H. Peter Anvin - All Rights Reserved
+ *
+ *   Permission is hereby granted, free of charge, to any person
+ *   obtaining a copy of this software and associated documentation
+ *   files (the "Software"), to deal in the Software without
+ *   restriction, including without limitation the rights to use,
+ *   copy, modify, merge, publish, distribute, sublicense, and/or
+ *   sell copies of the Software, and to permit persons to whom
+ *   the Software is furnished to do so, subject to the following
+ *   conditions:
+ *   
+ *   The above copyright notice and this permission notice shall
+ *   be included in all copies or substantial portions of the Software.
+ *   
+ *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *   OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *   OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * null_read.c
+ *
+ * Reading null device
+ */
+
+#include <errno.h>
+#include <string.h>
+#include <com32.h>
+#include <minmax.h>
+#include "file.h"
+
+static ssize_t __null_read(struct file_info *fp, void *buf, size_t count)
+{
+  (void)fp; (void)buf; (void)count;
+  return 0;
+}
+
+const struct input_dev dev_null_r = {
+  .dev_magic = __DEV_MAGIC,
+  .flags     = __DEV_INPUT | __DEV_NULL,
+  .fileflags = O_RDONLY,
+  .read      = __null_read,
+  .close     = NULL,
+};
diff --git a/com32/lib/sys/null_write.c b/com32/lib/sys/null_write.c
new file mode 100644 (file)
index 0000000..bebf34b
--- /dev/null
@@ -0,0 +1,53 @@
+#ident "$Id$"
+/* ----------------------------------------------------------------------- *
+ *   
+ *   Copyright 2004 H. Peter Anvin - All Rights Reserved
+ *
+ *   Permission is hereby granted, free of charge, to any person
+ *   obtaining a copy of this software and associated documentation
+ *   files (the "Software"), to deal in the Software without
+ *   restriction, including without limitation the rights to use,
+ *   copy, modify, merge, publish, distribute, sublicense, and/or
+ *   sell copies of the Software, and to permit persons to whom
+ *   the Software is furnished to do so, subject to the following
+ *   conditions:
+ *   
+ *   The above copyright notice and this permission notice shall
+ *   be included in all copies or substantial portions of the Software.
+ *   
+ *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *   OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *   OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * null_write.c
+ *
+ * Null writing device
+ */
+
+#include <errno.h>
+#include <string.h>
+#include <com32.h>
+#include <minmax.h>
+#include "file.h"
+
+static ssize_t __null_write(struct file_info *fp, const void *buf, size_t count)
+{
+  (void)fp; (void)buf; (void)count;
+  return count;
+}
+
+const struct output_dev dev_null_w = {
+  .dev_magic = __DEV_MAGIC,
+  .flags     = __DEV_OUTPUT | __DEV_NULL,
+  .fileflags = O_WRONLY | O_CREAT | O_TRUNC | O_APPEND,
+  .write     = __null_write,
+  .close     = NULL,
+};
index 139d104..433a8ec 100644 (file)
 extern ssize_t __file_read(struct file_info *, void *, size_t);
 extern int __file_close(struct file_info *);
 
-static const struct dev_info file_dev = {
+static const struct input_dev file_dev = {
   .dev_magic = __DEV_MAGIC,
-  .flags     = __DEV_FILE,
+  .flags     = __DEV_FILE | __DEV_INPUT,
   .fileflags = O_RDONLY,
   .read      = __file_read,
-  .write     = NULL,           /* File writes are not supported */
   .close     = __file_close,
 };
 
@@ -57,7 +56,7 @@ int open(const char *pathname, int flags, ...)
   int fd;
   struct file_info *fp;
 
-  fd = opendev(&file_dev, flags);
+  fd = opendev(&file_dev, NULL, flags);
 
   if ( fd < 0 )
     return -1;
@@ -80,12 +79,12 @@ int open(const char *pathname, int flags, ...)
   {
     uint16_t blklg2;
     asm("bsrw %1,%0" : "=r" (blklg2) : "rm" (regs.ecx.w[0]));
-    fp->p.f.blocklg2 = blklg2;
+    fp->i.blocklg2 = blklg2;
   }
-  fp->p.f.length    = regs.eax.l;
-  fp->p.f.filedes   = regs.esi.w[0];
-  fp->p.f.offset    = 0;
-  fp->p.f.nbytes    = 0;
+  fp->i.length    = regs.eax.l;
+  fp->i.filedes   = regs.esi.w[0];
+  fp->i.offset    = 0;
+  fp->i.nbytes    = 0;
 
   return fd;
 } 
index 08b584a..fbc277b 100644 (file)
 #include <console.h>
 #include <fcntl.h>
 
-int openconsole(const struct dev_info *dev)
+int openconsole(const struct input_dev *idev, const struct output_dev *odev)
 {
   close(0);
-  if ( opendev(dev, O_RDONLY) != 0 )
+  if ( opendev(idev, odev, O_RDONLY) != 0 )
     return -1;
   close(1);
-  if ( opendev(dev, O_WRONLY) != 1 )
+  if ( opendev(idev, odev, O_WRONLY) != 1 )
     return -1;
   close(2);
-  if ( opendev(dev, O_WRONLY) != 2 )
+  if ( opendev(idev, odev, O_WRONLY) != 2 )
     return -1;
 
   return 0;
index 4ef2fe9..4384d1e 100644 (file)
  * Open a special device
  */
 
-int opendev(const struct dev_info *dev, int flags)
+int opendev(const struct input_dev *idev, const struct output_dev *odev, int flags)
 {
   int fd;
   struct file_info *fp;
-  
-  if ( !(flags & 3) || (flags & ~dev->fileflags) ) {
+  int okflags;
+
+  okflags = (idev ? idev->fileflags : 0) | (odev ? odev->fileflags : 0);
+
+  if ( !(flags & 3) || (flags & ~okflags) ) {
     errno = EINVAL;
     return -1;
   }
 
   for ( fd = 0, fp = __file_info ; fd < NFILES ; fd++, fp++ )
-    if ( !fp->ops )
+    if ( !fp->iop && !fp->oop )
       break;
 
   if ( fd >= NFILES ) {
@@ -56,10 +59,11 @@ int opendev(const struct dev_info *dev, int flags)
     return -1;
   }
 
-  fp->ops = dev;
-  fp->p.f.offset    = 0;
-  fp->p.f.nbytes    = 0;
-  fp->p.f.datap     = fp->p.f.buf;
+  fp->iop         = idev ? idev : &dev_error_r;
+  fp->oop         = odev ? odev : &dev_error_w;
+  fp->i.offset    = 0;
+  fp->i.nbytes    = 0;
+  fp->i.datap     = fp->i.buf;
 
   return fd;
 }
index dfea96b..23a742b 100644 (file)
@@ -38,6 +38,7 @@
 #include <minmax.h>
 #include "file.h"
 
+/* Global, since it's used by stdcon_read */
 ssize_t __rawcon_read(struct file_info *fp, void *buf, size_t count)
 {
   com32sys_t ireg, oreg;
@@ -66,3 +67,11 @@ ssize_t __rawcon_read(struct file_info *fp, void *buf, size_t count)
 
   return n;
 }
+
+const struct input_dev dev_rawcon_r = {
+  .dev_magic  = __DEV_MAGIC,
+  .flags      = __DEV_TTY | __DEV_INPUT,
+  .fileflags  = O_RDONLY,
+  .read       = __rawcon_read,
+  .close      = NULL,
+};
index 8a037d2..329a116 100644 (file)
@@ -38,7 +38,7 @@
 #include <minmax.h>
 #include "file.h"
 
-ssize_t __rawcon_write(struct file_info *fp, const void *buf, size_t count)
+static ssize_t __rawcon_write(struct file_info *fp, const void *buf, size_t count)
 {
   com32sys_t ireg;
   const char *bufp = buf;
@@ -57,3 +57,11 @@ ssize_t __rawcon_write(struct file_info *fp, const void *buf, size_t count)
 
   return n;
 }
+
+const struct output_dev dev_rawcon_w = {
+  .dev_magic  = __DEV_MAGIC,
+  .flags      = __DEV_TTY | __DEV_OUTPUT,
+  .fileflags  = O_WRONLY | O_CREAT | O_TRUNC | O_APPEND,
+  .write      = __rawcon_write,
+  .close      = NULL,
+};
index ea5fde3..e461cd4 100644 (file)
@@ -43,15 +43,10 @@ ssize_t read(int fd, void *buf, size_t count)
 {
   struct file_info *fp = &__file_info[fd];
 
- if ( fd >= NFILES || !fp->ops ) {
+ if ( fd >= NFILES || !fp->iop ) {
     errno = EBADF;
     return -1;
   }
 
-  if ( __unlikely(!fp->ops->read) ) {
-    errno = EINVAL;
-    return -1;
-  }
-
-  return fp->ops->read(fp, buf, count);
+  return fp->iop->read(fp, buf, count);
 }
index 840e095..1f172cc 100644 (file)
@@ -40,7 +40,7 @@
 
 extern ssize_t __rawcon_read(struct file_info *fp, void *buf, size_t count);
 
-ssize_t __stdcon_read(struct file_info *fp, void *buf, size_t count)
+static ssize_t __stdcon_read(struct file_info *fp, void *buf, size_t count)
 {
   char *bufp = buf;
   size_t n = 0;
@@ -49,21 +49,29 @@ ssize_t __stdcon_read(struct file_info *fp, void *buf, size_t count)
   (void)fp;
 
   while ( n < count ) {
-    if ( fp->p.f.nbytes ) {
-      ch = *bufp++ = *fp->p.f.datap++;
-      fp->p.f.nbytes--;
+    if ( fp->i.nbytes ) {
+      ch = *bufp++ = *fp->i.datap++;
+      fp->i.nbytes--;
       n++;
       if ( ch == '\n' )
        return n;
     } else {
-      fp->p.f.nbytes = __line_input(fp, fp->p.f.buf, MAXBLOCK,
+      fp->i.nbytes = __line_input(fp, fp->i.buf, MAXBLOCK,
                                    __rawcon_read);
-      fp->p.f.datap = fp->p.f.buf;
+      fp->i.datap = fp->i.buf;
 
-      if ( fp->p.f.nbytes == 0 )
+      if ( fp->i.nbytes == 0 )
        return n;
     }
   }
 
   return n;
 }
+
+const struct input_dev dev_stdcon_r = {
+  .dev_magic  = __DEV_MAGIC,
+  .flags      = __DEV_TTY | __DEV_INPUT,
+  .fileflags  = O_RDONLY,
+  .read       = __stdcon_read,
+  .close      = NULL,
+};
index 9cfd07f..d5f9185 100644 (file)
@@ -38,7 +38,7 @@
 #include <minmax.h>
 #include "file.h"
 
-ssize_t __stdcon_write(struct file_info *fp, const void *buf, size_t count)
+static ssize_t __stdcon_write(struct file_info *fp, const void *buf, size_t count)
 {
   com32sys_t ireg;
   const char *bufp = buf;
@@ -61,3 +61,11 @@ ssize_t __stdcon_write(struct file_info *fp, const void *buf, size_t count)
 
   return n;
 }
+
+const struct output_dev dev_stdcon_w = {
+  .dev_magic  = __DEV_MAGIC,
+  .flags      = __DEV_TTY | __DEV_OUTPUT,
+  .fileflags  = O_WRONLY | O_CREAT | O_TRUNC | O_APPEND,
+  .write      = __stdcon_write,
+  .close      = NULL,
+};
index b4b3c6e..2e27d6f 100644 (file)
@@ -43,15 +43,10 @@ ssize_t write(int fd, void *buf, size_t count)
 {
   struct file_info *fp = &__file_info[fd];
 
-  if ( fd >= NFILES || !fp->ops ) {
+  if ( fd >= NFILES || !fp->oop ) {
     errno = EBADF;
     return -1;
   }
 
-  if ( __unlikely(!fp->ops->write) ) {
-    errno = EINVAL;
-    return -1;
-  }
-
-  return fp->ops->write(fp, buf, count);
+  return fp->oop->write(fp, buf, count);
 }
index aea8766..98964e0 100644 (file)
@@ -25,7 +25,7 @@ int main(void)
 {
   char buffer[1024];
 
-  openconsole(&dev_stdcon);
+  openconsole(&dev_stdcon_r, &dev_stdcon_w);
 
   printf("Hello, World!\n");