[pypy-svn] r79599 - in pypy/trunk/pypy: module/posix module/posix/test rpython/module

afa at codespeak.net afa at codespeak.net
Sat Nov 27 18:00:55 CET 2010


Author: afa
Date: Sat Nov 27 18:00:52 2010
New Revision: 79599

Modified:
   pypy/trunk/pypy/module/posix/__init__.py
   pypy/trunk/pypy/module/posix/interp_posix.py
   pypy/trunk/pypy/module/posix/test/test_posix2.py
   pypy/trunk/pypy/rpython/module/ll_os.py
Log:
Implement os.forkpty()


Modified: pypy/trunk/pypy/module/posix/__init__.py
==============================================================================
--- pypy/trunk/pypy/module/posix/__init__.py	(original)
+++ pypy/trunk/pypy/module/posix/__init__.py	Sat Nov 27 18:00:52 2010
@@ -96,6 +96,8 @@
         interpleveldefs['fork'] = 'interp_posix.fork'
     if hasattr(os, 'openpty'):
         interpleveldefs['openpty'] = 'interp_posix.openpty'
+    if hasattr(os, 'forkpty'):
+        interpleveldefs['forkpty'] = 'interp_posix.forkpty'
     if hasattr(os, 'waitpid'):
         interpleveldefs['waitpid'] = 'interp_posix.waitpid'
     if hasattr(os, 'execv'):

Modified: pypy/trunk/pypy/module/posix/interp_posix.py
==============================================================================
--- pypy/trunk/pypy/module/posix/interp_posix.py	(original)
+++ pypy/trunk/pypy/module/posix/interp_posix.py	Sat Nov 27 18:00:52 2010
@@ -608,6 +608,14 @@
         raise wrap_oserror(space, e)
     return space.newtuple([space.wrap(master_fd), space.wrap(slave_fd)])
 
+def forkpty(space):
+    try:
+        pid, master_fd = os.forkpty()
+    except OSError, e:
+        raise wrap_oserror(space, e)
+    return space.newtuple([space.wrap(pid),
+                           space.wrap(master_fd)])
+
 def waitpid(space, pid, options):
     """ waitpid(pid, options) -> (pid, status)
     

Modified: pypy/trunk/pypy/module/posix/test/test_posix2.py
==============================================================================
--- pypy/trunk/pypy/module/posix/test/test_posix2.py	(original)
+++ pypy/trunk/pypy/module/posix/test/test_posix2.py	Sat Nov 27 18:00:52 2010
@@ -331,6 +331,22 @@
             data = os.read(master_fd, 100)
             assert data.startswith('x')
 
+    if hasattr(__import__(os.name), "forkpty"):
+        def test_forkpty(self):
+            import sys
+            os = self.posix
+            childpid, master_fd = os.forkpty()
+            assert isinstance(childpid, int)
+            assert isinstance(master_fd, int)
+            if childpid == 0:
+                data = os.read(0, 100)
+                if data.startswith('abc'):
+                    os._exit(42)
+                else:
+                    os._exit(43)
+            os.write(master_fd, 'abc\n')
+            _, status = os.waitpid(childpid, 0)
+            assert status >> 8 == 42
 
     if hasattr(__import__(os.name), "execv"):
         def test_execv(self):

Modified: pypy/trunk/pypy/rpython/module/ll_os.py
==============================================================================
--- pypy/trunk/pypy/rpython/module/ll_os.py	(original)
+++ pypy/trunk/pypy/rpython/module/ll_os.py	Sat Nov 27 18:00:52 2010
@@ -1386,6 +1386,25 @@
         return extdef([], (int, int), "ll_os.ll_os_openpty",
                       llimpl=openpty_llimpl)
 
+    @registering_if(os, 'forkpty')
+    def register_os_forkpty(self):
+        os_forkpty = self.llexternal(
+            'forkpty',
+            [rffi.INTP, rffi.VOIDP, rffi.VOIDP, rffi.VOIDP],
+            rffi.PID_T,
+            compilation_info=ExternalCompilationInfo(libraries=['util']))
+        def forkpty_llimpl():
+            master_p = lltype.malloc(rffi.INTP.TO, 1, flavor='raw')
+            childpid = os_forkpty(master_p, None, None, None)
+            master_fd = master_p[0]
+            lltype.free(master_p, flavor='raw')
+            if childpid == -1:
+                raise OSError(rposix.get_errno(), "os_forkpty failed")
+            return (rffi.cast(lltype.Signed, childpid),
+                    rffi.cast(lltype.Signed, master_fd))
+
+        return extdef([], (int, int), "ll_os.ll_os_forkpty",
+                      llimpl=forkpty_llimpl)
 
     @registering(os._exit)
     def register_os__exit(self):



More information about the Pypy-commit mailing list