[pypy-commit] pypy errno-again: Add some more get_errno() -> get_saved_errno()

arigo noreply at buildbot.pypy.org
Thu Jan 15 15:31:51 CET 2015


Author: Armin Rigo <arigo at tunes.org>
Branch: errno-again
Changeset: r75347:56abcde18cf2
Date: 2015-01-15 15:31 +0100
http://bitbucket.org/pypy/pypy/changeset/56abcde18cf2/

Log:	Add some more get_errno() -> get_saved_errno()

diff --git a/pypy/module/_io/interp_bufferedio.py b/pypy/module/_io/interp_bufferedio.py
--- a/pypy/module/_io/interp_bufferedio.py
+++ b/pypy/module/_io/interp_bufferedio.py
@@ -19,10 +19,16 @@
 
 
 def make_write_blocking_error(space, written):
+    # XXX CPython reads 'errno' here.  I *think* it doesn't make sense,
+    # because we might reach this point after calling a write() method
+    # that may be overridden by the user, if that method returns None.
+    # In that case what we get is a potentially nonsense errno.  But
+    # we'll use get_saved_errno() anyway, and hope (like CPython does)
+    # that we're getting a reasonable value at this point.
     w_type = space.gettypeobject(W_BlockingIOError.typedef)
     w_value = space.call_function(
         w_type,
-        space.wrap(rposix.get_errno()),
+        space.wrap(rposix.get_saved_errno()),
         space.wrap("write could not complete without blocking"),
         space.wrap(written))
     return OperationError(w_type, w_value)
diff --git a/pypy/module/_locale/interp_locale.py b/pypy/module/_locale/interp_locale.py
--- a/pypy/module/_locale/interp_locale.py
+++ b/pypy/module/_locale/interp_locale.py
@@ -300,7 +300,8 @@
         return space.wrap(result)
 
     _bindtextdomain = rlocale.external('bindtextdomain', [rffi.CCHARP, rffi.CCHARP],
-                                                                rffi.CCHARP)
+                                                                rffi.CCHARP,
+                                       save_err=rffi.RFFI_SAVE_ERRNO)
 
     @unwrap_spec(domain=str)
     def bindtextdomain(space, domain, w_dir):
@@ -325,7 +326,7 @@
                 rffi.free_charp(dir_c)
 
         if not dirname:
-            errno = rposix.get_errno()
+            errno = rposix.get_saved_errno()
             raise OperationError(space.w_OSError, space.wrap(errno))
         return space.wrap(rffi.charp2str(dirname))
 
diff --git a/pypy/module/_multiprocessing/interp_semaphore.py b/pypy/module/_multiprocessing/interp_semaphore.py
--- a/pypy/module/_multiprocessing/interp_semaphore.py
+++ b/pypy/module/_multiprocessing/interp_semaphore.py
@@ -81,51 +81,59 @@
 
     _sem_open = external('sem_open',
                          [rffi.CCHARP, rffi.INT, rffi.INT, rffi.UINT],
-                         SEM_T)
+                         SEM_T, save_err=rffi.RFFI_SAVE_ERRNO)
     # sem_close is releasegil=False to be able to use it in the __del__
-    _sem_close = external('sem_close', [SEM_T], rffi.INT, releasegil=False)
-    _sem_unlink = external('sem_unlink', [rffi.CCHARP], rffi.INT)
-    _sem_wait = external('sem_wait', [SEM_T], rffi.INT)
-    _sem_trywait = external('sem_trywait', [SEM_T], rffi.INT)
-    _sem_post = external('sem_post', [SEM_T], rffi.INT)
-    _sem_getvalue = external('sem_getvalue', [SEM_T, rffi.INTP], rffi.INT)
+    _sem_close = external('sem_close', [SEM_T], rffi.INT, releasegil=False,
+                          save_err=rffi.RFFI_SAVE_ERRNO)
+    _sem_unlink = external('sem_unlink', [rffi.CCHARP], rffi.INT,
+                           save_err=rffi.RFFI_SAVE_ERRNO)
+    _sem_wait = external('sem_wait', [SEM_T], rffi.INT,
+                         save_err=rffi.RFFI_SAVE_ERRNO)
+    _sem_trywait = external('sem_trywait', [SEM_T], rffi.INT,
+                            save_err=rffi.RFFI_SAVE_ERRNO)
+    _sem_post = external('sem_post', [SEM_T], rffi.INT,
+                         save_err=rffi.RFFI_SAVE_ERRNO)
+    _sem_getvalue = external('sem_getvalue', [SEM_T, rffi.INTP], rffi.INT,
+                             save_err=rffi.RFFI_SAVE_ERRNO)
 
-    _gettimeofday = external('gettimeofday', [TIMEVALP, rffi.VOIDP], rffi.INT)
+    _gettimeofday = external('gettimeofday', [TIMEVALP, rffi.VOIDP], rffi.INT,
+                             save_err=rffi.RFFI_SAVE_ERRNO)
 
     _select = external('select', [rffi.INT, rffi.VOIDP, rffi.VOIDP, rffi.VOIDP,
-                                                          TIMEVALP], rffi.INT)
+                                                          TIMEVALP], rffi.INT,
+                       save_err=rffi.RFFI_SAVE_ERRNO)
 
     @jit.dont_look_inside
     def sem_open(name, oflag, mode, value):
         res = _sem_open(name, oflag, mode, value)
         if res == rffi.cast(SEM_T, SEM_FAILED):
