Author: Armin Rigo <ar...@tunes.org>
Branch: 
Changeset: r67898:d3fc81a3142a
Date: 2013-11-09 16:26 +0100
http://bitbucket.org/pypy/pypy/changeset/d3fc81a3142a/

Log:    os.confstr()

diff --git a/pypy/module/posix/__init__.py b/pypy/module/posix/__init__.py
--- a/pypy/module/posix/__init__.py
+++ b/pypy/module/posix/__init__.py
@@ -131,6 +131,9 @@
     if hasattr(os, 'fpathconf'):
         interpleveldefs['fpathconf'] = 'interp_posix.fpathconf'
         interpleveldefs['pathconf_names'] = 'space.wrap(os.pathconf_names)'
+    if hasattr(os, 'confstr'):
+        interpleveldefs['confstr'] = 'interp_posix.confstr'
+        interpleveldefs['confstr_names'] = 'space.wrap(os.confstr_names)'
     if hasattr(os, 'ttyname'):
         interpleveldefs['ttyname'] = 'interp_posix.ttyname'
     if hasattr(os, 'getloadavg'):
diff --git a/pypy/module/posix/interp_posix.py 
b/pypy/module/posix/interp_posix.py
--- a/pypy/module/posix/interp_posix.py
+++ b/pypy/module/posix/interp_posix.py
@@ -1233,15 +1233,28 @@
 
 def sysconf(space, w_name):
     num = confname_w(space, w_name, os.sysconf_names)
-    return space.wrap(os.sysconf(num))
+    try:
+        res = os.sysconf(num)
+    except OSError, e:
+        raise wrap_oserror(space, e)
+    return space.wrap(res)
 
 @unwrap_spec(fd=c_int)
 def fpathconf(space, fd, w_name):
     num = confname_w(space, w_name, os.pathconf_names)
     try:
-        return space.wrap(os.fpathconf(fd, num))
+        res = os.fpathconf(fd, num)
     except OSError, e:
         raise wrap_oserror(space, e)
+    return space.wrap(res)
+
+def confstr(space, w_name):
+    num = confname_w(space, w_name, os.confstr_names)
+    try:
+        res = os.confstr(num)
+    except OSError, e:
+        raise wrap_oserror(space, e)
+    return space.wrap(res)
 
 @unwrap_spec(path='str0', uid=c_uid_t, gid=c_gid_t)
 def chown(space, path, uid, gid):
diff --git a/pypy/module/posix/test/test_posix2.py 
b/pypy/module/posix/test/test_posix2.py
--- a/pypy/module/posix/test/test_posix2.py
+++ b/pypy/module/posix/test/test_posix2.py
@@ -78,6 +78,11 @@
             cls.w_sysconf_name = space.wrap(sysconf_name)
             cls.w_sysconf_value = space.wrap(os.sysconf_names[sysconf_name])
             cls.w_sysconf_result = space.wrap(os.sysconf(sysconf_name))
+        if hasattr(os, 'confstr'):
+            confstr_name = os.confstr_names.keys()[0]
+            cls.w_confstr_name = space.wrap(confstr_name)
+            cls.w_confstr_value = space.wrap(os.confstr_names[confstr_name])
+            cls.w_confstr_result = space.wrap(os.confstr(confstr_name))
         cls.w_SIGABRT = space.wrap(signal.SIGABRT)
         cls.w_python = space.wrap(sys.executable)
         if hasattr(os, 'major'):
@@ -700,6 +705,17 @@
             raises(OSError, os.fpathconf, -1, "PC_PIPE_BUF")
             raises(ValueError, os.fpathconf, 1, "##")
 
+    if hasattr(os, 'confstr'):
+        def test_os_confstr(self):
+            os = self.posix
+            assert os.confstr(self.confstr_value) == self.confstr_result
+            assert os.confstr(self.confstr_name) == self.confstr_result
+            assert os.confstr_names[self.confstr_name] == self.confstr_value
+
+        def test_os_confstr_error(self):
+            os = self.posix
+            raises(ValueError, os.confstr, "!@#$%!#$!@#")
+
     if hasattr(os, 'wait'):
         def test_os_wait(self):
             os = self.posix
diff --git a/rpython/rtyper/module/ll_os.py b/rpython/rtyper/module/ll_os.py
--- a/rpython/rtyper/module/ll_os.py
+++ b/rpython/rtyper/module/ll_os.py
@@ -651,6 +651,30 @@
         return extdef([int, int], int, "ll_os.ll_fpathconf",
                       llimpl=fpathconf_llimpl)
 
+    @registering_if(os, 'confstr')
+    def register_os_confstr(self):
+        c_confstr = self.llexternal('confstr', [rffi.INT, rffi.CCHARP,
+                                                rffi.SIZE_T], rffi.SIZE_T)
+
+        def confstr_llimpl(i):
+            rposix.set_errno(0)
+            n = c_confstr(i, lltype.nullptr(rffi.CCHARP.TO), 0)
+            n = rffi.cast(lltype.Signed, n)
+            if n > 0:
+                buf = lltype.malloc(rffi.CCHARP.TO, n, flavor='raw')
+                try:
+                    c_confstr(i, buf, n)
+                    return rffi.charp2strn(buf, n)
+                finally:
+                    lltype.free(buf, flavor='raw')
+            else:
+                errno = rposix.get_errno()
+                if errno != 0:
+                    raise OSError(errno, "confstr failed")
+                return None
+        return extdef([int], SomeString(can_be_None=True),
+                      "ll_os.ll_confstr", llimpl=confstr_llimpl)
+
     @registering_if(os, 'getuid')
     def register_os_getuid(self):
         return self.extdef_for_os_function_returning_int('getuid')
diff --git a/rpython/rtyper/module/test/test_posix.py 
b/rpython/rtyper/module/test/test_posix.py
--- a/rpython/rtyper/module/test/test_posix.py
+++ b/rpython/rtyper/module/test/test_posix.py
@@ -1,5 +1,6 @@
 import py
 from rpython.rtyper.test.tool import BaseRtypingTest
+from rpython.rtyper.annlowlevel import hlstr
 from rpython.tool.udir import udir
 from rpython.rlib.rarithmetic import is_valid_int
 
@@ -176,6 +177,19 @@
                 return os.sysconf(i)
             assert self.interpret(f, [13]) == f(13)
 
+    if hasattr(os, 'confstr'):
+        def test_os_confstr(self):
+            def f(i):
+                try:
+                    return os.confstr(i)
+                except OSError:
+                    return "oooops!!"
+            some_value = os.confstr_names.values()[-1]
+            res = self.interpret(f, [some_value])
+            assert hlstr(res) == f(some_value)
+            res = self.interpret(f, [94781413])
+            assert hlstr(res) == "oooops!!"
+
     if hasattr(os, 'chroot'):
         def test_os_chroot(self):
             def f():
_______________________________________________
pypy-commit mailing list
pypy-commit@python.org
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to