From 3eaa68f9163cc890dde3733b2dfa9ec0f774c360 Mon Sep 17 00:00:00 2001 From: hpa Date: Tue, 23 Nov 2004 23:43:02 +0000 Subject: [PATCH] Split input and output sides of the device model --- com32/include/console.h | 10 +++--- com32/include/dev.h | 54 +++++++++++++++++++++++++++++++++ com32/include/unistd.h | 2 -- com32/lib/Makefile | 8 +++-- com32/lib/sys/close.c | 12 ++++++-- com32/lib/sys/{rawcon.c => err_read.c} | 27 +++++++++-------- com32/lib/sys/{stdcon.c => err_write.c} | 27 +++++++++-------- com32/lib/sys/file.h | 44 +++++++++++++++++---------- com32/lib/sys/fileclose.c | 4 +-- com32/lib/sys/fileread.c | 26 ++++++++-------- com32/lib/sys/isatty.c | 4 +-- com32/lib/sys/line_input.c | 10 +++--- com32/lib/sys/null_read.c | 53 ++++++++++++++++++++++++++++++++ com32/lib/sys/null_write.c | 53 ++++++++++++++++++++++++++++++++ com32/lib/sys/open.c | 17 +++++------ com32/lib/sys/openconsole.c | 8 ++--- com32/lib/sys/opendev.c | 20 +++++++----- com32/lib/sys/rawcon_read.c | 9 ++++++ com32/lib/sys/rawcon_write.c | 10 +++++- com32/lib/sys/read.c | 9 ++---- com32/lib/sys/stdcon_read.c | 22 +++++++++----- com32/lib/sys/stdcon_write.c | 10 +++++- com32/lib/sys/write.c | 9 ++---- com32/modules/hello.c | 2 +- 24 files changed, 330 insertions(+), 120 deletions(-) create mode 100644 com32/include/dev.h rename com32/lib/sys/{rawcon.c => err_read.c} (77%) rename com32/lib/sys/{stdcon.c => err_write.c} (77%) create mode 100644 com32/lib/sys/null_read.c create mode 100644 com32/lib/sys/null_write.c diff --git a/com32/include/console.h b/com32/include/console.h index 5db9165..5590427 100644 --- a/com32/include/console.h +++ b/com32/include/console.h @@ -36,14 +36,16 @@ #define _CONSOLE_H #include +#include -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 index 0000000..a8cea76 --- /dev/null +++ b/com32/include/dev.h @@ -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 +#include + +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 */ + diff --git a/com32/include/unistd.h b/com32/include/unistd.h index 76ce33a..84120d3 100644 --- a/com32/include/unistd.h +++ b/com32/include/unistd.h @@ -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); diff --git a/com32/lib/Makefile b/com32/lib/Makefile index 0c1634a..0503459 100644 --- a/com32/lib/Makefile +++ b/com32/lib/Makefile @@ -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 diff --git a/com32/lib/sys/close.c b/com32/lib/sys/close.c index 9837d4b..765641f 100644 --- a/com32/lib/sys/close.c +++ b/com32/lib/sys/close.c @@ -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; } diff --git a/com32/lib/sys/rawcon.c b/com32/lib/sys/err_read.c similarity index 77% rename from com32/lib/sys/rawcon.c rename to com32/lib/sys/err_read.c index 4f168c0..c980889 100644 --- a/com32/lib/sys/rawcon.c +++ b/com32/lib/sys/err_read.c @@ -27,27 +27,28 @@ * ----------------------------------------------------------------------- */ /* - * rawcon.c + * err_read.c * - * Raw console + * Reading from a device which doesn't support reading */ #include #include #include #include -#include -#include #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, }; diff --git a/com32/lib/sys/stdcon.c b/com32/lib/sys/err_write.c similarity index 77% rename from com32/lib/sys/stdcon.c rename to com32/lib/sys/err_write.c index 7a83592..b0191c8 100644 --- a/com32/lib/sys/stdcon.c +++ b/com32/lib/sys/err_write.c @@ -27,27 +27,28 @@ * ----------------------------------------------------------------------- */ /* - * stdcon.c + * err_write.c * - * Default console + * Writing to a device which doesn't support writing */ #include #include #include #include -#include -#include #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, }; diff --git a/com32/lib/sys/file.h b/com32/lib/sys/file.h index aae8e60..0096e8a 100644 --- a/com32/lib/sys/file.h +++ b/com32/lib/sys/file.h @@ -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 #include #include +#include +#include /* 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]; diff --git a/com32/lib/sys/fileclose.c b/com32/lib/sys/fileclose.c index 5fb89f3..c35cad8 100644 --- a/com32/lib/sys/fileclose.c +++ b/com32/lib/sys/fileclose.c @@ -41,10 +41,10 @@ int __file_close(struct file_info *fp) { com32sys_t regs; - if ( fp->p.f.filedes ) { + if ( fp->i.filedes ) { memset(®s, 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, ®s, NULL); } diff --git a/com32/lib/sys/fileread.c b/com32/lib/sys/fileread.c index 44609f2..b9cc0d0 100644 --- a/com32/lib/sys/fileread.c +++ b/com32/lib/sys/fileread.c @@ -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; diff --git a/com32/lib/sys/isatty.c b/com32/lib/sys/isatty.c index 8a8e646..39146c7 100644 --- a/com32/lib/sys/isatty.c +++ b/com32/lib/sys/isatty.c @@ -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); } diff --git a/com32/lib/sys/line_input.c b/com32/lib/sys/line_input.c index c4dd8a5..e0de58b 100644 --- a/com32/lib/sys/line_input.c +++ b/com32/lib/sys/line_input.c @@ -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 index 0000000..8121fae --- /dev/null +++ b/com32/lib/sys/null_read.c @@ -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 +#include +#include +#include +#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 index 0000000..bebf34b --- /dev/null +++ b/com32/lib/sys/null_write.c @@ -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 +#include +#include +#include +#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, +}; diff --git a/com32/lib/sys/open.c b/com32/lib/sys/open.c index 139d104..433a8ec 100644 --- a/com32/lib/sys/open.c +++ b/com32/lib/sys/open.c @@ -42,12 +42,11 @@ 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; } diff --git a/com32/lib/sys/openconsole.c b/com32/lib/sys/openconsole.c index 08b584a..fbc277b 100644 --- a/com32/lib/sys/openconsole.c +++ b/com32/lib/sys/openconsole.c @@ -36,16 +36,16 @@ #include #include -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; diff --git a/com32/lib/sys/opendev.c b/com32/lib/sys/opendev.c index 4ef2fe9..4384d1e 100644 --- a/com32/lib/sys/opendev.c +++ b/com32/lib/sys/opendev.c @@ -37,18 +37,21 @@ * 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; } diff --git a/com32/lib/sys/rawcon_read.c b/com32/lib/sys/rawcon_read.c index dfea96b..23a742b 100644 --- a/com32/lib/sys/rawcon_read.c +++ b/com32/lib/sys/rawcon_read.c @@ -38,6 +38,7 @@ #include #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, +}; diff --git a/com32/lib/sys/rawcon_write.c b/com32/lib/sys/rawcon_write.c index 8a037d2..329a116 100644 --- a/com32/lib/sys/rawcon_write.c +++ b/com32/lib/sys/rawcon_write.c @@ -38,7 +38,7 @@ #include #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, +}; diff --git a/com32/lib/sys/read.c b/com32/lib/sys/read.c index ea5fde3..e461cd4 100644 --- a/com32/lib/sys/read.c +++ b/com32/lib/sys/read.c @@ -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); } diff --git a/com32/lib/sys/stdcon_read.c b/com32/lib/sys/stdcon_read.c index 840e095..1f172cc 100644 --- a/com32/lib/sys/stdcon_read.c +++ b/com32/lib/sys/stdcon_read.c @@ -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, +}; diff --git a/com32/lib/sys/stdcon_write.c b/com32/lib/sys/stdcon_write.c index 9cfd07f..d5f9185 100644 --- a/com32/lib/sys/stdcon_write.c +++ b/com32/lib/sys/stdcon_write.c @@ -38,7 +38,7 @@ #include #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, +}; diff --git a/com32/lib/sys/write.c b/com32/lib/sys/write.c index b4b3c6e..2e27d6f 100644 --- a/com32/lib/sys/write.c +++ b/com32/lib/sys/write.c @@ -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); } diff --git a/com32/modules/hello.c b/com32/modules/hello.c index aea8766..98964e0 100644 --- a/com32/modules/hello.c +++ b/com32/modules/hello.c @@ -25,7 +25,7 @@ int main(void) { char buffer[1024]; - openconsole(&dev_stdcon); + openconsole(&dev_stdcon_r, &dev_stdcon_w); printf("Hello, World!\n"); -- 2.7.4