[pypy-commit] pypy default: Passing file arguments.
arigo
noreply at buildbot.pypy.org
Sat Oct 20 10:21:47 CEST 2012
Author: Armin Rigo <arigo at tunes.org>
Branch:
Changeset: r58268:235d902b48ba
Date: 2012-10-20 10:21 +0200
http://bitbucket.org/pypy/pypy/changeset/235d902b48ba/
Log: Passing file arguments.
diff --git a/pypy/module/_cffi_backend/ctypefunc.py b/pypy/module/_cffi_backend/ctypefunc.py
--- a/pypy/module/_cffi_backend/ctypefunc.py
+++ b/pypy/module/_cffi_backend/ctypefunc.py
@@ -147,9 +147,13 @@
argtype = self.fargs[i]
if isinstance(argtype, W_CTypePointer):
data = rffi.ptradd(buffer, cif_descr.exchange_args[i])
- if get_mustfree_flag(data):
+ flag = get_mustfree_flag(data)
+ if flag == 1:
raw_string = rffi.cast(rffi.CCHARPP, data)[0]
lltype.free(raw_string, flavor='raw')
+ elif flag == 2:
+ file = rffi.cast(rffi.CCHARPP, data)[0]
+ rffi_fclose(file)
lltype.free(buffer, flavor='raw')
return w_res
@@ -164,6 +168,26 @@
assert isinstance(abi, int)
return space.wrap(abi)
+rffi_fdopen = rffi.llexternal("fdopen", [rffi.INT, rffi.CCHARP], rffi.CCHARP)
+rffi_fclose = rffi.llexternal("fclose", [rffi.CCHARP], rffi.INT)
+
+def prepare_file_call_argument(fileobj):
+ import os
+ space = fileobj.space
+ fd = fileobj.direct_fileno()
+ if fd < 0:
+ raise OperationError(self.space.w_ValueError,
+ self.space.wrap("file has no OS file descriptor"))
+ try:
+ fd2 = os.dup(fd)
+ f = rffi_fdopen(fd2, fileobj.mode)
+ if not f:
+ os.close(fd2)
+ raise OSError(rposix.get_errno(), "fdopen failed")
+ except OSError, e:
+ raise wrap_oserror(space, e)
+ return f
+
# ____________________________________________________________
diff --git a/pypy/module/_cffi_backend/ctypeptr.py b/pypy/module/_cffi_backend/ctypeptr.py
--- a/pypy/module/_cffi_backend/ctypeptr.py
+++ b/pypy/module/_cffi_backend/ctypeptr.py
@@ -177,7 +177,8 @@
class W_CTypePointer(W_CTypePtrBase):
- _attrs_ = []
+ _attrs_ = ['is_file']
+ _immutable_fields_ = ['is_file']
def __init__(self, space, ctitem):
from pypy.module._cffi_backend import ctypearray
@@ -186,6 +187,7 @@
extra = "(*)" # obscure case: see test_array_add
else:
extra = " *"
+ self.is_file = (ctitem.name == "struct _IO_FILE")
W_CTypePtrBase.__init__(self, space, size, extra, 2, ctitem)
def newp(self, w_init):
@@ -234,7 +236,7 @@
p = rffi.ptradd(cdata, i * self.ctitem.size)
return cdataobj.W_CData(space, p, self)
- def _prepare_pointer_call_argument(self, w_init):
+ def _prepare_pointer_call_argument(self, w_init, cdata):
space = self.space
if (space.isinstance_w(w_init, space.w_list) or
space.isinstance_w(w_init, space.w_tuple)):
@@ -242,10 +244,19 @@
elif space.isinstance_w(w_init, space.w_basestring):
# from a string, we add the null terminator
length = space.int_w(space.len(w_init)) + 1
+ elif self.is_file:
+ from pypy.module._file.interp_file import W_File
+ from pypy.module._cffi_backend import ctypefunc
+ ob = space.interpclass_w(w_init)
+ if isinstance(ob, W_File):
+ result = ctypefunc.prepare_file_call_argument(ob)
+ rffi.cast(rffi.CCHARPP, cdata)[0] = result
+ return 2
+ return 0
else:
- return lltype.nullptr(rffi.CCHARP.TO)
+ return 0
if self.ctitem.size <= 0:
- return lltype.nullptr(rffi.CCHARP.TO)
+ return 0
try:
datasize = ovfcheck(length * self.ctitem.size)
except OverflowError:
@@ -258,25 +269,19 @@
except Exception:
lltype.free(result, flavor='raw')
raise
- return result
+ rffi.cast(rffi.CCHARPP, cdata)[0] = result
+ return 1
def convert_argument_from_object(self, cdata, w_ob):
from pypy.module._cffi_backend.ctypefunc import set_mustfree_flag
space = self.space
ob = space.interpclass_w(w_ob)
- if isinstance(ob, cdataobj.W_CData):
- buffer = lltype.nullptr(rffi.CCHARP.TO)
- else:
- buffer = self._prepare_pointer_call_argument(w_ob)
- #
- if buffer:
- rffi.cast(rffi.CCHARPP, cdata)[0] = buffer
- set_mustfree_flag(cdata, True)
- return True
- else:
- set_mustfree_flag(cdata, False)
+ result = (not isinstance(ob, cdataobj.W_CData) and
+ self._prepare_pointer_call_argument(w_ob, cdata))
+ if result == 0:
self.convert_from_object(cdata, w_ob)
- return False
+ set_mustfree_flag(cdata, result)
+ return result
def getcfield(self, attr):
return self.ctitem.getcfield(attr)
More information about the pypy-commit
mailing list