Skip to content

Commit 6518165

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 87041b5 commit 6518165

File tree

6 files changed

+38
-9
lines changed

6 files changed

+38
-9
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: 0 additions & 5 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: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2473,6 +2473,41 @@ _Py_set_blocking(int fd, int blocking)
24732473
return -1;
24742474
}
24752475
#else /* MS_WINDOWS */
2476+
int
2477+
_Py_get_blocking(int fd)
2478+
{
2479+
HANDLE handle;
2480+
DWORD mode;
2481+
2482+
handle = _Py_get_osfhandle(fd);
2483+
if (handle == INVALID_HANDLE_VALUE)
2484+
return -1;
2485+
2486+
if (!GetNamedPipeHandleState(handle, &mode, NULL, NULL, NULL, NULL, 0)) {
2487+
PyErr_SetFromWindowsErr(0);
2488+
return -1;
2489+
}
2490+
return mode == PIPE_WAIT;
2491+
}
2492+
2493+
int
2494+
_Py_set_blocking(int fd, int blocking)
2495+
{
2496+
HANDLE handle;
2497+
DWORD mode;
2498+
2499+
handle = _Py_get_osfhandle(fd);
2500+
if (handle == INVALID_HANDLE_VALUE)
2501+
return -1;
2502+
2503+
mode = blocking ? PIPE_WAIT : PIPE_NOWAIT;
2504+
if (!SetNamedPipeHandleState(handle, &mode, NULL, NULL)) {
2505+
PyErr_SetFromWindowsErr(0);
2506+
return -1;
2507+
}
2508+
return 0;
2509+
}
2510+
24762511
void*
24772512
_Py_get_osfhandle_noraise(int fd)
24782513
{

0 commit comments

Comments
 (0)