Author: Amaury Forgeot d'Arc <[email protected]>
Branch: more-rposix
Changeset: r74383:d7099109e3cc
Date: 2014-11-07 19:32 +0100
http://bitbucket.org/pypy/pypy/changeset/d7099109e3cc/

Log:    Port fork() and forkpty()

diff --git a/rpython/rlib/rposix.py b/rpython/rlib/rposix.py
--- a/rpython/rlib/rposix.py
+++ b/rpython/rlib/rposix.py
@@ -10,6 +10,7 @@
 from rpython.rlib import jit
 from rpython.translator.platform import platform
 from rpython.rlib import rstring
+from rpython.rlib import debug, rthread
 
 _WIN32 = sys.platform.startswith('win')
 UNDERSCORE_ON_WIN32 = '_' if _WIN32 else ''
@@ -137,12 +138,15 @@
 
 if _WIN32:
     includes = ['io.h', 'sys/utime.h', 'sys/types.h']
+    libraries = []
 else:
     includes = ['unistd.h',  'sys/types.h',
                 'utime.h', 'sys/time.h', 'sys/times.h',
                 'grp.h']
+    libraries = ['util']
 eci = ExternalCompilationInfo(
     includes=includes,
+    libraries=libraries,
 )
 
 class CConfig:
@@ -329,7 +333,7 @@
 
 @specialize.arg(0)
 def handle_posix_error(name, result):
-    if result < 0:
+    if intmask(result) < 0:
         raise OSError(get_errno(), '%s failed' % name)
     return intmask(result)
 
@@ -408,6 +412,54 @@
     rffi.free_charpp(l_args)
     return handle_posix_error('spawnve', childpid)
 
+c_fork = external('fork', [], rffi.PID_T, _nowrapper = True)
+c_openpty = external('openpty',
+                     [rffi.INTP, rffi.INTP, rffi.VOIDP, rffi.VOIDP, 
rffi.VOIDP],
+                     rffi.INT)
+c_forkpty = external('forkpty',
+                     [rffi.INTP, rffi.VOIDP, rffi.VOIDP, rffi.VOIDP],
+                     rffi.PID_T)
+
+@replace_os_function('fork')
+def fork():
+    # NB. keep forkpty() up-to-date, too
+    ofs = debug.debug_offset()
+    opaqueaddr = rthread.gc_thread_before_fork()
+    childpid = c_fork()
+    rthread.gc_thread_after_fork(childpid, opaqueaddr)
+    childpid = handle_posix_error('fork', childpid)
+    if childpid == 0:
+        debug.debug_forked(ofs)
+    return childpid
+
+@replace_os_function('openpty')
+def openpty():
+    master_p = lltype.malloc(rffi.INTP.TO, 1, flavor='raw')
+    slave_p = lltype.malloc(rffi.INTP.TO, 1, flavor='raw')
+    try:
+        handle_posix_error(
+            'openpty', c_openpty(master_p, slave_p, None, None, None))
+        return (intmask(master_p[0]), intmask(slave_p[0]))
+    finally:
+        lltype.free(master_p, flavor='raw')
+        lltype.free(slave_p, flavor='raw')
+
+@replace_os_function('forkpty')
+def forkpty():
+    master_p = lltype.malloc(rffi.INTP.TO, 1, flavor='raw')
+    master_p[0] = rffi.cast(rffi.INT, -1)
+    try:
+        ofs = debug.debug_offset()
+        opaqueaddr = rthread.gc_thread_before_fork()
+        childpid = os_forkpty(master_p, None, None, None)
+        rthread.gc_thread_after_fork(childpid, opaqueaddr)
+        childpid = handle_posix_error('forkpty', childpid)
+        if childpid == 0:
+            debug.debug_forked(ofs)
+        return (childpid, master_p[0])
+    finally:
+        lltype.free(master_p, flavor='raw')
+
 @replace_os_function('getlogin')
 def getlogin():
     result = c_getlogin()
@@ -853,7 +905,7 @@
             raise OSError(errno, "sysconf failed")
     return res
 
-@replace_os_functions('fpathconf')
+@replace_os_function('fpathconf')
 def fpathconf(fd, value):
     rposix.set_errno(0)
     res = c_fpathconf(fd, value)
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
@@ -980,78 +980,6 @@
         return extdef([str0, str0], s_None, llimpl=symlink_llimpl,
                       export_name="ll_os.ll_os_symlink")
 
-    @registering_if(os, 'fork')
-    def register_os_fork(self):
-        from rpython.rlib import debug, rthread
-        os_fork = self.llexternal('fork', [], rffi.PID_T,
-                                  _nowrapper = True)
-
-        def fork_llimpl():
-            # NB. keep forkpty() up-to-date, too
-            ofs = debug.debug_offset()
-            opaqueaddr = rthread.gc_thread_before_fork()
-            childpid = rffi.cast(lltype.Signed, os_fork())
-            rthread.gc_thread_after_fork(childpid, opaqueaddr)
-            if childpid == -1:
-                raise OSError(rposix.get_errno(), "os_fork failed")
-            if childpid == 0:
-                debug.debug_forked(ofs)
-            return rffi.cast(lltype.Signed, childpid)
-
-        return extdef([], int, llimpl=fork_llimpl,
-                      export_name="ll_os.ll_os_fork")
-
-    @registering_if(os, 'openpty')
-    def register_os_openpty(self):
-        os_openpty = self.llexternal(
-            'openpty',
-            [rffi.INTP, rffi.INTP, rffi.VOIDP, rffi.VOIDP, rffi.VOIDP],
-            rffi.INT,
-            compilation_info=ExternalCompilationInfo(libraries=['util']))
-        def openpty_llimpl():
-            master_p = lltype.malloc(rffi.INTP.TO, 1, flavor='raw')
-            slave_p = lltype.malloc(rffi.INTP.TO, 1, flavor='raw')
-            result = os_openpty(master_p, slave_p, None, None, None)
-            master_fd = master_p[0]
-            slave_fd = slave_p[0]
-            lltype.free(master_p, flavor='raw')
-            lltype.free(slave_p, flavor='raw')
-            if result == -1:
-                raise OSError(rposix.get_errno(), "os_openpty failed")
-            return (rffi.cast(lltype.Signed, master_fd),
-                    rffi.cast(lltype.Signed, slave_fd))
-
-        return extdef([], (int, int), "ll_os.ll_os_openpty",
-                      llimpl=openpty_llimpl)
-
-    @registering_if(os, 'forkpty')
-    def register_os_forkpty(self):
-        from rpython.rlib import debug, rthread
-        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')
-            master_p[0] = rffi.cast(rffi.INT, -1)
-            ofs = debug.debug_offset()
-            opaqueaddr = rthread.gc_thread_before_fork()
-            childpid = rffi.cast(lltype.Signed,
-                                 os_forkpty(master_p, None, None, None))
-            rthread.gc_thread_after_fork(childpid, opaqueaddr)
-            master_fd = master_p[0]
-            lltype.free(master_p, flavor='raw')
-            if childpid == -1:
-                raise OSError(rposix.get_errno(), "os_forkpty failed")
-            if childpid == 0:
-                debug.debug_forked(ofs)
-            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):
         from rpython.rlib import debug
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to