[pypy-commit] pypy refactor-buffer-api: cleanup fcntl/ioctl behavior

bdkearns noreply at buildbot.pypy.org
Thu Apr 24 21:37:42 CEST 2014


Author: Brian Kearns <bdkearns at 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
 


More information about the pypy-commit mailing list