-            raise OSError(rposix.get_errno(), "sem_open failed")
+            raise OSError(rposix.get_saved_errno(), "sem_open failed")
         return res
 
     def sem_close(handle):
         res = _sem_close(handle)
         if res < 0:
-            raise OSError(rposix.get_errno(), "sem_close failed")
+            raise OSError(rposix.get_saved_errno(), "sem_close failed")
 
     def sem_unlink(name):
         res = _sem_unlink(name)
         if res < 0:
-            raise OSError(rposix.get_errno(), "sem_unlink failed")
+            raise OSError(rposix.get_saved_errno(), "sem_unlink failed")
 
     def sem_wait(sem):
         res = _sem_wait(sem)
         if res < 0:
-            raise OSError(rposix.get_errno(), "sem_wait failed")
+            raise OSError(rposix.get_saved_errno(), "sem_wait failed")
 
     def sem_trywait(sem):
         res = _sem_trywait(sem)
         if res < 0:
-            raise OSError(rposix.get_errno(), "sem_trywait failed")
+            raise OSError(rposix.get_saved_errno(), "sem_trywait failed")
 
     def sem_timedwait(sem, deadline):
         res = _sem_timedwait(sem, deadline)
         if res < 0:
-            raise OSError(rposix.get_errno(), "sem_timedwait failed")
+            raise OSError(rposix.get_saved_errno(), "sem_timedwait failed")
 
     def _sem_timedwait_save(sem, deadline):
         delay = 0
@@ -135,7 +143,7 @@
                 # poll
                 if _sem_trywait(sem) == 0:
                     return 0
-                elif rposix.get_errno() != errno.EAGAIN:
+                elif rposix.get_saved_errno() != errno.EAGAIN:
                     return -1
 
                 now = gettimeofday()
@@ -143,7 +151,7 @@
                 c_tv_nsec = rffi.getintfield(deadline[0], 'c_tv_nsec')
                 if (c_tv_sec < now[0] or
                     (c_tv_sec == now[0] and c_tv_nsec <= now[1])):
-                    rposix.set_errno(errno.ETIMEDOUT)
+                    rposix.set_saved_errno(errno.ETIMEDOUT)
                     return -1
 
 
@@ -166,21 +174,21 @@
 
     if SEM_TIMED_WAIT:
         _sem_timedwait = external('sem_timedwait', [SEM_T, TIMESPECP],
-                                  rffi.INT)
+                                  rffi.INT, save_err=rffi.RFFI_SAVE_ERRNO)
     else:
         _sem_timedwait = _sem_timedwait_save
 
     def sem_post(sem):
         res = _sem_post(sem)
         if res < 0:
-            raise OSError(rposix.get_errno(), "sem_post failed")
+            raise OSError(rposix.get_saved_errno(), "sem_post failed")
 
     def sem_getvalue(sem):
         sval_ptr = lltype.malloc(rffi.INTP.TO, 1, flavor='raw')
         try:
             res = _sem_getvalue(sem, sval_ptr)
             if res < 0:
-                raise OSError(rposix.get_errno(), "sem_getvalue failed")
+                raise OSError(rposix.get_saved_errno(), "sem_getvalue failed")
             return rffi.cast(lltype.Signed, sval_ptr[0])
         finally:
             lltype.free(sval_ptr, flavor='raw')
@@ -190,7 +198,7 @@
         try:
             res = _gettimeofday(now, None)
             if res < 0:
-                raise OSError(rposix.get_errno(), "gettimeofday failed")
+                raise OSError(rposix.get_saved_errno(), "gettimeofday failed")
             return (rffi.getintfield(now[0], 'c_tv_sec'),
                     rffi.getintfield(now[0], 'c_tv_usec'))
         finally:
diff --git a/pypy/module/cpyext/pyerrors.py b/pypy/module/cpyext/pyerrors.py
--- a/pypy/module/cpyext/pyerrors.py
+++ b/pypy/module/cpyext/pyerrors.py
@@ -9,7 +9,7 @@
     PyObject, PyObjectP, make_ref, from_ref, Py_DecRef, borrow_from)
 from pypy.module.cpyext.state import State
 from pypy.module.cpyext.import_ import PyImport_Import
-from rpython.rlib.rposix import get_errno
+from rpython.rlib import rposix, jit
 
 @cpython_api([PyObject, PyObject], lltype.Void)
 def PyErr_SetObject(space, w_type, w_value):
@@ -159,6 +159,7 @@
     PyErr_SetFromErrnoWithFilenameObject(space, w_type, filename)
 
 @cpython_api([PyObject, PyObject], PyObject)
