[pypy-commit] pypy default: make os.fdopen rpython

fijal noreply at buildbot.pypy.org
Tue Apr 1 11:23:04 CEST 2014


Author: Maciej Fijalkowski <fijall at gmail.com>
Branch: 
Changeset: r70374:495dc5472421
Date: 2014-04-01 11:21 +0200
http://bitbucket.org/pypy/pypy/changeset/495dc5472421/

Log:	make os.fdopen rpython

diff --git a/rpython/flowspace/specialcase.py b/rpython/flowspace/specialcase.py
--- a/rpython/flowspace/specialcase.py
+++ b/rpython/flowspace/specialcase.py
@@ -49,6 +49,11 @@
     from rpython.rlib.rfile import create_file
     return ctx.appcall(create_file, *args_w)
 
+ at register_flow_sc(os.fdopen)
+def sc_os_fdopen(ctx, *args_w):
+    from rpython.rlib.rfile import create_fdopen_rfile
+    return ctx.appcall(create_fdopen_rfile, *args_w)
+
 @register_flow_sc(os.tmpfile)
 def sc_os_tmpfile(ctx):
     from rpython.rlib.rfile import create_temp_rfile
diff --git a/rpython/rlib/rfile.py b/rpython/rlib/rfile.py
--- a/rpython/rlib/rfile.py
+++ b/rpython/rlib/rfile.py
@@ -47,6 +47,7 @@
                      rffi.INT)
 c_tmpfile = llexternal('tmpfile', [], lltype.Ptr(FILE))
 c_fileno = llexternal(fileno, [lltype.Ptr(FILE)], rffi.INT)
+c_fdopen = llexternal('fdopen', [rffi.INT, rffi.CCHARP], lltype.Ptr(FILE))
 c_ftell = llexternal('ftell', [lltype.Ptr(FILE)], rffi.LONG)
 c_fflush = llexternal('fflush', [lltype.Ptr(FILE)], rffi.INT)
 c_ftruncate = llexternal(ftruncate, [rffi.INT, OFF_T], rffi.INT, macro=True)
@@ -93,6 +94,17 @@
         raise OSError(errno, os.strerror(errno))
     return RFile(res)
 
+def create_fdopen_rfile(fd, mode="r"):
+    assert mode is not None
+    ll_mode = rffi.str2charp(mode)
+    try:
+        ll_f = c_fdopen(rffi.cast(rffi.INT, fd), ll_mode)
+        if not ll_f:
+            errno = rposix.get_errno()
+            raise OSError(errno, os.strerror(errno))
+    finally:
+        lltype.free(ll_mode, flavor='raw')
+    return RFile(ll_f)
 
 def create_popen_file(command, type):
     ll_command = rffi.str2charp(command)
diff --git a/rpython/rlib/test/test_rfile.py b/rpython/rlib/test/test_rfile.py
--- a/rpython/rlib/test/test_rfile.py
+++ b/rpython/rlib/test/test_rfile.py
@@ -79,6 +79,22 @@
         f()
         self.interpret(f, [])
 
+    def test_fdopen(self):
+        fname = str(self.tmpdir.join('file_4a'))
+
+        def f():
+            f = open(fname, "w")
+            new_fno = os.dup(f.fileno())
+            f2 = os.fdopen(new_fno, "w")
+            f.close()
+            f2.write("xxx")
+            f2.close()
+
+        f()
+        assert open(fname).read() == "xxx"
+        self.interpret(f, [])
+        assert open(fname).read() == "xxx"
+
     def test_fileno(self):
         fname = str(self.tmpdir.join('file_5'))
 


More information about the pypy-commit mailing list