Skip to content

Commit 182042b

Browse files
committed
fileutils: handle Windows errors in non-blocking mode
Handle erroring operations on non-blocking pipes by reading the _doserrno code.
1 parent 81e3aa8 commit 182042b

File tree

1 file changed

+23
-0
lines changed

1 file changed

+23
-0
lines changed

Python/fileutils.c

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1750,7 +1750,16 @@ _Py_read(int fd, void *buf, size_t count)
17501750
Py_BEGIN_ALLOW_THREADS
17511751
errno = 0;
17521752
#ifdef MS_WINDOWS
1753+
_doserrno = 0;
17531754
n = read(fd, buf, (int)count);
1755+
int winerr = _doserrno;
1756+
if (n < 0 && errno == EINVAL) {
1757+
if (winerr == ERROR_NO_DATA) {
1758+
/* read() on a non-blocking empty pipe
1759+
returns EINVAL on Windows */
1760+
errno = EAGAIN;
1761+
}
1762+
}
17541763
#else
17551764
n = read(fd, buf, count);
17561765
#endif
@@ -1814,7 +1823,14 @@ _Py_write_impl(int fd, const void *buf, size_t count, int gil_held)
18141823
Py_BEGIN_ALLOW_THREADS
18151824
errno = 0;
18161825
#ifdef MS_WINDOWS
1826+
_doserrno = 0;
18171827
n = write(fd, buf, (int)count);
1828+
int winerr = _doserrno;
1829+
if (n < 0 && errno == ENOSPC) {
1830+
/* write() on a non-blocking full pipe
1831+
returns ENOSPC on Windows */
1832+
errno = EAGAIN;
1833+
}
18181834
#else
18191835
n = write(fd, buf, count);
18201836
#endif
@@ -1829,7 +1845,14 @@ _Py_write_impl(int fd, const void *buf, size_t count, int gil_held)
18291845
do {
18301846
errno = 0;
18311847
#ifdef MS_WINDOWS
1848+
_doserrno = 0;
18321849
n = write(fd, buf, (int)count);
1850+
int winerr = _doserrno;
1851+
if (n < 0 && errno == ENOSPC) {
1852+
/* write() on a non-blocking full pipe
1853+
returns ENOSPC on Windows */
1854+
errno = EAGAIN;
1855+
}
18331856
#else
18341857
n = write(fd, buf, count);
18351858
#endif

0 commit comments

Comments
 (0)