py/stream: seek: Consistently handle negative offset for SEEK_SET.

Per POSIX, this is EINVAL, so raises OSError(EINVAL).
This commit is contained in:
Paul Sokolovsky 2017-08-20 21:57:36 +03:00
parent 0cd9ab7755
commit e3383e9352
3 changed files with 20 additions and 1 deletions

View File

@ -448,11 +448,16 @@ STATIC mp_obj_t stream_seek(size_t n_args, const mp_obj_t *args) {
struct mp_stream_seek_t seek_s;
// TODO: Could be uint64
seek_s.offset = mp_obj_get_int(args[1]);
seek_s.whence = 0;
seek_s.whence = SEEK_SET;
if (n_args == 3) {
seek_s.whence = mp_obj_get_int(args[2]);
}
// In POSIX, it's error to seek before end of stream, we enforce it here.
if (seek_s.whence == SEEK_SET && seek_s.offset < 0) {
mp_raise_OSError(MP_EINVAL);
}
int error;
mp_uint_t res = stream_p->ioctl(args[0], MP_STREAM_SEEK, (mp_uint_t)(uintptr_t)&seek_s, &error);
if (res == MP_STREAM_ERROR) {

13
tests/io/bytesio_ext2.py Normal file
View File

@ -0,0 +1,13 @@
try:
import uio as io
except ImportError:
import io
a = io.BytesIO(b"foobar")
try:
a.seek(-10)
except Exception as e:
# CPython throws ValueError, but MicroPython has consistent stream
# interface, so BytesIO raises the same error as a real file, which
# is OSError(EINVAL).
print(repr(e))

View File

@ -0,0 +1 @@
OSError(22,)