# HG changeset patch # User Paul Boddie # Date 1481043355 -3600 # Node ID 7ce269cf45391ef3a5efb817ad3d279f3e05e04e # Parent fd3bcbdacf1855a76fc34e66bc65135a4b4c90b9 Moved native I/O function usage to functions in the posix.io module, employing these functions in the built-in file object. Added the raising of IOError in native functions. Added a tentative read native function implementation. Added a tentative fdopen native function implementation and a miscellaneous datavalue member to the __attr structure. Moved the read function into the posix.io module. Temporarily removed imports from the posix top-level module. diff -r fd3bcbdacf18 -r 7ce269cf4539 lib/__builtins__/io.py --- a/lib/__builtins__/io.py Tue Dec 06 17:49:39 2016 +0100 +++ b/lib/__builtins__/io.py Tue Dec 06 17:55:55 2016 +0100 @@ -19,7 +19,7 @@ this program. If not, see . """ -from native import _read, _write +from posix.io import fdopen, read, write class sysfile: @@ -35,13 +35,13 @@ "Read 'n' bytes from the file." - return _read(self.fd, n) + return read(self.fd, n) def write(self, s): "Write 's' to the file." - _write(self.fd, str(s)) + write(self.fd, str(s)) def open(name, mode=None, buffering=None): diff -r fd3bcbdacf18 -r 7ce269cf4539 lib/native.py --- a/lib/native.py Tue Dec 06 17:49:39 2016 +0100 +++ b/lib/native.py Tue Dec 06 17:55:55 2016 +0100 @@ -96,7 +96,8 @@ # Input/output. -def _read(fd, n): pass +def _fdopen(fd, mode): IOError +def _read(fd, n): IOError def _write(fd, str): pass # vim: tabstop=4 expandtab shiftwidth=4 diff -r fd3bcbdacf18 -r 7ce269cf4539 lib/posix/__init__.py --- a/lib/posix/__init__.py Tue Dec 06 17:49:39 2016 +0100 +++ b/lib/posix/__init__.py Tue Dec 06 17:55:55 2016 +0100 @@ -1,12 +1,5 @@ #!/usr/bin/env python -from posix.core import name, linesep -from posix.conf import * -from posix.filesys import * -from posix.io import * -from posix.process import * -from posix.random import * -from posix.stat import * -from posix.temp import * +"POSIX support package." # vim: tabstop=4 expandtab shiftwidth=4 diff -r fd3bcbdacf18 -r 7ce269cf4539 lib/posix/filesys.py --- a/lib/posix/filesys.py Tue Dec 06 17:49:39 2016 +0100 +++ b/lib/posix/filesys.py Tue Dec 06 17:55:55 2016 +0100 @@ -14,7 +14,6 @@ def mkdir(path, mode=0777): pass def mkfifo(filename, mode=0666): pass def mknod(filename, mode=0600, device=None): pass -def read(fd, buffersize): pass def readlink(path): pass def remove(path): pass def rename(old, new): pass diff -r fd3bcbdacf18 -r 7ce269cf4539 lib/posix/io.py --- a/lib/posix/io.py Tue Dec 06 17:49:39 2016 +0100 +++ b/lib/posix/io.py Tue Dec 06 17:55:55 2016 +0100 @@ -1,31 +1,86 @@ #!/usr/bin/env python +""" +POSIX input/output functions. + +Copyright (C) 2016 Paul Boddie + +This program is free software; you can redistribute it and/or modify it under +the terms of the GNU General Public License as published by the Free Software +Foundation; either version 3 of the License, or (at your option) any later +version. + +This program is distributed in the hope that it will be useful, but WITHOUT +ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +FOR A PARTICULAR PURPOSE. See the GNU General Public License for more +details. + +You should have received a copy of the GNU General Public License along with +this program. If not, see . +""" + +import native + def close(fd): pass def closerange(fd_low, fd_high): pass def dup(fd): pass def dup2(old_fd, new_fd): pass -def fchdir(fildes): pass +def fchdir(fd): pass def fchmod(fd, mode): pass def fchown(fd, uid, gid): pass -def fdatasync(fildes): pass -def fdopen(fd, mode='r', bufsize=None): pass +def fdatasync(fd): pass + +def fdopen(fd, mode="r"): + + """ + Open a stream for the given file descriptor 'fd', operating in the given + 'mode'. + """ + + _check_fd(fd) + _check_string(mode) + return native._fdopen(fd, mode) + def fpathconf(fd, name): pass def fstat(fd): pass def fstatvfs(fd): pass -def fsync(fildes): pass +def fsync(fd): pass def ftruncate(fd, length): pass def isatty(fd): pass + +SEEK_CUR = 1 +SEEK_END = 2 +SEEK_SET = 0 + def lseek(fd, pos, how): pass def open(filename, flag, mode=0777): pass def openpty(): pass def pipe(): pass def putenv(key, value): pass + +def read(fd, n): + + """ + Read using the low-level file descriptor 'fd' the given number of bytes 'n'. + """ + + _check_fd(fd) + _check_int(n) + return native._read(fd, n) + def times(): pass def ttyname(fd): pass def umask(new_mask): pass def uname(): pass def unsetenv(key): pass -def write(fd, string): pass + +def write(fd, s): + + "Write using the low-level file descriptor 'fd' the given string 's'." + + _check_fd(fd) + _check_string(s) + native._write(fd, s) O_APPEND = 1024 O_ASYNC = 8192 @@ -47,8 +102,25 @@ O_TRUNC = 512 O_WRONLY = 1 -SEEK_CUR = 1 -SEEK_END = 2 -SEEK_SET = 0 +def _check_fd(fd): + + "Check the given low-level file descriptor 'fd'." + + if not native._isinstance(fd, int): + raise ValueError(fd) + +def _check_int(i): + + "Check the given int 'i'." + + if not native._isinstance(i, int): + raise ValueError(i) + +def _check_string(s): + + "Check the given string 's'." + + if not native._isinstance(s, string): + raise ValueError(s) # vim: tabstop=4 expandtab shiftwidth=4 diff -r fd3bcbdacf18 -r 7ce269cf4539 templates/native.c --- a/templates/native.c Tue Dec 06 17:49:39 2016 +0100 +++ b/templates/native.c Tue Dec 06 17:55:55 2016 +0100 @@ -3,7 +3,7 @@ #include /* INT_MAX, INT_MIN */ #include /* ceil, log10, pow */ #include /* strcmp, strncpy, strlen */ -#include /* snprintf */ +#include /* fdopen, snprintf */ #include /* errno */ #include "types.h" #include "exceptions.h" @@ -644,13 +644,57 @@ return __builtins___boolean_False; } +/* Input/output. */ + +__attr __fn_native__fdopen(__attr __args[]) +{ + __attr * const fd = &__args[1]; + __attr * const mode = &__args[2]; + /* fd.__data__ interpreted as int */ + int i = __load_via_object(fd->value, __pos___data__).intvalue; + /* str.__data__ interpreted as string */ + char *s = __load_via_object(mode->value, __pos___data__).strvalue; + FILE *f; + __attr attr; + + errno = 0; + f = fdopen(i, s); + + /* Produce an exception if the operation failed. */ + + if (f == NULL) + __raise_io_error(errno); + else + { + attr.context = 0; + attr.datavalue = (void *) f; + return attr; + } +} + __attr __fn_native__read(__attr __args[]) { __attr * const fd = &__args[1]; __attr * const n = &__args[2]; + /* fd.__data__ interpreted as int */ + int i = __load_via_object(fd->value, __pos___data__).intvalue; + /* n.__data__ interpreted as int */ + int to_read = __load_via_object(n->value, __pos___data__).intvalue; + void *buf[to_read + 1]; + ssize_t have_read; - /* NOTE: To be written. */ - return __builtins___none_None; + errno = 0; + have_read = read(i, buf, to_read); + + if (have_read == -1) + __raise_io_error(errno); + else + { + /* Zero terminate the string. */ + + buf[have_read] = 0; + return __new_str((char *) buf); + } } __attr __fn_native__write(__attr __args[]) diff -r fd3bcbdacf18 -r 7ce269cf4539 templates/native.h --- a/templates/native.h Tue Dec 06 17:49:39 2016 +0100 +++ b/templates/native.h Tue Dec 06 17:55:55 2016 +0100 @@ -65,6 +65,7 @@ __attr __fn_native__isinstance(__attr __args[]); __attr __fn_native__issubclass(__attr __args[]); +__attr __fn_native__fdopen(__attr __args[]); __attr __fn_native__read(__attr __args[]); __attr __fn_native__write(__attr __args[]); diff -r fd3bcbdacf18 -r 7ce269cf4539 templates/types.h --- a/templates/types.h Tue Dec 06 17:49:39 2016 +0100 +++ b/templates/types.h Tue Dec 06 17:55:55 2016 +0100 @@ -54,6 +54,7 @@ double floatvalue; /* floating point value */ char * strvalue; /* string value */ __fragment * seqvalue; /* sequence data */ + void * datavalue; /* object-specific data */ }; } __attr;