+ at jit.dont_look_inside       # direct use of _get_errno()
 def PyErr_SetFromErrnoWithFilenameObject(space, w_type, w_value):
     """Similar to PyErr_SetFromErrno(), with the additional behavior that if
     w_value is not NULL, it is passed to the constructor of type as a
@@ -166,7 +167,7 @@
     this is used to define the filename attribute of the exception instance.
     Return value: always NULL."""
     # XXX Doesn't actually do anything with PyErr_CheckSignals.
-    errno = get_errno()
+    errno = rposix._get_errno()
     msg = os.strerror(errno)
     if w_value:
         w_error = space.call_function(w_type,
diff --git a/pypy/module/cpyext/pystrtod.py b/pypy/module/cpyext/pystrtod.py
--- a/pypy/module/cpyext/pystrtod.py
+++ b/pypy/module/cpyext/pystrtod.py
@@ -4,12 +4,13 @@
 from pypy.module.cpyext.pyobject import PyObject
 from rpython.rlib import rdtoa
 from rpython.rlib import rfloat
-from rpython.rlib import rposix
+from rpython.rlib import rposix, jit
 from rpython.rtyper.lltypesystem import lltype
 from rpython.rtyper.lltypesystem import rffi
 
 
 @cpython_api([rffi.CCHARP, rffi.CCHARPP, PyObject], rffi.DOUBLE, error=-1.0)
+ at jit.dont_look_inside       # direct use of _get_errno()
 def PyOS_string_to_double(space, s, endptr, w_overflow_exception):
     """Convert a string s to a double, raising a Python
     exception on failure.  The set of accepted strings corresponds to
@@ -52,8 +53,8 @@
             raise OperationError(
                 space.w_ValueError,
                 space.wrap('invalid input at position %s' % endpos))
-        if rposix.get_errno() == errno.ERANGE:
-            rposix.set_errno(0)
+        if rposix._get_errno() == errno.ERANGE:
+            rposix._set_errno(0)
             if w_overflow_exception is None:
                 if result > 0:
                     return rfloat.INFINITY
diff --git a/pypy/module/time/interp_time.py b/pypy/module/time/interp_time.py
--- a/pypy/module/time/interp_time.py
+++ b/pypy/module/time/interp_time.py
@@ -169,10 +169,12 @@
 c_clock = external('clock', [rffi.TIME_TP], clock_t)
 c_time = external('time', [rffi.TIME_TP], rffi.TIME_T)
 c_ctime = external('ctime', [rffi.TIME_TP], rffi.CCHARP)
-c_gmtime = external('gmtime', [rffi.TIME_TP], TM_P)
+c_gmtime = external('gmtime', [rffi.TIME_TP], TM_P,
+                    save_err=rffi.RFFI_SAVE_ERRNO)
 c_mktime = external('mktime', [TM_P], rffi.TIME_T)
 c_asctime = external('asctime', [TM_P], rffi.CCHARP)
-c_localtime = external('localtime', [rffi.TIME_TP], TM_P)
+c_localtime = external('localtime', [rffi.TIME_TP], TM_P,
+                       save_err=rffi.RFFI_SAVE_ERRNO)
 if _POSIX:
     c_tzset = external('tzset', [], lltype.Void)
 if _WIN:
@@ -304,7 +306,7 @@
     _set_module_object(space, 'altzone', space.wrap(altzone))
 
 def _get_error_msg():
-    errno = rposix.get_errno()
+    errno = rposix.get_saved_errno()
     return os.strerror(errno)
 
 if sys.platform != 'win32':
diff --git a/rpython/rlib/clibffi.py b/rpython/rlib/clibffi.py
--- a/rpython/rlib/clibffi.py
+++ b/rpython/rlib/clibffi.py
@@ -11,7 +11,7 @@
 from rpython.rlib.rmmap import alloc
 from rpython.rlib.rdynload import dlopen, dlclose, dlsym, dlsym_byordinal
 from rpython.rlib.rdynload import DLOpenError, DLLHANDLE
-from rpython.rlib import jit
+from rpython.rlib import jit, rposix
 from rpython.rlib.objectmodel import specialize
 from rpython.translator.tool.cbuild import ExternalCompilationInfo
 from rpython.translator.platform import platform
@@ -412,7 +412,7 @@
 
 
 @jit.jit_callback("CLIBFFI")
-def ll_callback(ffi_cif, ll_res, ll_args, ll_userdata):
+def _ll_callback(ffi_cif, ll_res, ll_args, ll_userdata):
     """ Callback specification.
     ffi_cif - something ffi specific, don't care
     ll_args - rffi.VOIDPP - pointer to array of pointers to args
@@ -423,6 +423,12 @@
     userdata = rffi.cast(USERDATA_P, ll_userdata)
     userdata.callback(ll_args, ll_res, userdata)
 
+def ll_callback(ffi_cif, ll_res, ll_args, ll_userdata):
+    rposix._errno_after(rffi.RFFI_ERR_ALL)
+    _ll_callback(ffi_cif, ll_res, ll_args, ll_userdata)
+    rposix._errno_before(rffi.RFFI_ERR_ALL)
+
+
 class StackCheckError(ValueError):
     message = None
     def __init__(self, message):


More information about the pypy-commit mailing list