1.1 --- a/lib/__builtins__/io.py Tue Dec 06 17:49:39 2016 +0100
1.2 +++ b/lib/__builtins__/io.py Tue Dec 06 17:55:55 2016 +0100
1.3 @@ -19,7 +19,7 @@
1.4 this program. If not, see <http://www.gnu.org/licenses/>.
1.5 """
1.6
1.7 -from native import _read, _write
1.8 +from posix.io import fdopen, read, write
1.9
1.10 class sysfile:
1.11
1.12 @@ -35,13 +35,13 @@
1.13
1.14 "Read 'n' bytes from the file."
1.15
1.16 - return _read(self.fd, n)
1.17 + return read(self.fd, n)
1.18
1.19 def write(self, s):
1.20
1.21 "Write 's' to the file."
1.22
1.23 - _write(self.fd, str(s))
1.24 + write(self.fd, str(s))
1.25
1.26 def open(name, mode=None, buffering=None):
1.27
2.1 --- a/lib/native.py Tue Dec 06 17:49:39 2016 +0100
2.2 +++ b/lib/native.py Tue Dec 06 17:55:55 2016 +0100
2.3 @@ -96,7 +96,8 @@
2.4
2.5 # Input/output.
2.6
2.7 -def _read(fd, n): pass
2.8 +def _fdopen(fd, mode): IOError
2.9 +def _read(fd, n): IOError
2.10 def _write(fd, str): pass
2.11
2.12 # vim: tabstop=4 expandtab shiftwidth=4
3.1 --- a/lib/posix/__init__.py Tue Dec 06 17:49:39 2016 +0100
3.2 +++ b/lib/posix/__init__.py Tue Dec 06 17:55:55 2016 +0100
3.3 @@ -1,12 +1,5 @@
3.4 #!/usr/bin/env python
3.5
3.6 -from posix.core import name, linesep
3.7 -from posix.conf import *
3.8 -from posix.filesys import *
3.9 -from posix.io import *
3.10 -from posix.process import *
3.11 -from posix.random import *
3.12 -from posix.stat import *
3.13 -from posix.temp import *
3.14 +"POSIX support package."
3.15
3.16 # vim: tabstop=4 expandtab shiftwidth=4
4.1 --- a/lib/posix/filesys.py Tue Dec 06 17:49:39 2016 +0100
4.2 +++ b/lib/posix/filesys.py Tue Dec 06 17:55:55 2016 +0100
4.3 @@ -14,7 +14,6 @@
4.4 def mkdir(path, mode=0777): pass
4.5 def mkfifo(filename, mode=0666): pass
4.6 def mknod(filename, mode=0600, device=None): pass
4.7 -def read(fd, buffersize): pass
4.8 def readlink(path): pass
4.9 def remove(path): pass
4.10 def rename(old, new): pass
5.1 --- a/lib/posix/io.py Tue Dec 06 17:49:39 2016 +0100
5.2 +++ b/lib/posix/io.py Tue Dec 06 17:55:55 2016 +0100
5.3 @@ -1,31 +1,86 @@
5.4 #!/usr/bin/env python
5.5
5.6 +"""
5.7 +POSIX input/output functions.
5.8 +
5.9 +Copyright (C) 2016 Paul Boddie <paul@boddie.org.uk>
5.10 +
5.11 +This program is free software; you can redistribute it and/or modify it under
5.12 +the terms of the GNU General Public License as published by the Free Software
5.13 +Foundation; either version 3 of the License, or (at your option) any later
5.14 +version.
5.15 +
5.16 +This program is distributed in the hope that it will be useful, but WITHOUT
5.17 +ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
5.18 +FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
5.19 +details.
5.20 +
5.21 +You should have received a copy of the GNU General Public License along with
5.22 +this program. If not, see <http://www.gnu.org/licenses/>.
5.23 +"""
5.24 +
5.25 +import native
5.26 +
5.27 def close(fd): pass
5.28 def closerange(fd_low, fd_high): pass
5.29 def dup(fd): pass
5.30 def dup2(old_fd, new_fd): pass
5.31 -def fchdir(fildes): pass
5.32 +def fchdir(fd): pass
5.33 def fchmod(fd, mode): pass
5.34 def fchown(fd, uid, gid): pass
5.35 -def fdatasync(fildes): pass
5.36 -def fdopen(fd, mode='r', bufsize=None): pass
5.37 +def fdatasync(fd): pass
5.38 +
5.39 +def fdopen(fd, mode="r"):
5.40 +
5.41 + """
5.42 + Open a stream for the given file descriptor 'fd', operating in the given
5.43 + 'mode'.
5.44 + """
5.45 +
5.46 + _check_fd(fd)
5.47 + _check_string(mode)
5.48 + return native._fdopen(fd, mode)
5.49 +
5.50 def fpathconf(fd, name): pass
5.51 def fstat(fd): pass
5.52 def fstatvfs(fd): pass
5.53 -def fsync(fildes): pass
5.54 +def fsync(fd): pass
5.55 def ftruncate(fd, length): pass
5.56 def isatty(fd): pass
5.57 +
5.58 +SEEK_CUR = 1
5.59 +SEEK_END = 2
5.60 +SEEK_SET = 0
5.61 +
5.62 def lseek(fd, pos, how): pass
5.63 def open(filename, flag, mode=0777): pass
5.64 def openpty(): pass
5.65 def pipe(): pass
5.66 def putenv(key, value): pass
5.67 +
5.68 +def read(fd, n):
5.69 +
5.70 + """
5.71 + Read using the low-level file descriptor 'fd' the given number of bytes 'n'.
5.72 + """
5.73 +
5.74 + _check_fd(fd)
5.75 + _check_int(n)
5.76 + return native._read(fd, n)
5.77 +
5.78 def times(): pass
5.79 def ttyname(fd): pass
5.80 def umask(new_mask): pass
5.81 def uname(): pass
5.82 def unsetenv(key): pass
5.83 -def write(fd, string): pass
5.84 +
5.85 +def write(fd, s):
5.86 +
5.87 + "Write using the low-level file descriptor 'fd' the given string 's'."
5.88 +
5.89 + _check_fd(fd)
5.90 + _check_string(s)
5.91 + native._write(fd, s)
5.92
5.93 O_APPEND = 1024
5.94 O_ASYNC = 8192
5.95 @@ -47,8 +102,25 @@
5.96 O_TRUNC = 512
5.97 O_WRONLY = 1
5.98
5.99 -SEEK_CUR = 1
5.100 -SEEK_END = 2
5.101 -SEEK_SET = 0
5.102 +def _check_fd(fd):
5.103 +
5.104 + "Check the given low-level file descriptor 'fd'."
5.105 +
5.106 + if not native._isinstance(fd, int):
5.107 + raise ValueError(fd)
5.108 +
5.109 +def _check_int(i):
5.110 +
5.111 + "Check the given int 'i'."
5.112 +
5.113 + if not native._isinstance(i, int):
5.114 + raise ValueError(i)
5.115 +
5.116 +def _check_string(s):
5.117 +
5.118 + "Check the given string 's'."
5.119 +
5.120 + if not native._isinstance(s, string):
5.121 + raise ValueError(s)
5.122
5.123 # vim: tabstop=4 expandtab shiftwidth=4
6.1 --- a/templates/native.c Tue Dec 06 17:49:39 2016 +0100
6.2 +++ b/templates/native.c Tue Dec 06 17:55:55 2016 +0100
6.3 @@ -3,7 +3,7 @@
6.4 #include <limits.h> /* INT_MAX, INT_MIN */
6.5 #include <math.h> /* ceil, log10, pow */
6.6 #include <string.h> /* strcmp, strncpy, strlen */
6.7 -#include <stdio.h> /* snprintf */
6.8 +#include <stdio.h> /* fdopen, snprintf */
6.9 #include <errno.h> /* errno */
6.10 #include "types.h"
6.11 #include "exceptions.h"
6.12 @@ -644,13 +644,57 @@
6.13 return __builtins___boolean_False;
6.14 }
6.15
6.16 +/* Input/output. */
6.17 +
6.18 +__attr __fn_native__fdopen(__attr __args[])
6.19 +{
6.20 + __attr * const fd = &__args[1];
6.21 + __attr * const mode = &__args[2];
6.22 + /* fd.__data__ interpreted as int */
6.23 + int i = __load_via_object(fd->value, __pos___data__).intvalue;
6.24 + /* str.__data__ interpreted as string */
6.25 + char *s = __load_via_object(mode->value, __pos___data__).strvalue;
6.26 + FILE *f;
6.27 + __attr attr;
6.28 +
6.29 + errno = 0;
6.30 + f = fdopen(i, s);
6.31 +
6.32 + /* Produce an exception if the operation failed. */
6.33 +
6.34 + if (f == NULL)
6.35 + __raise_io_error(errno);
6.36 + else
6.37 + {
6.38 + attr.context = 0;
6.39 + attr.datavalue = (void *) f;
6.40 + return attr;
6.41 + }
6.42 +}
6.43 +
6.44 __attr __fn_native__read(__attr __args[])
6.45 {
6.46 __attr * const fd = &__args[1];
6.47 __attr * const n = &__args[2];
6.48 + /* fd.__data__ interpreted as int */
6.49 + int i = __load_via_object(fd->value, __pos___data__).intvalue;
6.50 + /* n.__data__ interpreted as int */
6.51 + int to_read = __load_via_object(n->value, __pos___data__).intvalue;
6.52 + void *buf[to_read + 1];
6.53 + ssize_t have_read;
6.54
6.55 - /* NOTE: To be written. */
6.56 - return __builtins___none_None;
6.57 + errno = 0;
6.58 + have_read = read(i, buf, to_read);
6.59 +
6.60 + if (have_read == -1)
6.61 + __raise_io_error(errno);
6.62 + else
6.63 + {
6.64 + /* Zero terminate the string. */
6.65 +
6.66 + buf[have_read] = 0;
6.67 + return __new_str((char *) buf);
6.68 + }
6.69 }
6.70
6.71 __attr __fn_native__write(__attr __args[])
7.1 --- a/templates/native.h Tue Dec 06 17:49:39 2016 +0100
7.2 +++ b/templates/native.h Tue Dec 06 17:55:55 2016 +0100
7.3 @@ -65,6 +65,7 @@
7.4 __attr __fn_native__isinstance(__attr __args[]);
7.5 __attr __fn_native__issubclass(__attr __args[]);
7.6
7.7 +__attr __fn_native__fdopen(__attr __args[]);
7.8 __attr __fn_native__read(__attr __args[]);
7.9 __attr __fn_native__write(__attr __args[]);
7.10
8.1 --- a/templates/types.h Tue Dec 06 17:49:39 2016 +0100
8.2 +++ b/templates/types.h Tue Dec 06 17:55:55 2016 +0100
8.3 @@ -54,6 +54,7 @@
8.4 double floatvalue; /* floating point value */
8.5 char * strvalue; /* string value */
8.6 __fragment * seqvalue; /* sequence data */
8.7 + void * datavalue; /* object-specific data */
8.8 };
8.9 } __attr;
8.10