summaryrefslogtreecommitdiff
path: root/com32
diff options
context:
space:
mode:
authorhpa <hpa>2004-11-17 05:52:45 +0000
committerhpa <hpa>2004-11-17 05:52:45 +0000
commit8aada67545460566c9be6a3e021260509e8edaee (patch)
tree443a4442dc20031c8d42229a7c5b9e2ba2f33aae /com32
parent17f967640cef484f83d755c9dd016a946711236f (diff)
downloadsyslinux-8aada67545460566c9be6a3e021260509e8edaee.tar.gz
Very basic operations now work; need to handle line-oriented
versus character-oriented input
Diffstat (limited to 'com32')
-rw-r--r--com32/include/console.h46
-rw-r--r--com32/include/fcntl.h24
-rw-r--r--com32/include/stdio.h2
-rw-r--r--com32/include/sys/stat.h43
-rw-r--r--com32/include/unistd.h31
-rw-r--r--com32/lib/Makefile9
-rw-r--r--com32/lib/abort.c9
-rw-r--r--com32/lib/sys/close.c15
-rw-r--r--com32/lib/sys/file.h50
-rw-r--r--com32/lib/sys/fileclose.c53
-rw-r--r--com32/lib/sys/fileread.c86
-rw-r--r--com32/lib/sys/isatty.c53
-rw-r--r--com32/lib/sys/open.c51
-rw-r--r--com32/lib/sys/openconsole.c52
-rw-r--r--com32/lib/sys/opendev.c62
-rw-r--r--com32/lib/sys/read.c49
-rw-r--r--com32/lib/sys/stdcon.c53
-rw-r--r--com32/lib/sys/stdcon_read.c68
-rw-r--r--com32/lib/sys/stdcon_write.c63
-rw-r--r--com32/lib/sys/write.c21
-rw-r--r--com32/modules/Makefile5
-rw-r--r--com32/modules/hello.c14
22 files changed, 746 insertions, 113 deletions
diff --git a/com32/include/console.h b/com32/include/console.h
new file mode 100644
index 00000000..78025fb8
--- /dev/null
+++ b/com32/include/console.h
@@ -0,0 +1,46 @@
+#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 _CONSOLE_H
+#define _CONSOLE_H
+
+#include <klibc/extern.h>
+
+struct dev_info;
+__extern int openconsole(const struct dev_info *);
+
+extern const struct dev_info dev_stdcon;
+
+#endif /* _CONSOLE_H */
+
diff --git a/com32/include/fcntl.h b/com32/include/fcntl.h
new file mode 100644
index 00000000..b691b5cd
--- /dev/null
+++ b/com32/include/fcntl.h
@@ -0,0 +1,24 @@
+/*
+ * fcntl.h
+ */
+
+#ifndef _FCNTL_H
+#define _FCNTL_H
+
+#include <klibc/extern.h>
+#include <klibc/compiler.h>
+#include <sys/types.h>
+
+/* None of these are actually supported, although O_RDONLY works */
+/* Note this is different from the classical Unix way of doing it */
+#define O_RDONLY 1
+#define O_WRONLY 2
+#define O_RDWR 3
+#define O_CREAT 0100
+#define O_EXCL 0200
+#define O_TRUNC 01000
+#define O_APPEND 02000
+
+__extern int open(const char *, int, ...);
+
+#endif /* _FCNTL_H */
diff --git a/com32/include/stdio.h b/com32/include/stdio.h
index e40a3af8..0ebe922d 100644
--- a/com32/include/stdio.h
+++ b/com32/include/stdio.h
@@ -47,6 +47,8 @@ static __inline__ int fileno(FILE *__f)
#define stderr __create_file(2)
__extern FILE *fopen(const char *, const char *);
+struct dev_info;
+__extern FILE *fopendev(const struct dev_info *, const char *);
static __inline__ FILE *fdopen(int __fd, const char *__m)
{
diff --git a/com32/include/sys/stat.h b/com32/include/sys/stat.h
new file mode 100644
index 00000000..c0afb914
--- /dev/null
+++ b/com32/include/sys/stat.h
@@ -0,0 +1,43 @@
+/*
+ * sys/stat.h
+ */
+
+#ifndef _SYS_STAT_H
+#define _SYS_STAT_H
+
+#include <sys/types.h>
+
+/* We don't use this, but it's there for compatibility */
+
+#define S_IFMT 00170000
+#define S_IFSOCK 0140000
+#define S_IFLNK 0120000
+#define S_IFREG 0100000
+#define S_IFBLK 0060000
+#define S_IFDIR 0040000
+#define S_IFCHR 0020000
+#define S_IFIFO 0010000
+#define S_ISUID 0004000
+#define S_ISGID 0002000
+#define S_ISVTX 0001000
+#define S_ISLNK(m) (((m) & S_IFMT) == S_IFLNK)
+#define S_ISREG(m) (((m) & S_IFMT) == S_IFREG)
+#define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR)
+#define S_ISCHR(m) (((m) & S_IFMT) == S_IFCHR)
+#define S_ISBLK(m) (((m) & S_IFMT) == S_IFBLK)
+#define S_ISFIFO(m) (((m) & S_IFMT) == S_IFIFO)
+#define S_ISSOCK(m) (((m) & S_IFMT) == S_IFSOCK)
+#define S_IRWXU 00700
+#define S_IRUSR 00400
+#define S_IWUSR 00200
+#define S_IXUSR 00100
+#define S_IRWXG 00070
+#define S_IRGRP 00040
+#define S_IWGRP 00020
+#define S_IXGRP 00010
+#define S_IRWXO 00007
+#define S_IROTH 00004
+#define S_IWOTH 00002
+#define S_IXOTH 00001
+
+#endif /* _SYS_STAT_H */
diff --git a/com32/include/unistd.h b/com32/include/unistd.h
new file mode 100644
index 00000000..76ce33ae
--- /dev/null
+++ b/com32/include/unistd.h
@@ -0,0 +1,31 @@
+/*
+ * unistd.h
+ */
+
+#ifndef _UNISTD_H
+#define _UNISTD_H
+
+#include <klibc/extern.h>
+#include <klibc/compiler.h>
+#include <stddef.h>
+#include <sys/types.h>
+
+__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);
+__extern ssize_t write(int, const void *, size_t);
+
+__extern int isatty(int);
+
+
+/* Standard file descriptor numbers. */
+#define STDIN_FILENO 0
+#define STDOUT_FILENO 1
+#define STDERR_FILENO 2
+
+#endif /* _UNISTD_H */
diff --git a/com32/lib/Makefile b/com32/lib/Makefile
index 6b5ab015..857f8fb5 100644
--- a/com32/lib/Makefile
+++ b/com32/lib/Makefile
@@ -77,11 +77,10 @@ LIBOBJS = \
vsprintf.o \
vsscanf.o \
sys/entry.o sys/exit.o \
- sys/open.o \
- sys/fileinfo.o \
- sys/close.o \
- sys/read.o \
- sys/write.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/stdcon.o sys/stdcon_write.o sys/stdcon_read.o
all: libcom32.a
diff --git a/com32/lib/abort.c b/com32/lib/abort.c
index 9280d986..aacfbbf4 100644
--- a/com32/lib/abort.c
+++ b/com32/lib/abort.c
@@ -4,16 +4,9 @@
#include <stdlib.h>
#include <unistd.h>
-#include <signal.h>
void abort(void)
{
- sigset_t set;
-
- sigemptyset(&set);
- sigaddset(&set, SIGABRT);
- sigprocmask(SIG_UNBLOCK, &set, NULL);
- raise(SIGABRT);
- _exit(255); /* raise() should have killed us */
+ _exit(255);
}
diff --git a/com32/lib/sys/close.c b/com32/lib/sys/close.c
index b81d77ef..7af7ff13 100644
--- a/com32/lib/sys/close.c
+++ b/com32/lib/sys/close.c
@@ -37,21 +37,20 @@
int close(int fd)
{
- com32sys_t regs;
struct file_info *fp = &__file_info[fd];
+ int rv = 0;
- if ( fd >= NFILES || fp->blocklg2 == 0 ) {
+ if ( fd >= NFILES || !fp->ops ) {
errno = EBADF;
return -1;
}
- if ( fp->filedes ) {
- memset(&regs, 0, sizeof regs);
- regs.eax.w[0] = 0x0008; /* Close file */
- regs.esi.w[0] = fp->filedes;
-
- __com32.cs_intcall(0x22, &regs, NULL);
+ if ( fp->ops->close ) {
+ rv = fp->ops->close(fp);
+ if ( rv )
+ return rv;
}
+ fp->ops = NULL; /* File structure unused */
return 0;
}
diff --git a/com32/lib/sys/file.h b/com32/lib/sys/file.h
index 6a56f587..194c35df 100644
--- a/com32/lib/sys/file.h
+++ b/com32/lib/sys/file.h
@@ -39,31 +39,45 @@
#include <stdlib.h>
#include <sys/types.h>
-/* Ordinary file */
+/* Device structure; contains the relevant operations */
+
+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 {
+ uint16_t dev_magic; /* Magic number */
+ uint16_t flags; /* Flags */
+ int fileflags; /* Permitted file flags */
+ ssize_t (*read)(struct file_info *, void *, size_t);
+ ssize_t (*write)(struct file_info *, const void *, size_t);
+ int (*close)(struct file_info *);
+};
+
+/* File structure */
#define NFILES 32 /* Number of files to support */
#define MAXBLOCK 16384 /* Defined by ABI */
struct file_info {
- 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];
+ const struct dev_info *ops; /* Operations structure */
+
+ 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;
};
extern struct file_info __file_info[NFILES];
-/* Special device (tty et al) */
-
-#define __DEV_MAGIC 0x504af4e7
-struct dev_info {
- uint32_t dev_magic; /* Magic number */
- ssize_t (*read)(int, void *, size_t);
- ssize_t (*write)(int, const void *, size_t);
-};
-
#endif /* _COM32_SYS_FILE_H */
diff --git a/com32/lib/sys/fileclose.c b/com32/lib/sys/fileclose.c
new file mode 100644
index 00000000..5fb89f3b
--- /dev/null
+++ b/com32/lib/sys/fileclose.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.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * fileclose.c
+ *
+ * Close an ordinary file
+ */
+
+#include <errno.h>
+#include <com32.h>
+#include <string.h>
+#include "file.h"
+
+int __file_close(struct file_info *fp)
+{
+ com32sys_t regs;
+
+ if ( fp->p.f.filedes ) {
+ memset(&regs, 0, sizeof regs);
+ regs.eax.w[0] = 0x0008; /* Close file */
+ regs.esi.w[0] = fp->p.f.filedes;
+
+ __com32.cs_intcall(0x22, &regs, NULL);
+ }
+
+ return 0;
+}
diff --git a/com32/lib/sys/fileread.c b/com32/lib/sys/fileread.c
new file mode 100644
index 00000000..44609f2c
--- /dev/null
+++ b/com32/lib/sys/fileread.c
@@ -0,0 +1,86 @@
+#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.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * read.c
+ *
+ * Reading from a file
+ */
+
+#include <errno.h>
+#include <string.h>
+#include <com32.h>
+#include <minmax.h>
+#include "file.h"
+
+ssize_t __file_read(struct file_info *fp, void *buf, size_t count)
+{
+ com32sys_t ireg, oreg;
+ char *bufp = buf;
+ size_t n = 0;
+ size_t ncopy;
+
+ memset(&ireg, 0, sizeof ireg);
+ ireg.eax.w[0] = 0x0007; /* Read file */
+ ireg.esi.w[0] = OFFS(__com32.cs_bounce);
+ 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 )
+ return n; /* As good as it gets... */
+
+ ireg.esi.w[0] = fp->p.f.filedes;
+ ireg.ecx.w[0] = MAXBLOCK >> fp->p.f.blocklg2;
+
+ __intcall(0x22, &ireg, &oreg);
+
+ if ( oreg.eflags.l & EFLAGS_CF ) {
+ errno = EIO;
+ 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);
+ }
+
+ ncopy = min(count, fp->p.f.nbytes);
+ memcpy(bufp, fp->p.f.datap, ncopy);
+
+ n += ncopy;
+ bufp += ncopy;
+ count -= ncopy;
+ fp->p.f.datap += ncopy;
+ fp->p.f.offset += ncopy;
+ fp->p.f.nbytes -= ncopy;
+ }
+
+ return n;
+}
diff --git a/com32/lib/sys/isatty.c b/com32/lib/sys/isatty.c
new file mode 100644
index 00000000..8a8e6465
--- /dev/null
+++ b/com32/lib/sys/isatty.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.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * isatty.c
+ *
+ * Return if this is a tty or not
+ */
+
+#include <errno.h>
+#include <string.h>
+#include <com32.h>
+#include <minmax.h>
+#include <unistd.h>
+#include <klibc/compiler.h>
+#include "file.h"
+
+int isatty(int fd)
+{
+ struct file_info *fp = &__file_info[fd];
+
+ if ( fd >= NFILES || !fp->ops ) {
+ errno = EBADF;
+ return -1;
+ }
+
+ return (fp->ops->flags & __DEV_TTY);
+}
diff --git a/com32/lib/sys/open.c b/com32/lib/sys/open.c
index 3f84e5f7..27c22cec 100644
--- a/com32/lib/sys/open.c
+++ b/com32/lib/sys/open.c
@@ -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
@@ -29,27 +29,40 @@
#include <errno.h>
#include <com32.h>
#include <string.h>
+#include <unistd.h>
+#include <fcntl.h>
#include "file.h"
-int open(const char *pathname, int flags, mode_t mode)
+/*
+ * open.c
+ *
+ * Open an ordinary 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 = {
+ .dev_magic = __DEV_MAGIC,
+ .flags = __DEV_FILE,
+ .fileflags = O_RDONLY,
+ .read = __file_read,
+ .write = NULL, /* File writes are not supported */
+ .close = __file_close,
+};
+
+int open(const char *pathname, int flags, ...)
{
com32sys_t regs;
int fd;
struct file_info *fp;
-
- if ( flags ) {
- errno = EINVAL;
- return -1;
- }
- for ( fd = 0, fp = __file_info ; fd < NFILES ; fd++, fp++ )
- if ( fp->blocklg2 == 0 )
- break;
+ fd = opendev(&file_dev, flags);
- if ( fd >= NFILES ) {
- errno = EMFILE;
+ if ( fd < 0 )
return -1;
- }
+
+ fp = &__file_info[fd];
strlcpy(__com32.cs_bounce, pathname, __com32.cs_bounce_size);
@@ -67,13 +80,13 @@ int open(const char *pathname, int flags, mode_t mode)
{
uint16_t blklg2;
asm("bsrw %1,%0" : "=r" (blklg2) : "rm" (regs.ecx.w[0]));
- fp->blocklg2 = blklg2;
+ fp->p.f.blocklg2 = blklg2;
}
- fp->length = regs.eax.l;
- fp->filedes = regs.esi.w[0];
- fp->offset = 0;
- fp->nbytes = 0;
- fp->datap = fp->buf;
+ 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->p.f.datap = fp->p.f.buf;
return fd;
}
diff --git a/com32/lib/sys/openconsole.c b/com32/lib/sys/openconsole.c
new file mode 100644
index 00000000..08b584a0
--- /dev/null
+++ b/com32/lib/sys/openconsole.c
@@ -0,0 +1,52 @@
+#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.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * openconsole.c
+ *
+ * Open the chosen console device
+ */
+
+#include <unistd.h>
+#include <console.h>
+#include <fcntl.h>
+
+int openconsole(const struct dev_info *dev)
+{
+ close(0);
+ if ( opendev(dev, O_RDONLY) != 0 )
+ return -1;
+ close(1);
+ if ( opendev(dev, O_WRONLY) != 1 )
+ return -1;
+ close(2);
+ if ( opendev(dev, O_WRONLY) != 2 )
+ return -1;
+
+ return 0;
+}
diff --git a/com32/lib/sys/opendev.c b/com32/lib/sys/opendev.c
new file mode 100644
index 00000000..0d49a954
--- /dev/null
+++ b/com32/lib/sys/opendev.c
@@ -0,0 +1,62 @@
+#ident "$Id$"
+/* ----------------------------------------------------------------------- *
+ *
+ * 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
+ * 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.
+ *
+ * ----------------------------------------------------------------------- */
+
+#include <errno.h>
+#include <com32.h>
+#include <string.h>
+#include "file.h"
+
+/*
+ * opendev.c
+ *
+ * Open a special device
+ */
+
+int opendev(const struct dev_info *dev, int flags)
+{
+ int fd;
+ struct file_info *fp;
+
+ if ( !(flags & 3) || (flags & ~dev->fileflags) ) {
+ errno = EINVAL;
+ return -1;
+ }
+
+ for ( fd = 0, fp = __file_info ; fd < NFILES ; fd++, fp++ )
+ if ( !fp->ops )
+ break;
+
+ if ( fd >= NFILES ) {
+ errno = EMFILE;
+ return -1;
+ }
+
+ fp->ops = dev;
+
+ return fd;
+}
diff --git a/com32/lib/sys/read.c b/com32/lib/sys/read.c
index 1c16ce47..ea5fde32 100644
--- a/com32/lib/sys/read.c
+++ b/com32/lib/sys/read.c
@@ -29,64 +29,29 @@
/*
* read.c
*
- * Reading from a file
+ * Reading from a file descriptor
*/
#include <errno.h>
#include <string.h>
#include <com32.h>
#include <minmax.h>
+#include <klibc/compiler.h>
#include "file.h"
ssize_t read(int fd, void *buf, size_t count)
{
- com32sys_t ireg, oreg;
struct file_info *fp = &__file_info[fd];
- char *bufp = buf;
- size_t n = 0;
- size_t ncopy;
- if ( fd >= NFILES || fp->blocklg2 == 0 ) {
+ if ( fd >= NFILES || !fp->ops ) {
errno = EBADF;
return -1;
}
- memset(&ireg, 0, sizeof ireg);
- ireg.eax.w[0] = 0x0007; /* Read file */
- ireg.esi.w[0] = OFFS(__com32.cs_bounce);
- ireg.es = SEG(__com32.cs_bounce);
-
- while ( count ) {
- if ( fp->nbytes == 0 ) {
- if ( fp->offset >= fp->length || !fp->filedes )
- return n; /* As good as it gets... */
-
- ireg.esi.w[0] = fp->filedes;
- ireg.ecx.w[0] = MAXBLOCK >> fp->blocklg2;
-
- __intcall(0x22, &ireg, &oreg);
-
- if ( oreg.eflags.l & EFLAGS_CF ) {
- errno = EIO;
- return -1;
- }
-
- fp->filedes = ireg.esi.w[0];
- fp->nbytes = min(fp->length-fp->offset, (unsigned)MAXBLOCK);
- fp->datap = fp->buf;
- memcpy(fp->buf, __com32.cs_bounce, fp->nbytes);
- }
-
- ncopy = min(count, fp->nbytes);
- memcpy(bufp, fp->datap, ncopy);
-
- n += ncopy;
- bufp += ncopy;
- count -= ncopy;
- fp->datap += ncopy;
- fp->offset += ncopy;
- fp->nbytes -= ncopy;
+ if ( __unlikely(!fp->ops->read) ) {
+ errno = EINVAL;
+ return -1;
}
- return n;
+ return fp->ops->read(fp, buf, count);
}
diff --git a/com32/lib/sys/stdcon.c b/com32/lib/sys/stdcon.c
new file mode 100644
index 00000000..7a835927
--- /dev/null
+++ b/com32/lib/sys/stdcon.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.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * stdcon.c
+ *
+ * Default console
+ */
+
+#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);
+
+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,
+};
diff --git a/com32/lib/sys/stdcon_read.c b/com32/lib/sys/stdcon_read.c
new file mode 100644
index 00000000..0e5df19a
--- /dev/null
+++ b/com32/lib/sys/stdcon_read.c
@@ -0,0 +1,68 @@
+#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.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * stdcon_read.c
+ *
+ * Reading from the console, with echo
+ */
+
+#include <errno.h>
+#include <string.h>
+#include <com32.h>
+#include <minmax.h>
+#include "file.h"
+
+ssize_t __stdcon_read(struct file_info *fp, void *buf, size_t count)
+{
+ com32sys_t ireg, oreg;
+ char *bufp = buf;
+ size_t n = 0;
+
+ (void)fp;
+
+ memset(&ireg, 0, sizeof ireg);
+
+ while ( count ) {
+ ireg.eax.b[1] = 0x01;
+ __intcall(0x21, &ireg, &oreg);
+ *bufp++ = oreg.eax.b[0];
+ n++;
+
+ if ( ! --count )
+ break;
+
+ /* Only return more than one if there is stuff in the buffer */
+ ireg.eax.b[1] = 0x0B;
+ __intcall(0x21, &ireg, &oreg);
+ if ( !oreg.eax.b[0] )
+ break;
+ }
+
+ return n;
+}
diff --git a/com32/lib/sys/stdcon_write.c b/com32/lib/sys/stdcon_write.c
new file mode 100644
index 00000000..62bc4cce
--- /dev/null
+++ b/com32/lib/sys/stdcon_write.c
@@ -0,0 +1,63 @@
+#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.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * write.c
+ *
+ * Writing to the console
+ */
+
+#include <errno.h>
+#include <string.h>
+#include <com32.h>
+#include <minmax.h>
+#include "file.h"
+
+ssize_t __stdcon_write(struct file_info *fp, const void *buf, size_t count)
+{
+ com32sys_t ireg;
+ const char *bufp = buf;
+ size_t n = 0;
+
+ (void)fp;
+
+ memset(&ireg, 0, sizeof ireg);
+ ireg.eax.b[1] = 0x02;
+
+ while ( count-- ) {
+ if ( *bufp == '\n' ) {
+ ireg.edx.b[0] = '\r';
+ __intcall(0x21, &ireg, NULL);
+ }
+ ireg.edx.b[0] = *bufp++;
+ __intcall(0x21, &ireg, NULL);
+ n++;
+ }
+
+ return n;
+}
diff --git a/com32/lib/sys/write.c b/com32/lib/sys/write.c
index b908f362..b4b3c6ee 100644
--- a/com32/lib/sys/write.c
+++ b/com32/lib/sys/write.c
@@ -29,30 +29,29 @@
/*
* write.c
*
- * Writing to the console
+ * Write to a file descriptor
*/
#include <errno.h>
#include <string.h>
#include <com32.h>
#include <minmax.h>
+#include <klibc/compiler.h>
#include "file.h"
ssize_t write(int fd, void *buf, size_t count)
{
- com32sys_t ireg;
struct file_info *fp = &__file_info[fd];
- char *bufp = buf;
- size_t n = 0;
- memset(&ireg, 0, sizeof ireg);
- ireg.eax.b[1] = 0x02;
+ if ( fd >= NFILES || !fp->ops ) {
+ errno = EBADF;
+ return -1;
+ }
- while ( count-- ) {
- ireg.edx.b[0] = *bufp++;
- __intcall(0x21, &ireg, NULL);
- n++;
+ if ( __unlikely(!fp->ops->write) ) {
+ errno = EINVAL;
+ return -1;
}
- return n;
+ return fp->ops->write(fp, buf, count);
}
diff --git a/com32/modules/Makefile b/com32/modules/Makefile
index a47e0a27..dfd6a3bb 100644
--- a/com32/modules/Makefile
+++ b/com32/modules/Makefile
@@ -25,12 +25,13 @@ LD = ld -m elf_i386
AR = ar
NASM = nasm
RANLIB = ranlib
-CFLAGS = -W -Wall -march=i386 -Os -fomit-frame-pointer -I../com32/include
+CFLAGS = -W -Wall -march=i386 -Os -fomit-frame-pointer -I../include
SFLAGS = -march=i386
LDFLAGS = -s -T ../lib/com32.ld
OBJCOPY = objcopy
PPMTOLSS16 = ../ppmtolss16
LIB = ../lib/libcom32.a
+LIBGCC := $(shell $(CC) --print-libgcc)
.SUFFIXES: .lss .c .o .elf .c32
@@ -46,7 +47,7 @@ all: hello.c32
.PRECIOUS: %.elf
%.elf: %.o $(LIB)
- $(LD) $(LDFLAGS) -o $@ $^
+ $(LD) $(LDFLAGS) -o $@ $^ $(LIBGCC)
%.c32: %.elf
$(OBJCOPY) -O binary $< $@
diff --git a/com32/modules/hello.c b/com32/modules/hello.c
index bcb018d9..aea8766b 100644
--- a/com32/modules/hello.c
+++ b/com32/modules/hello.c
@@ -17,11 +17,25 @@
* Hello, World! using libcom32
*/
+#include <string.h>
#include <stdio.h>
+#include <console.h>
int main(void)
{
+ char buffer[1024];
+
+ openconsole(&dev_stdcon);
+
printf("Hello, World!\n");
+ for (;;) {
+ printf("> ");
+ fgets(buffer, sizeof buffer, stdin);
+ if ( !strncmp(buffer, "exit", 4) )
+ break;
+ printf(": %s", buffer);
+ }
+
return 0;
}