Skip to content

Commit f853e83

Browse files
committed
os: support blocking functions on Windows
Use the GetNamedPipeHandleState and SetNamedPipeHandleState Win32 API functions to add support for os.get_blocking and os.set_blocking.
1 parent 7d3b7d0 commit f853e83

File tree

6 files changed

+45
-21
lines changed

6 files changed

+45
-21
lines changed

Include/internal/pycore_fileutils.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -160,11 +160,10 @@ PyAPI_FUNC(int) _Py_set_inheritable_async_safe(int fd, int inheritable,
160160

161161
PyAPI_FUNC(int) _Py_dup(int fd);
162162

163-
#ifndef MS_WINDOWS
164163
PyAPI_FUNC(int) _Py_get_blocking(int fd);
165164

166165
PyAPI_FUNC(int) _Py_set_blocking(int fd, int blocking);
167-
#else /* MS_WINDOWS */
166+
#ifdef MS_WINDOWS
168167
PyAPI_FUNC(void*) _Py_get_osfhandle_noraise(int fd);
169168

170169
PyAPI_FUNC(void*) _Py_get_osfhandle(int fd);

Lib/test/test_os.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4099,6 +4099,7 @@ def test_path_t_converter_and_custom_class(self):
40994099
@unittest.skipUnless(hasattr(os, 'get_blocking'),
41004100
'needs os.get_blocking() and os.set_blocking()')
41014101
@unittest.skipIf(support.is_emscripten, "Cannot unset blocking flag")
4102+
@unittest.skipIf(sys.platform == 'win32', 'Windows only supports blocking on pipes')
41024103
class BlockingTests(unittest.TestCase):
41034104
def test_blocking(self):
41044105
fd = os.open(__file__, os.O_RDONLY)
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Add support for the os.get_blocking() and os.set_blocking() functions on Windows.

Modules/clinic/posixmodule.c.h

Lines changed: 1 addition & 17 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Modules/posixmodule.c

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13930,7 +13930,6 @@ os_set_handle_inheritable_impl(PyObject *module, intptr_t handle,
1393013930
}
1393113931
#endif /* MS_WINDOWS */
1393213932

13933-
#ifndef MS_WINDOWS
1393413933
/*[clinic input]
1393513934
os.get_blocking -> bool
1393613935
fd: int
@@ -13978,7 +13977,6 @@ os_set_blocking_impl(PyObject *module, int fd, int blocking)
1397813977
return NULL;
1397913978
Py_RETURN_NONE;
1398013979
}
13981-
#endif /* !MS_WINDOWS */
1398213980

1398313981

1398413982
/*[clinic input]

Python/fileutils.c

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2470,6 +2470,47 @@ _Py_set_blocking(int fd, int blocking)
24702470
return -1;
24712471
}
24722472
#else /* MS_WINDOWS */
2473+
int
2474+
_Py_get_blocking(int fd)
2475+
{
2476+
HANDLE handle;
2477+
DWORD mode;
2478+
2479+
handle = _Py_get_osfhandle(fd);
2480+
if (handle == INVALID_HANDLE_VALUE) {
2481+
return -1;
2482+
}
2483+
2484+
if (!GetNamedPipeHandleStateW(handle, &mode, NULL, NULL, NULL, NULL, 0)) {
2485+
PyErr_SetFromWindowsErr(0);
2486+
return -1;
2487+
}
2488+
return mode & PIPE_WAIT;
2489+
}
2490+
2491+
int
2492+
_Py_set_blocking(int fd, int blocking)
2493+
{
2494+
HANDLE handle;
2495+
DWORD mode;
2496+
2497+
handle = _Py_get_osfhandle(fd);
2498+
if (handle == INVALID_HANDLE_VALUE) {
2499+
return -1;
2500+
}
2501+
2502+
if (!GetNamedPipeHandleStateW(handle, &mode, NULL, NULL, NULL, NULL, 0)) {
2503+
PyErr_SetFromWindowsErr(0);
2504+
return -1;
2505+
}
2506+
mode |= blocking ? PIPE_WAIT : PIPE_NOWAIT;
2507+
if (!SetNamedPipeHandleState(handle, &mode, NULL, NULL)) {
2508+
PyErr_SetFromWindowsErr(0);
2509+
return -1;
2510+
}
2511+
return 0;
2512+
}
2513+
24732514
void*
24742515
_Py_get_osfhandle_noraise(int fd)
24752516
{

0 commit comments

Comments
 (0)