Author: Brian Kearns <bdkea...@gmail.com> Branch: refactor-buffer-api Changeset: r70933:2f1472af7614 Date: 2014-04-24 15:33 -0400 http://bitbucket.org/pypy/pypy/changeset/2f1472af7614/
Log: cleanup fcntl/ioctl behavior diff --git a/pypy/module/fcntl/interp_fcntl.py b/pypy/module/fcntl/interp_fcntl.py --- a/pypy/module/fcntl/interp_fcntl.py +++ b/pypy/module/fcntl/interp_fcntl.py @@ -1,6 +1,6 @@ from rpython.rtyper.tool import rffi_platform as platform from rpython.rtyper.lltypesystem import rffi, lltype -from pypy.interpreter.error import OperationError, wrap_oserror +from pypy.interpreter.error import OperationError, wrap_oserror, oefmt from pypy.interpreter.gateway import unwrap_spec, WrappedDefault from rpython.rlib import rposix from rpython.translator.tool.cbuild import ExternalCompilationInfo @@ -92,33 +92,27 @@ op = rffi.cast(rffi.INT, op) # C long => C int try: - intarg = space.int_w(w_arg) - except OperationError, e: - if not e.match(space, space.w_TypeError): - raise - else: - intarg = rffi.cast(rffi.INT, intarg) # C long => C int - rv = fcntl_int(fd, op, intarg) - if rv < 0: - raise _get_error(space, "fcntl") - return space.wrap(rv) - - try: - arg = space.bufferstr_w(w_arg) + arg = space.getarg_w('s#', w_arg) except OperationError, e: if not e.match(space, space.w_TypeError): raise else: ll_arg = rffi.str2charp(arg) - rv = fcntl_str(fd, op, ll_arg) - arg = rffi.charpsize2str(ll_arg, len(arg)) - lltype.free(ll_arg, flavor='raw') - if rv < 0: - raise _get_error(space, "fcntl") - return space.wrap(arg) + try: + rv = fcntl_str(fd, op, ll_arg) + if rv < 0: + raise _get_error(space, "fcntl") + arg = rffi.charpsize2str(ll_arg, len(arg)) + return space.wrap(arg) + finally: + lltype.free(ll_arg, flavor='raw') - raise OperationError(space.w_TypeError, - space.wrap("int or string or buffer required")) + intarg = space.int_w(w_arg) + intarg = rffi.cast(rffi.INT, intarg) # C long => C int + rv = fcntl_int(fd, op, intarg) + if rv < 0: + raise _get_error(space, "fcntl") + return space.wrap(rv) @unwrap_spec(op=int) def flock(space, w_fd, op): @@ -207,50 +201,50 @@ fd = space.c_filedescriptor_w(w_fd) op = rffi.cast(rffi.INT, op) # C long => C int - if mutate_flag != 0: - try: - rwbuffer = space.writebuf_w(w_arg) - except OperationError, e: - if not e.match(space, space.w_TypeError): - raise - if mutate_flag > 0: - raise - else: - arg = rwbuffer.as_str() - ll_arg = rffi.str2charp(arg) - rv = ioctl_str(fd, op, ll_arg) - arg = rffi.charpsize2str(ll_arg, len(arg)) - lltype.free(ll_arg, flavor='raw') - if rv < 0: - raise _get_error(space, "ioctl") - rwbuffer.setslice(0, arg) - return space.wrap(rv) - try: - intarg = space.int_w(w_arg) + rwbuffer = space.writebuf_w(w_arg) except OperationError, e: if not e.match(space, space.w_TypeError): raise else: - intarg = rffi.cast(rffi.INT, intarg) # C long => C int - rv = ioctl_int(fd, op, intarg) - if rv < 0: - raise _get_error(space, "ioctl") - return space.wrap(rv) + arg = rwbuffer.as_str() + ll_arg = rffi.str2charp(arg) + try: + rv = ioctl_str(fd, op, ll_arg) + if rv < 0: + raise _get_error(space, "ioctl") + arg = rffi.charpsize2str(ll_arg, len(arg)) + if mutate_flag != 0: + rwbuffer.setslice(0, arg) + return space.wrap(rv) + return space.wrap(arg) + finally: + lltype.free(ll_arg, flavor='raw') + + if mutate_flag != -1: + raise OperationError(space.w_TypeError, space.wrap( + "ioctl requires a file or file descriptor, an integer " + "and optionally an integer or buffer argument")) try: - arg = space.bufferstr_w(w_arg) + arg = space.getarg_w('s#', w_arg) except OperationError, e: if not e.match(space, space.w_TypeError): raise else: ll_arg = rffi.str2charp(arg) - rv = ioctl_str(fd, op, ll_arg) - arg = rffi.charpsize2str(ll_arg, len(arg)) - lltype.free(ll_arg, flavor='raw') - if rv < 0: - raise _get_error(space, "ioctl") - return space.wrap(arg) + try: + rv = ioctl_str(fd, op, ll_arg) + if rv < 0: + raise _get_error(space, "ioctl") + arg = rffi.charpsize2str(ll_arg, len(arg)) + return space.wrap(arg) + finally: + lltype.free(ll_arg, flavor='raw') - raise OperationError(space.w_TypeError, - space.wrap("int or string or buffer required")) + intarg = space.int_w(w_arg) + intarg = rffi.cast(rffi.INT, intarg) # C long => C int + rv = ioctl_int(fd, op, intarg) + if rv < 0: + raise _get_error(space, "ioctl") + return space.wrap(rv) diff --git a/pypy/module/fcntl/test/test_fcntl.py b/pypy/module/fcntl/test/test_fcntl.py --- a/pypy/module/fcntl/test/test_fcntl.py +++ b/pypy/module/fcntl/test/test_fcntl.py @@ -51,6 +51,8 @@ assert fcntl.fcntl(f, 1, 0) == 0 assert fcntl.fcntl(f, 2, "foo") == "foo" assert fcntl.fcntl(f, 2, buffer("foo")) == "foo" + exc = raises(TypeError, fcntl.fcntl, f, 2, memoryview("foo")) + assert 'integer' in str(exc.value) try: os.O_LARGEFILE @@ -226,6 +228,18 @@ assert res == 0 assert buf.tostring() == expected + buf = array.array('i', [0]) + res = fcntl.ioctl(mfd, TIOCGPGRP, buffer(buf)) + assert res == expected + assert buf.tostring() == '\x00' * 4 + + exc = raises(TypeError, fcntl.ioctl, mfd, TIOCGPGRP, memoryview('abc')) + assert 'integer' in str(exc.value) + exc = raises(TypeError, fcntl.ioctl, mfd, TIOCGPGRP, buffer(buf), False) + assert str(exc.value) == "ioctl requires a file or file descriptor, an integer and optionally an integer or buffer argument" + exc = raises(TypeError, fcntl.ioctl, mfd, TIOCGPGRP, memoryview('abc'), False) + assert str(exc.value) == "ioctl requires a file or file descriptor, an integer and optionally an integer or buffer argument" + res = fcntl.ioctl(mfd, TIOCGPGRP, buf, False) assert res == expected _______________________________________________ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit