Author: Armin Rigo <[email protected]>
Branch:
Changeset: r69115:56fc72b18321
Date: 2014-02-10 11:09 +0100
http://bitbucket.org/pypy/pypy/changeset/56fc72b18321/
Log: Add create_popen_file(), which calls directly the C library's
popen() function.
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,9 @@
c_fgets = llexternal('fgets', [rffi.CCHARP, rffi.INT, lltype.Ptr(FILE)],
rffi.CCHARP)
+c_popen = llexternal('popen', [rffi.CCHARP, rffi.CCHARP], lltype.Ptr(FILE))
+c_pclose = llexternal('pclose', [lltype.Ptr(FILE)], rffi.INT)
+
BASE_BUF_SIZE = 4096
BASE_LINE_SIZE = 100
@@ -75,6 +78,21 @@
raise OSError(errno, os.strerror(errno))
return RFile(res)
+def create_popen_file(command, type):
+ ll_command = rffi.str2charp(command)
+ try:
+ ll_type = rffi.str2charp(type)
+ try:
+ ll_f = c_popen(ll_command, ll_type)
+ if not ll_f:
+ errno = rposix.get_errno()
+ raise OSError(errno, os.strerror(errno))
+ finally:
+ lltype.free(ll_type, flavor='raw')
+ finally:
+ lltype.free(ll_command, flavor='raw')
+ return RPopenFile(ll_f)
+
class RFile(object):
def __init__(self, ll_file):
self.ll_file = ll_file
@@ -100,12 +118,15 @@
def close(self):
if self.ll_file:
# double close is allowed
- res = c_close(self.ll_file)
+ res = self._do_close()
self.ll_file = lltype.nullptr(FILE)
if res == -1:
errno = rposix.get_errno()
raise OSError(errno, os.strerror(errno))
+ def _do_close(self):
+ return c_close(self.ll_file)
+
def read(self, size=-1):
# XXX CPython uses a more delicate logic here
ll_file = self.ll_file
@@ -234,3 +255,9 @@
finally:
rffi.keep_buffer_alive_until_here(raw_buf, gc_buf)
raise ValueError("I/O operation on closed file")
+
+
+class RPopenFile(RFile):
+
+ def _do_close(self):
+ return c_pclose(self.ll_file)
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
@@ -1,5 +1,5 @@
-import os
+import os, sys, py
from rpython.rtyper.test.tool import BaseRtypingTest
from rpython.tool.udir import udir
from rpython.rlib import rfile
@@ -184,3 +184,15 @@
got = f.readline()
assert got == ''
f.close()
+
+
+class TestPopen:
+ def setup_class(cls):
+ if sys.platform == 'win32':
+ py.test.skip("not for win32")
+
+ def test_popen(self):
+ f = rfile.create_popen_file("python -c 'print 42'", "r")
+ s = f.read()
+ f.close()
+ assert s == '42\n'
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit