# HG changeset patch # User Steve Dower # Date 1424930096 28800 # Wed Feb 25 21:54:56 2015 -0800 # Node ID f2e50dc5b4ae99dec19ad99735d32ecba0440a3f # Parent 8545624309f5e1f5b18f8107acb051794c5f61f4 Issue #23524: Replace _PyVerify_fd function with calls to _set_thread_local_invalid_parameter_handler. diff --git a/Modules/posixmodule.c b/Modules/posixmodule.c --- a/Modules/posixmodule.c +++ b/Modules/posixmodule.c @@ -1051,7 +1051,42 @@ } -#if defined _MSC_VER && _MSC_VER >= 1400 +#if defined _MSC_VER + +#if _MSC_VER >= 1900 + +static void __cdecl _silent_invalid_parameter_handler( + wchar_t const* expression, + wchar_t const* function, + wchar_t const* file, + unsigned int line, + uintptr_t pReserved) { } + +#define _Py_BEGIN_SUPPRESS_IPH { _invalid_parameter_handler old_handler = \ + _set_thread_local_invalid_parameter_handler(_silent_invalid_parameter_handler); +#define _Py_END_SUPPRESS_IPH _set_thread_local_invalid_parameter_handler(old_handler); } +#define _Py_VERIFY_FD(fd) 1 +#define _Py_VERIFY_FD_DUP2(fd1, fd2) 1 + +/* This function lets the Windows CRT validate the file handle without + terminating the process if it's invalid. */ +int +_PyVerify_fd(int fd) +{ + intptr_t osh; + /* Fast check for the only condition we know */ + if (fd < 0) { + _set_errno(EBADF); + return 0; + } + _Py_BEGIN_SUPPRESS_IPH + osh = _get_osfhandle(fd); + _Py_END_SUPPRESS_IPH + return osh != (intptr_t)-1; +} + +#elif _MSC_VER >= 1400 + /* Microsoft CRT in VS2005 and higher will verify that a filehandle is * valid and raise an assertion if it isn't. * Normally, an invalid fd is likely to be a C program error and therefore @@ -1075,32 +1110,14 @@ /* The actual size of the structure is determined at runtime. * Only the first items must be present. */ - -#if _MSC_VER >= 1900 - -typedef struct { - CRITICAL_SECTION lock; - intptr_t osfhnd; - __int64 startpos; - char osfile; -} my_ioinfo; - -#define IOINFO_L2E 6 -#define IOINFO_ARRAYS 128 - -#else - typedef struct { intptr_t osfhnd; char osfile; } my_ioinfo; +extern __declspec(dllimport) char * __pioinfo[]; #define IOINFO_L2E 5 #define IOINFO_ARRAYS 64 - -#endif - -extern __declspec(dllimport) char * __pioinfo[]; #define IOINFO_ARRAY_ELTS (1 << IOINFO_L2E) #define _NHANDLE_ (IOINFO_ARRAYS * IOINFO_ARRAY_ELTS) #define FOPEN 0x01 @@ -1157,10 +1174,41 @@ else return 0; } -#else -/* dummy version. _PyVerify_fd() is already defined in fileobject.h */ -#define _PyVerify_fd_dup2(A, B) (1) -#endif + +#define _Py_BEGIN_SUPPRESS_IPH +#define _Py_END_SUPPRESS_IPH +#define _Py_VERIFY_FD(fd) (_PyVerify_fd(fd)) +#define _Py_VERIFY_FD_DUP2(fd1, fd2) (_PyVerify_fd_dup2(fd1, fd2)) + +#else + +/* This function lets the Windows CRT validate the file handle */ +int +_PyVerify_fd(int fd) +{ + /* Fast check for the only condition we know */ + if (fd < 0) { + _set_errno(EBADF); + return 0; + } + return _get_osfhandle(fd) != (intptr_t)-1; +} + +#define _Py_BEGIN_SUPPRESS_IPH +#define _Py_END_SUPPRESS_IPH +#define _Py_VERIFY_FD(fd) (_PyVerify_fd(fd)) +#define _Py_VERIFY_FD_DUP2(fd1, fd2) (_PyVerify_fd(fd1) && fd2 >= 0) + +#endif /* _MSC_VER >= 1900 // _MSC_VER >= 1400 */ + +#else + +#define _Py_BEGIN_SUPPRESS_IPH +#define _Py_END_SUPPRESS_IPH +#define _Py_VERIFY_FD(fd) 1 +#define _Py_VERIFY_FD_DUP2(fd1, fd2) 1 + +#endif /* defined _MSC_VER */ #ifdef MS_WINDOWS @@ -1371,7 +1419,9 @@ do { Py_BEGIN_ALLOW_THREADS + _Py_BEGIN_SUPPRESS_IPH res = (*func)(fd); + _Py_END_SUPPRESS_IPH Py_END_ALLOW_THREADS } while (res != 0 && errno == EINTR && !(async_err = PyErr_CheckSignals())); if (res != 0) @@ -5751,6 +5801,7 @@ int result; Py_BEGIN_ALLOW_THREADS + _Py_BEGIN_SUPPRESS_IPH #ifdef MS_WINDOWS if (path->wide) result = Py_DeleteFileW(path->wide); @@ -5765,6 +5816,7 @@ #endif /* HAVE_UNLINKAT */ result = unlink(path->narrow); #endif + _Py_END_SUPPRESS_IPH Py_END_ALLOW_THREADS if (result) @@ -10834,14 +10886,16 @@ /*[clinic end generated code: output=927004e29ad55808 input=2bc42451ca5c3223]*/ { int res; - if (!_PyVerify_fd(fd)) + if (!_Py_VERIFY_FD(fd)) return posix_error(); /* We do not want to retry upon EINTR: see http://lwn.net/Articles/576478/ * and http://linux.derkeiler.com/Mailing-Lists/Kernel/2005-09/3000.html * for more details. */ Py_BEGIN_ALLOW_THREADS + _Py_BEGIN_SUPPRESS_IPH res = close(fd); + _Py_END_SUPPRESS_IPH Py_END_ALLOW_THREADS if (res < 0) return posix_error(); @@ -10894,9 +10948,11 @@ { int i; Py_BEGIN_ALLOW_THREADS + _Py_BEGIN_SUPPRESS_IPH for (i = fd_low; i < fd_high; i++) - if (_PyVerify_fd(i)) + if (_Py_VERIFY_FD(i)) close(i); + _Py_END_SUPPRESS_IPH Py_END_ALLOW_THREADS Py_RETURN_NONE; } @@ -11002,7 +11058,7 @@ int dup3_works = -1; #endif - if (!_PyVerify_fd_dup2(fd, fd2)) + if (!_Py_VERIFY_FD_DUP2(fd, fd2)) return posix_error(); /* dup2() can fail with EINTR if the target FD is already open, because it @@ -11011,7 +11067,9 @@ */ #ifdef MS_WINDOWS Py_BEGIN_ALLOW_THREADS + _Py_BEGIN_SUPPRESS_IPH res = dup2(fd, fd2); + _Py_END_SUPPRESS_IPH Py_END_ALLOW_THREADS if (res < 0) return posix_error(); @@ -11198,7 +11256,7 @@ { Py_off_t result; - if (!_PyVerify_fd(fd)) { + if (!_Py_VERIFY_FD(fd)) { posix_error(); return -1; } @@ -11214,16 +11272,18 @@ if (PyErr_Occurred()) return -1; - if (!_PyVerify_fd(fd)) { + if (!_Py_VERIFY_FD(fd)) { posix_error(); return -1; } Py_BEGIN_ALLOW_THREADS + _Py_BEGIN_SUPPRESS_IPH #ifdef MS_WINDOWS result = _lseeki64(fd, position, how); #else result = lseek(fd, position, how); #endif + _Py_END_SUPPRESS_IPH Py_END_ALLOW_THREADS if (result < 0) posix_error(); @@ -11282,7 +11342,7 @@ errno = EINVAL; return posix_error(); } - if (!_PyVerify_fd(fd)) + if (!_Py_VERIFY_FD(fd)) return posix_error(); #ifdef MS_WINDOWS @@ -11299,7 +11359,9 @@ do { Py_BEGIN_ALLOW_THREADS + _Py_BEGIN_SUPPRESS_IPH n = read(fd, PyBytes_AS_STRING(buffer), READ_CAST length); + _Py_END_SUPPRESS_IPH Py_END_ALLOW_THREADS } while (n < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals())); @@ -11536,14 +11598,16 @@ buffer = PyBytes_FromStringAndSize((char *)NULL, length); if (buffer == NULL) return NULL; - if (!_PyVerify_fd(fd)) { + if (!_Py_VERIFY_FD(fd)) { Py_DECREF(buffer); return posix_error(); } do { Py_BEGIN_ALLOW_THREADS + _Py_BEGIN_SUPPRESS_IPH n = pread(fd, PyBytes_AS_STRING(buffer), length, offset); + _Py_END_SUPPRESS_IPH Py_END_ALLOW_THREADS } while (n < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals())); @@ -11612,14 +11676,14 @@ Py_ssize_t size; int async_err = 0; Py_ssize_t len = data->len; - - if (!_PyVerify_fd(fd)) { + if (!_Py_VERIFY_FD(fd)) { posix_error(); return -1; } do { Py_BEGIN_ALLOW_THREADS + _Py_BEGIN_SUPPRESS_IPH #ifdef MS_WINDOWS if (len > INT_MAX) len = INT_MAX; @@ -11627,6 +11691,7 @@ #else size = write(fd, data->buf, len); #endif + _Py_END_SUPPRESS_IPH Py_END_ALLOW_THREADS } while (size < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals())); @@ -11906,9 +11971,13 @@ os_isatty_impl(PyModuleDef *module, int fd) /*[clinic end generated code: output=4bfadbfe22715097 input=08ce94aa1eaf7b5e]*/ { - if (!_PyVerify_fd(fd)) + int return_value; + if (!_Py_VERIFY_FD(fd)) return 0; - return isatty(fd); + _Py_BEGIN_SUPPRESS_IPH + return_value = isatty(fd); + _Py_END_SUPPRESS_IPH + return return_value; } @@ -12229,14 +12298,16 @@ Py_ssize_t size; int async_err = 0; - if (!_PyVerify_fd(fd)) { + if (!_Py_VERIFY_FD(fd)) { posix_error(); return -1; } do { Py_BEGIN_ALLOW_THREADS + _Py_BEGIN_SUPPRESS_IPH size = pwrite(fd, buffer->buf, (size_t)buffer->len, offset); + _Py_END_SUPPRESS_IPH Py_END_ALLOW_THREADS } while (size < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals())); @@ -16197,12 +16268,16 @@ os_get_inheritable_impl(PyModuleDef *module, int fd) /*[clinic end generated code: output=261d1dd2b0dbdc35 input=89ac008dc9ab6b95]*/ { - if (!_PyVerify_fd(fd)){ + int return_value; + if (!_Py_VERIFY_FD(fd)) { posix_error(); return -1; } - return _Py_get_inheritable(fd); + _Py_BEGIN_SUPPRESS_IPH + return_value = _Py_get_inheritable(fd); + _Py_END_SUPPRESS_IPH + return return_value; } @@ -16248,10 +16323,14 @@ os_set_inheritable_impl(PyModuleDef *module, int fd, int inheritable) /*[clinic end generated code: output=64dfe5e15c906539 input=9ceaead87a1e2402]*/ { - if (!_PyVerify_fd(fd)) - return posix_error(); - - if (_Py_set_inheritable(fd, inheritable, NULL) < 0) + int result; + if (!_Py_VERIFY_FD(fd)) + return posix_error(); + + _Py_BEGIN_SUPPRESS_IPH + result = _Py_set_inheritable(fd, inheritable, NULL); + _Py_END_SUPPRESS_IPH + if (result < 0) return NULL; Py_RETURN_NONE; } @@ -16380,10 +16459,12 @@ if (!PyArg_ParseTuple(args, "i:get_blocking", &fd)) return NULL; - if (!_PyVerify_fd(fd)) - return posix_error(); - + if (!_Py_VERIFY_FD(fd)) + return posix_error(); + + _Py_BEGIN_SUPPRESS_IPH blocking = _Py_get_blocking(fd); + _Py_END_SUPPRESS_IPH if (blocking < 0) return NULL; return PyBool_FromLong(blocking); @@ -16399,15 +16480,18 @@ static PyObject* posix_set_blocking(PyObject *self, PyObject *args) { - int fd, blocking; + int fd, blocking, result; if (!PyArg_ParseTuple(args, "ii:set_blocking", &fd, &blocking)) return NULL; - if (!_PyVerify_fd(fd)) - return posix_error(); - - if (_Py_set_blocking(fd, blocking) < 0) + if (!_Py_VERIFY_FD(fd)) + return posix_error(); + + _Py_BEGIN_SUPPRESS_IPH + result = _Py_set_blocking(fd, blocking); + _Py_END_SUPPRESS_IPH + if (result < 0) return NULL; Py_RETURN_NONE; }