diff --git a/extmod/moduos.c b/extmod/moduos.c index 87a611148d1cf..4d6a45b7f8ee1 100644 --- a/extmod/moduos.c +++ b/extmod/moduos.c @@ -48,6 +48,10 @@ #include "genhdr/mpversion.h" #endif +#if MICROPY_PY_USELECT || MICROPY_PY_USELECT_POSIX +#include "py/stream.h" +#endif + #ifdef MICROPY_PY_UOS_INCLUDEFILE #include MICROPY_PY_UOS_INCLUDEFILE #endif @@ -102,6 +106,21 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_0(mp_uos_uname_obj, mp_uos_uname); #endif +#if MICROPY_PY_USELECT || MICROPY_PY_USELECT_POSIX +STATIC mp_obj_t select_ioctl(mp_obj_t stream, mp_obj_t reg, mp_obj_t arg) { + const mp_stream_p_t *stream_p = mp_get_stream_raise(stream, MP_STREAM_OP_IOCTL); + int errcode = 0; + mp_int_t ret = stream_p->ioctl(stream, mp_obj_int_get_uint_checked(reg), (uintptr_t)mp_obj_int_get_uint_checked(arg), &errcode); + if (ret == -1) { + // error doing ioctl + mp_raise_OSError(errcode); + } + + return mp_obj_new_int(ret); +} +STATIC MP_DEFINE_CONST_FUN_OBJ_3(mp_select_ioctl_obj, select_ioctl); +#endif + STATIC const mp_rom_map_elem_t os_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_uos) }, @@ -168,6 +187,27 @@ STATIC const mp_rom_map_elem_t os_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR_VfsPosix), MP_ROM_PTR(&mp_type_vfs_posix) }, #endif #endif + + #if MICROPY_PY_USELECT || MICROPY_PY_USELECT_POSIX + { MP_ROM_QSTR(MP_QSTR_ioctl), MP_ROM_PTR(&mp_select_ioctl_obj) }, + + { MP_ROM_QSTR(MP_QSTR_STREAM_FLUSH), MP_ROM_INT(MP_STREAM_FLUSH) }, + { MP_ROM_QSTR(MP_QSTR_STREAM_SEEK), MP_ROM_INT(MP_STREAM_SEEK) }, + { MP_ROM_QSTR(MP_QSTR_STREAM_POLL), MP_ROM_INT(MP_STREAM_POLL) }, + { MP_ROM_QSTR(MP_QSTR_STREAM_CLOSE), MP_ROM_INT(MP_STREAM_CLOSE) }, + { MP_ROM_QSTR(MP_QSTR_STREAM_TIMEOUT), MP_ROM_INT(MP_STREAM_TIMEOUT) }, + { MP_ROM_QSTR(MP_QSTR_STREAM_GET_OPTS), MP_ROM_INT(MP_STREAM_GET_OPTS) }, + { MP_ROM_QSTR(MP_QSTR_STREAM_SET_OPTS), MP_ROM_INT(MP_STREAM_SET_OPTS) }, + { MP_ROM_QSTR(MP_QSTR_STREAM_GET_DATA_OPTS), MP_ROM_INT(MP_STREAM_GET_DATA_OPTS) }, + { MP_ROM_QSTR(MP_QSTR_STREAM_SET_DATA_OPTS), MP_ROM_INT(MP_STREAM_SET_DATA_OPTS) }, + { MP_ROM_QSTR(MP_QSTR_STREAM_GET_FILENO), MP_ROM_INT(MP_STREAM_GET_FILENO) }, + + { MP_ROM_QSTR(MP_QSTR_STREAM_POLL_RD), MP_ROM_INT(MP_STREAM_POLL_RD) }, + { MP_ROM_QSTR(MP_QSTR_STREAM_POLL_WR), MP_ROM_INT(MP_STREAM_POLL_WR) }, + { MP_ROM_QSTR(MP_QSTR_STREAM_POLL_ERR), MP_ROM_INT(MP_STREAM_POLL_ERR) }, + { MP_ROM_QSTR(MP_QSTR_STREAM_POLL_HUP), MP_ROM_INT(MP_STREAM_POLL_HUP) }, + { MP_ROM_QSTR(MP_QSTR_STREAM_POLL_NVAL), MP_ROM_INT(MP_STREAM_POLL_NVAL) }, + #endif }; STATIC MP_DEFINE_CONST_DICT(os_module_globals, os_module_globals_table); diff --git a/tests/extmod/uos_ioctl.py b/tests/extmod/uos_ioctl.py new file mode 100644 index 0000000000000..4e70b17e33db2 --- /dev/null +++ b/tests/extmod/uos_ioctl.py @@ -0,0 +1,37 @@ +import uos +import uio + +class TestIO(uio.IOBase): + def __init__(self): + self._read_rdy = False + self._write_rdy = False + + def ioctl(self, req, arg): + if req == uos.STREAM_POLL: + ret = 0 + if arg & uos.STREAM_POLL_RD and self._read_rdy: + ret |= uos.STREAM_POLL_RD + if arg & uos.STREAM_POLL_WR and self._write_rdy: + ret |= uos.STREAM_POLL_WR + return ret + + raise Exception("Foo") + + +f = TestIO() + +def _assert_ioctl_poll(expected): + assert f.ioctl(uos.STREAM_POLL, uos.STREAM_POLL_RD | uos.STREAM_POLL_WR) == expected + +_assert_ioctl_poll(0) +f._read_rdy = True +_assert_ioctl_poll(uos.STREAM_POLL_RD) +f._write_rdy = True +_assert_ioctl_poll(uos.STREAM_POLL_RD | uos.STREAM_POLL_WR) + +try: + uos.ioctl(f, 666, 0) +except Exception as exc: + assert repr(exc) == "Exception('Foo',)" +else: + assert False diff --git a/tests/extmod/uos_ioctl.py.exp b/tests/extmod/uos_ioctl.py.exp new file mode 100644 index 0000000000000..e69de29bb2d1d
Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.
Alternative Proxies: