[pypy-commit] pypy default: 'nt.spawnve()', a Windows function

arigo noreply at buildbot.pypy.org
Thu Nov 10 15:54:00 CET 2011


Author: Armin Rigo <arigo at tunes.org>
Branch: 
Changeset: r49280:bde6464f341d
Date: 2011-11-10 15:53 +0100
http://bitbucket.org/pypy/pypy/changeset/bde6464f341d/

Log:	'nt.spawnve()', a Windows function

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
@@ -137,6 +137,8 @@
         interpleveldefs['execve'] = 'interp_posix.execve'
     if hasattr(posix, 'spawnv'):
         interpleveldefs['spawnv'] = 'interp_posix.spawnv'
+    if hasattr(posix, 'spawnve'):
+        interpleveldefs['spawnve'] = 'interp_posix.spawnve'
     if hasattr(os, 'uname'):
         interpleveldefs['uname'] = 'interp_posix.uname'
     if hasattr(os, 'sysconf'):
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
@@ -760,6 +760,14 @@
     except OSError, e:
         raise wrap_oserror(space, e)
 
+def _env2interp(space, w_env):
+    env = {}
+    w_keys = space.call_method(w_env, 'keys')
+    for w_key in space.unpackiterable(w_keys):
+        w_value = space.getitem(w_env, w_key)
+        env[space.str_w(w_key)] = space.str_w(w_value)
+    return env
+
 def execve(space, w_command, w_args, w_env):
     """ execve(path, args, env)
 
@@ -771,11 +779,7 @@
     """
     command = fsencode_w(space, w_command)
     args = [fsencode_w(space, w_arg) for w_arg in space.unpackiterable(w_args)]
-    env = {}
-    w_keys = space.call_method(w_env, 'keys')
-    for w_key in space.unpackiterable(w_keys):
-        w_value = space.getitem(w_env, w_key)
-        env[space.str_w(w_key)] = space.str_w(w_value)
+    env = _env2interp(space, w_env)
     try:
         os.execve(command, args, env)
     except OSError, e:
@@ -790,6 +794,16 @@
         raise wrap_oserror(space, e)
     return space.wrap(ret)
 
+ at unwrap_spec(mode=int, path=str)
+def spawnve(space, mode, path, w_args, w_env):
+    args = [space.str_w(w_arg) for w_arg in space.unpackiterable(w_args)]
+    env = _env2interp(space, w_env)
+    try:
+        ret = os.spawnve(mode, path, args, env)
+    except OSError, e:
+        raise wrap_oserror(space, e)
+    return space.wrap(ret)
+
 def utime(space, w_path, w_tuple):
     """ utime(path, (atime, mtime))
 utime(path, None)
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
@@ -471,6 +471,17 @@
                             ['python', '-c', 'raise(SystemExit(42))'])
             assert ret == 42
 
+    if hasattr(__import__(os.name), "spawnve"):
+        def test_spawnve(self):
+            os = self.posix
+            import sys
+            print self.python
+            ret = os.spawnve(os.P_WAIT, self.python,
+                             ['python', '-c',
+                              "raise(SystemExit(int(__import__('os').environ['FOOBAR'])))"],
+                             {'FOOBAR': '42'})
+            assert ret == 42
+
     def test_popen(self):
         os = self.posix
         for i in range(5):
diff --git a/pypy/rpython/module/ll_os.py b/pypy/rpython/module/ll_os.py
--- a/pypy/rpython/module/ll_os.py
+++ b/pypy/rpython/module/ll_os.py
@@ -356,6 +356,32 @@
         return extdef([int, str, [str]], int, llimpl=spawnv_llimpl,
                       export_name="ll_os.ll_os_spawnv")
 
+    @registering_if(os, 'spawnve')
+    def register_os_spawnve(self):
+        os_spawnve = self.llexternal('spawnve',
+                                     [rffi.INT, rffi.CCHARP, rffi.CCHARPP,
+                                      rffi.CCHARPP],
+                                     rffi.INT)
+
+        def spawnve_llimpl(mode, path, args, env):
+            envstrs = []
+            for item in env.iteritems():
+                envstrs.append("%s=%s" % item)
+
+            mode = rffi.cast(rffi.INT, mode)
+            l_args = rffi.liststr2charpp(args)
+            l_env = rffi.liststr2charpp(envstrs)
+            childpid = os_spawnve(mode, path, l_args, l_env)
+            rffi.free_charpp(l_env)
+            rffi.free_charpp(l_args)
+            if childpid == -1:
+                raise OSError(rposix.get_errno(), "os_spawnve failed")
+            return rffi.cast(lltype.Signed, childpid)
+
+        return extdef([int, str, [str], {str: str}], int,
+                      llimpl=spawnve_llimpl,
+                      export_name="ll_os.ll_os_spawnve")
+
     @registering(os.dup)
     def register_os_dup(self):
         os_dup = self.llexternal(underscore_on_windows+'dup', [rffi.INT], rffi.INT)
diff --git a/pypy/translator/c/test/test_extfunc.py b/pypy/translator/c/test/test_extfunc.py
--- a/pypy/translator/c/test/test_extfunc.py
+++ b/pypy/translator/c/test/test_extfunc.py
@@ -818,6 +818,24 @@
         func()
         assert open(filename).read() == "2"
 
+if hasattr(posix, 'spawnve'):
+    def test_spawnve():
+        filename = str(udir.join('test_spawnve.txt'))
+        progname = str(sys.executable)
+        scriptpath = udir.join('test_spawnve.py')
+        scriptpath.write('import os\n' +
+                         'f=open(%r,"w")\n' % filename +
+                         'f.write(os.environ["FOOBAR"])\n' +
+                         'f.close\n')
+        scriptname = str(scriptpath)
+        def does_stuff():
+            l = [progname, scriptname]
+            pid = os.spawnve(os.P_NOWAIT, progname, l, {'FOOBAR': '42'})
+            os.waitpid(pid, 0)
+        func = compile(does_stuff, [])
+        func()
+        assert open(filename).read() == "42"
+
 def test_utime():
     path = str(udir.ensure("test_utime.txt"))
     from time import time, sleep


More information about the pypy-commit mailing list