diff options
author | nierob <nierob@users.noreply.github.com> | 2018-11-23 15:46:12 (GMT) |
---|---|---|
committer | Victor Stinner <vstinner@redhat.com> | 2018-11-23 15:46:12 (GMT) |
commit | b409ffa848b280c1db1b4f450bfae14f263099ac (patch) | |
tree | 0c240c1514a28c75ad2300852712cfdc31faaf15 /Modules | |
parent | f653fd4d950ac092719b6152e38d77c62b443125 (diff) | |
download | cpython-b409ffa848b280c1db1b4f450bfae14f263099ac.zip cpython-b409ffa848b280c1db1b4f450bfae14f263099ac.tar.gz cpython-b409ffa848b280c1db1b4f450bfae14f263099ac.tar.bz2 |
bpo-35189: Retry fnctl calls on EINTR (GH-10413)
Modify the following fnctl function to retry if interrupted by a signal
(EINTR): flock, lockf, fnctl.
Diffstat (limited to 'Modules')
-rw-r--r-- | Modules/fcntlmodule.c | 55 |
1 files changed, 32 insertions, 23 deletions
diff --git a/Modules/fcntlmodule.c b/Modules/fcntlmodule.c index 77ddebf..a938d9e 100644 --- a/Modules/fcntlmodule.c +++ b/Modules/fcntlmodule.c @@ -64,6 +64,7 @@ fcntl_fcntl_impl(PyObject *module, int fd, int code, PyObject *arg) char *str; Py_ssize_t len; char buf[1024]; + int async_err = 0; if (arg != NULL) { int parse_result; @@ -75,12 +76,13 @@ fcntl_fcntl_impl(PyObject *module, int fd, int code, PyObject *arg) return NULL; } memcpy(buf, str, len); - Py_BEGIN_ALLOW_THREADS - ret = fcntl(fd, code, buf); - Py_END_ALLOW_THREADS + do { + Py_BEGIN_ALLOW_THREADS + ret = fcntl(fd, code, buf); + Py_END_ALLOW_THREADS + } while (ret == -1 && errno == EINTR && !(async_err = PyErr_CheckSignals())); if (ret < 0) { - PyErr_SetFromErrno(PyExc_OSError); - return NULL; + return !async_err ? PyErr_SetFromErrno(PyExc_OSError) : NULL; } return PyBytes_FromStringAndSize(buf, len); } @@ -95,12 +97,13 @@ fcntl_fcntl_impl(PyObject *module, int fd, int code, PyObject *arg) } } - Py_BEGIN_ALLOW_THREADS - ret = fcntl(fd, code, (int)int_arg); - Py_END_ALLOW_THREADS + do { + Py_BEGIN_ALLOW_THREADS + ret = fcntl(fd, code, (int)int_arg); + Py_END_ALLOW_THREADS + } while (ret == -1 && errno == EINTR && !(async_err = PyErr_CheckSignals())); if (ret < 0) { - PyErr_SetFromErrno(PyExc_OSError); - return NULL; + return !async_err ? PyErr_SetFromErrno(PyExc_OSError) : NULL; } return PyLong_FromLong((long)ret); } @@ -283,11 +286,14 @@ fcntl_flock_impl(PyObject *module, int fd, int code) /*[clinic end generated code: output=84059e2b37d2fc64 input=b70a0a41ca22a8a0]*/ { int ret; + int async_err = 0; #ifdef HAVE_FLOCK - Py_BEGIN_ALLOW_THREADS - ret = flock(fd, code); - Py_END_ALLOW_THREADS + do { + Py_BEGIN_ALLOW_THREADS + ret = flock(fd, code); + Py_END_ALLOW_THREADS + } while (ret == -1 && errno == EINTR && !(async_err = PyErr_CheckSignals())); #else #ifndef LOCK_SH @@ -310,14 +316,15 @@ fcntl_flock_impl(PyObject *module, int fd, int code) return NULL; } l.l_whence = l.l_start = l.l_len = 0; - Py_BEGIN_ALLOW_THREADS - ret = fcntl(fd, (code & LOCK_NB) ? F_SETLK : F_SETLKW, &l); - Py_END_ALLOW_THREADS + do { + Py_BEGIN_ALLOW_THREADS + ret = fcntl(fd, (code & LOCK_NB) ? F_SETLK : F_SETLKW, &l); + Py_END_ALLOW_THREADS + } while (ret == -1 && errno == EINTR && !(async_err = PyErr_CheckSignals())); } #endif /* HAVE_FLOCK */ if (ret < 0) { - PyErr_SetFromErrno(PyExc_OSError); - return NULL; + return !async_err ? PyErr_SetFromErrno(PyExc_OSError) : NULL; } Py_RETURN_NONE; } @@ -363,6 +370,7 @@ fcntl_lockf_impl(PyObject *module, int fd, int code, PyObject *lenobj, /*[clinic end generated code: output=4985e7a172e7461a input=3a5dc01b04371f1a]*/ { int ret; + int async_err = 0; #ifndef LOCK_SH #define LOCK_SH 1 /* shared lock */ @@ -407,13 +415,14 @@ fcntl_lockf_impl(PyObject *module, int fd, int code, PyObject *lenobj, return NULL; } l.l_whence = whence; - Py_BEGIN_ALLOW_THREADS - ret = fcntl(fd, (code & LOCK_NB) ? F_SETLK : F_SETLKW, &l); - Py_END_ALLOW_THREADS + do { + Py_BEGIN_ALLOW_THREADS + ret = fcntl(fd, (code & LOCK_NB) ? F_SETLK : F_SETLKW, &l); + Py_END_ALLOW_THREADS + } while (ret == -1 && errno == EINTR && !(async_err = PyErr_CheckSignals())); } if (ret < 0) { - PyErr_SetFromErrno(PyExc_OSError); - return NULL; + return !async_err ? PyErr_SetFromErrno(PyExc_OSError) : NULL; } Py_RETURN_NONE; } |