Author: Maciej Fijalkowski <fij...@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) + +@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 _______________________________________________ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit