diff -r cfe541c694f3 Python/fileutils.c --- a/Python/fileutils.c Wed Mar 18 01:39:23 2015 +0100 +++ b/Python/fileutils.c Wed Mar 18 01:48:50 2015 +0100 @@ -912,6 +912,7 @@ static int _Py_open_impl(const char *pathname, int flags, int gil_held) { int fd; + int async_err = 0; #ifndef MS_WINDOWS int *atomic_flag_works; #endif @@ -926,10 +927,14 @@ static int #endif if (gil_held) { - Py_BEGIN_ALLOW_THREADS - fd = open(pathname, flags); - Py_END_ALLOW_THREADS - + do { + Py_BEGIN_ALLOW_THREADS + fd = open(pathname, flags); + Py_END_ALLOW_THREADS + } while (fd < 0 + && errno == EINTR && !(async_err = PyErr_CheckSignals())); + if (async_err) + return -1; if (fd < 0) { PyErr_SetFromErrnoWithFilename(PyExc_OSError, pathname); return -1; @@ -957,6 +962,9 @@ static int The file descriptor is created non-inheritable. + When interrupted by a signal (open() fails with EINTR), retry the syscall, + except if the Python signal handler raises an exception. + The GIL must be held. */ int _Py_open(const char *pathname, int flags) @@ -969,7 +977,9 @@ int /* Open a file with the specified flags (wrapper to open() function). Return a file descriptor on success. Set errno and return -1 on error. - The file descriptor is created non-inheritable. */ + The file descriptor is created non-inheritable. + + Don't retry if interrupted by a signal (fail with EINTR). */ int _Py_open_noraise(const char *pathname, int flags) { @@ -979,7 +989,9 @@ int /* Open a file. Use _wfopen() on Windows, encode the path to the locale encoding and use fopen() otherwise. - The file descriptor is created non-inheritable). */ + The file descriptor is created non-inheritable. + + Don't retry if interrupted by a signal (fail with EINTR). */ FILE * _Py_wfopen(const wchar_t *path, const wchar_t *mode) { @@ -1012,7 +1024,9 @@ FILE * /* Wrapper to fopen(). - The file descriptor is created non-inheritable). */ + The file descriptor is created non-inheritable. + + Don't retry if interrupted by a signal (fail with EINTR). */ FILE* _Py_fopen(const char *pathname, const char *mode) { @@ -1039,6 +1053,7 @@ FILE* _Py_fopen_obj(PyObject *path, const char *mode) { FILE *f; + int async_err = 0; #ifdef MS_WINDOWS wchar_t *wpath; wchar_t wmode[10]; @@ -1062,9 +1077,12 @@ FILE* return NULL; } - Py_BEGIN_ALLOW_THREADS - f = _wfopen(wpath, wmode); - Py_END_ALLOW_THREADS + do { + Py_BEGIN_ALLOW_THREADS + f = _wfopen(wpath, wmode); + Py_END_ALLOW_THREADS + } while (f == NULL + && errno == EINTR && !(async_err = PyErr_CheckSignals())); #else PyObject *bytes; char *path_bytes; @@ -1075,12 +1093,18 @@ FILE* return NULL; path_bytes = PyBytes_AS_STRING(bytes); - Py_BEGIN_ALLOW_THREADS - f = fopen(path_bytes, mode); - Py_END_ALLOW_THREADS + do { + Py_BEGIN_ALLOW_THREADS + f = fopen(path_bytes, mode); + Py_END_ALLOW_THREADS + } while (f == NULL + && errno == EINTR && !(async_err = PyErr_CheckSignals())); Py_DECREF(bytes); #endif + if (async_err) + return NULL; + if (f == NULL) { PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError, path); return NULL; @@ -1219,14 +1243,13 @@ int #ifdef MS_WINDOWS HANDLE handle; DWORD ftype; -#endif if (!_PyVerify_fd(fd)) { PyErr_SetFromErrno(PyExc_OSError); return -1; } -#ifdef MS_WINDOWS + handle = (HANDLE)_get_osfhandle(fd); if (handle == INVALID_HANDLE_VALUE) { PyErr_SetFromErrno(PyExc_OSError); @@ -1261,9 +1284,15 @@ int } #else - Py_BEGIN_ALLOW_THREADS - fd = dup(fd); - Py_END_ALLOW_THREADS + int async_err = 0; + + do { + Py_BEGIN_ALLOW_THREADS + fd = dup(fd); + Py_END_ALLOW_THREADS + } while (fd < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals())); + if (async_err) + return -1; if (fd < 0) { PyErr_SetFromErrno(PyExc_OSError); return -1;