diff --git a/Include/pymath.h b/Include/pymath.h --- a/Include/pymath.h +++ b/Include/pymath.h @@ -182,7 +182,7 @@ #if defined(__FreeBSD__) || defined(__OpenBSD__) #define Py_OVERFLOWED(X) isinf(X) #else -#define Py_OVERFLOWED(X) ((X) != 0.0 && (errno == ERANGE || \ +#define Py_OVERFLOWED(X) ((X) != 0.0 && (Py_errno == ERANGE || \ (X) == Py_HUGE_VAL || \ (X) == -Py_HUGE_VAL)) #endif diff --git a/Include/pyport.h b/Include/pyport.h --- a/Include/pyport.h +++ b/Include/pyport.h @@ -463,15 +463,15 @@ * X is evaluated more than once. */ #if defined(__FreeBSD__) || defined(__OpenBSD__) || (defined(__hpux) && defined(__ia64)) -#define _Py_SET_EDOM_FOR_NAN(X) if (isnan(X)) errno = EDOM; +#define _Py_SET_EDOM_FOR_NAN(X) if (isnan(X)) Py_errno = EDOM; #else #define _Py_SET_EDOM_FOR_NAN(X) ; #endif #define Py_SET_ERRNO_ON_MATH_ERROR(X) \ do { \ - if (errno == 0) { \ + if (Py_errno == 0) { \ if ((X) == Py_HUGE_VAL || (X) == -Py_HUGE_VAL) \ - errno = ERANGE; \ + Py_errno = ERANGE; \ else _Py_SET_EDOM_FOR_NAN(X) \ } \ } while(0) @@ -497,23 +497,23 @@ */ #define Py_ADJUST_ERANGE1(X) \ do { \ - if (errno == 0) { \ + if (Py_errno == 0) { \ if ((X) == Py_HUGE_VAL || (X) == -Py_HUGE_VAL) \ - errno = ERANGE; \ + Py_errno = ERANGE; \ } \ - else if (errno == ERANGE && (X) == 0.0) \ - errno = 0; \ + else if (Py_errno == ERANGE && (X) == 0.0) \ + Py_errno = 0; \ } while(0) #define Py_ADJUST_ERANGE2(X, Y) \ do { \ if ((X) == Py_HUGE_VAL || (X) == -Py_HUGE_VAL || \ (Y) == Py_HUGE_VAL || (Y) == -Py_HUGE_VAL) { \ - if (errno == 0) \ - errno = ERANGE; \ + if (Py_errno == 0) \ + Py_errno = ERANGE; \ } \ - else if (errno == ERANGE) \ - errno = 0; \ + else if (Py_errno == ERANGE) \ + Py_errno = 0; \ } while(0) /* The functions _Py_dg_strtod and _Py_dg_dtoa in Python/dtoa.c (which are @@ -868,4 +868,18 @@ #endif #endif +/* + * Access to errno variable of Python's C runtime library. When a Python + * extension is linked to another CRT (e.g. on Windows with different version + * of Visual Studio) it sees another errno as each CRT has its own thread + * local storage. + */ +PyAPI_FUNC(int *) _Py_errno(void); + +#ifdef Py_BUILD_CORE +# define Py_errno errno +#else +# define Py_errno (*_Py_errno()) +#endif + #endif /* Py_PYPORT_H */ diff --git a/Python/errors.c b/Python/errors.c --- a/Python/errors.c +++ b/Python/errors.c @@ -977,6 +977,13 @@ return NULL; } +/* access Python core's errno TLS variable */ +int * +_Py_errno() +{ + return &errno; +} + #ifdef __cplusplus } #endif