[pypy-commit] pypy default: merge

fijal noreply at buildbot.pypy.org
Mon May 4 14:07:22 CEST 2015


Author: Maciej Fijalkowski <fijall at gmail.com>
Branch: 
Changeset: r77038:079696fb2f9a
Date: 2015-05-04 14:07 +0200
http://bitbucket.org/pypy/pypy/changeset/079696fb2f9a/

Log:	merge

diff --git a/lib_pypy/_ctypes/function.py b/lib_pypy/_ctypes/function.py
--- a/lib_pypy/_ctypes/function.py
+++ b/lib_pypy/_ctypes/function.py
@@ -308,6 +308,8 @@
                 res = self.callable(*newargs)
             except:
                 exc_info = sys.exc_info()
+                if issubclass(exc_info[0], SystemExit):
+                    exc_info = handle_system_exit(exc_info)
                 traceback.print_tb(exc_info[2], file=sys.stderr)
                 print >>sys.stderr, "%s: %s" % (exc_info[0].__name__, exc_info[1])
                 return 0
@@ -715,3 +717,26 @@
     make_fastpath_subclass.memo[CFuncPtr] = CFuncPtrFast
     return CFuncPtrFast
 make_fastpath_subclass.memo = {}
+
+
+def handle_system_exit(exc_info):
+    # issue #1194: if we get SystemExit here, then exit the interpreter.
+    # Highly obscure imho but some people seem to depend on it.
+    try:
+        if sys.flags.inspect:
+            return exc_info   # Don't exit if -i flag was given.
+
+        code = exc_info[1].code
+        if isinstance(code, int):
+            exitcode = code
+        else:
+            f = getattr(sys, 'stderr', None)
+            if f is None:
+                f = sys.__stderr__
+            print >> f, code
+            exitcode = 1
+
+        _rawffi.exit(exitcode)
+
+    except:
+        return sys.exc_info()
diff --git a/pypy/module/_rawffi/__init__.py b/pypy/module/_rawffi/__init__.py
--- a/pypy/module/_rawffi/__init__.py
+++ b/pypy/module/_rawffi/__init__.py
@@ -29,6 +29,7 @@
         'get_last_error'     : 'interp_rawffi.get_last_error',
         'set_last_error'     : 'interp_rawffi.set_last_error',
         'SegfaultException'  : 'space.new_exception_class("_rawffi.SegfaultException")',
+        'exit'               : 'interp_exit.exit',
     }
 
     appleveldefs = {
diff --git a/pypy/module/_rawffi/interp_exit.py b/pypy/module/_rawffi/interp_exit.py
new file mode 100644
--- /dev/null
+++ b/pypy/module/_rawffi/interp_exit.py
@@ -0,0 +1,9 @@
+from pypy.interpreter.gateway import unwrap_spec
+from rpython.rtyper.lltypesystem import lltype, rffi
+
+
+ll_exit = rffi.llexternal('exit', [rffi.INT], lltype.Void, _nowrapper=True)
+
+ at unwrap_spec(status="c_int")
+def exit(space, status):
+    ll_exit(rffi.cast(rffi.INT, status))
diff --git a/pypy/module/_rawffi/test/test_exit.py b/pypy/module/_rawffi/test/test_exit.py
new file mode 100644
--- /dev/null
+++ b/pypy/module/_rawffi/test/test_exit.py
@@ -0,0 +1,15 @@
+
+class AppTestFfi:
+    spaceconfig = dict(usemodules=['_rawffi', 'posix'])
+
+    def test_exit(self):
+        import posix, _rawffi
+        if not hasattr(posix, 'fork'):
+            skip("requires fork() to test")
+        #
+        pid = posix.fork()
+        if pid == 0:
+            _rawffi.exit(5)   # in the child
+        pid, status = posix.waitpid(pid, 0)
+        assert posix.WIFEXITED(status)
+        assert posix.WEXITSTATUS(status) == 5


More information about the pypy-commit mailing list