1.1 --- a/lib/__builtins__/exception/io.py Tue Dec 06 18:18:47 2016 +0100
1.2 +++ b/lib/__builtins__/exception/io.py Tue Dec 06 20:32:33 2016 +0100
1.3 @@ -3,7 +3,7 @@
1.4 """
1.5 Input/output exception objects.
1.6
1.7 -Copyright (C) 2015 Paul Boddie <paul@boddie.org.uk>
1.8 +Copyright (C) 2015, 2016 Paul Boddie <paul@boddie.org.uk>
1.9
1.10 This program is free software; you can redistribute it and/or modify it under
1.11 the terms of the GNU General Public License as published by the Free Software
1.12 @@ -20,7 +20,17 @@
1.13 """
1.14
1.15 class EOFError(Exception): pass
1.16 -class IOError(Exception): pass
1.17 +
1.18 +class IOError(Exception):
1.19 +
1.20 + "An input/output error."
1.21 +
1.22 + def __init__(self, value):
1.23 +
1.24 + "Initialise the exception with the given 'value'."
1.25 +
1.26 + self.value = value
1.27 +
1.28 class KeyboardInterrupt(Exception): pass
1.29
1.30 # vim: tabstop=4 expandtab shiftwidth=4
2.1 --- a/templates/native.c Tue Dec 06 18:18:47 2016 +0100
2.2 +++ b/templates/native.c Tue Dec 06 20:32:33 2016 +0100
2.3 @@ -663,7 +663,7 @@
2.4 /* Produce an exception if the operation failed. */
2.5
2.6 if (f == NULL)
2.7 - __raise_io_error(errno);
2.8 + __raise_io_error(__new_int(errno));
2.9 else
2.10 {
2.11 attr.context = 0;
2.12 @@ -682,18 +682,19 @@
2.13 int to_read = __load_via_object(n->value, __pos___data__).intvalue;
2.14 void *buf[to_read + 1];
2.15 ssize_t have_read;
2.16 + char *s;
2.17
2.18 errno = 0;
2.19 have_read = read(i, buf, to_read);
2.20
2.21 if (have_read == -1)
2.22 - __raise_io_error(errno);
2.23 + __raise_io_error(__new_int(errno));
2.24 else
2.25 {
2.26 - /* Zero terminate the string. */
2.27 -
2.28 - buf[have_read] = 0;
2.29 - return __new_str((char *) buf);
2.30 + /* Reserve space for a new string. */
2.31 + s = __ALLOCATE(have_read + 1, 1);
2.32 + strncpy(s, (char *) buf, have_read); /* does not null terminate but final byte should be zero */
2.33 + return __new_str(s);
2.34 }
2.35 }
2.36
3.1 --- a/templates/progops.c Tue Dec 06 18:18:47 2016 +0100
3.2 +++ b/templates/progops.c Tue Dec 06 20:32:33 2016 +0100
3.3 @@ -80,9 +80,9 @@
3.4 /* Helpers for raising errors within common operations. */
3.5
3.6 #ifdef __HAVE___builtins___exception_io_IOError
3.7 -void __raise_io_error()
3.8 +void __raise_io_error(__attr value)
3.9 {
3.10 - __attr args[1];
3.11 + __attr args[2] = {{0, 0}, value};
3.12 __attr exc = __new___builtins___exception_io_IOError(args);
3.13 __Raise(exc);
3.14 }
4.1 --- a/templates/progops.h Tue Dec 06 18:18:47 2016 +0100
4.2 +++ b/templates/progops.h Tue Dec 06 20:32:33 2016 +0100
4.3 @@ -18,7 +18,7 @@
4.4 /* Exception raising. */
4.5
4.6 #ifdef __HAVE___builtins___exception_io_IOError
4.7 -void __raise_io_error();
4.8 +void __raise_io_error(__attr value);
4.9 #endif /* __HAVE___builtins___exception_io_IOError */
4.10
4.11 void __raise_memory_error();
5.1 --- a/test_all.sh Tue Dec 06 18:18:47 2016 +0100
5.2 +++ b/test_all.sh Tue Dec 06 20:32:33 2016 +0100
5.3 @@ -35,6 +35,8 @@
5.4 fi
5.5 fi
5.6
5.7 +TESTINPUT="tests/testinput.txt"
5.8 +
5.9 # Perform each test.
5.10
5.11 for FILENAME in tests/* ; do
5.12 @@ -50,6 +52,12 @@
5.13 fi
5.14 fi
5.15
5.16 + # Skip non-program files.
5.17 +
5.18 + if [ `basename "$FILENAME"` = "$TESTNAME" ]; then
5.19 + continue
5.20 + fi
5.21 +
5.22 # Run tests without an existing cache.
5.23
5.24 echo "$FILENAME..." 1>&2
5.25 @@ -96,7 +104,7 @@
5.26 fi
5.27
5.28 echo " (run)..." 1>&2
5.29 - if ! "_generated/main" > "$OUTLOG" ; then
5.30 + if ! "_generated/main" > "$OUTLOG" < "$TESTINPUT" ; then
5.31 exit 1
5.32 fi
5.33 fi
6.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
6.2 +++ b/tests/read.py Tue Dec 06 20:32:33 2016 +0100
6.3 @@ -0,0 +1,9 @@
6.4 +from posix.io import read
6.5 +
6.6 +try:
6.7 + s = read(3, 10)
6.8 +except IOError, exc:
6.9 + print "read(3, 10): input/output error condition", exc.value
6.10 +
6.11 +s = read(0, 10)
6.12 +print s
7.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
7.2 +++ b/tests/testinput.txt Tue Dec 06 20:32:33 2016 +0100
7.3 @@ -0,0 +1,1 @@
7.4 +Hello world!