diff options
author | Masaru Tsuchiyama <m.tmatma@gmail.com> | 2023-10-07 17:33:22 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-10-07 17:33:22 (GMT) |
commit | de2a4036cbfd5e41a5bdd2b81122b7765729af83 (patch) | |
tree | 44b739676b2707fddf3404882ae4b0e870cf0ce0 /Modules | |
parent | 64f158e7b09e67d0bf5c8603ff88c86ed4e8f8fd (diff) | |
download | cpython-de2a4036cbfd5e41a5bdd2b81122b7765729af83.zip cpython-de2a4036cbfd5e41a5bdd2b81122b7765729af83.tar.gz cpython-de2a4036cbfd5e41a5bdd2b81122b7765729af83.tar.bz2 |
gh-108277: Add os.timerfd_create() function (#108382)
Add wrapper for timerfd_create, timerfd_settime, and timerfd_gettime to os module.
Co-authored-by: Serhiy Storchaka <storchaka@gmail.com>
Co-authored-by: Adam Turner <9087854+AA-Turner@users.noreply.github.com>
Co-authored-by: Erlend E. Aasland <erlend.aasland@protonmail.com>
Co-authored-by: Victor Stinner <vstinner@python.org>
Diffstat (limited to 'Modules')
-rw-r--r-- | Modules/clinic/posixmodule.c.h | 392 | ||||
-rw-r--r-- | Modules/posixmodule.c | 248 |
2 files changed, 639 insertions, 1 deletions
diff --git a/Modules/clinic/posixmodule.c.h b/Modules/clinic/posixmodule.c.h index 0238d3a..1791327 100644 --- a/Modules/clinic/posixmodule.c.h +++ b/Modules/clinic/posixmodule.c.h @@ -6022,6 +6022,376 @@ os_times(PyObject *module, PyObject *Py_UNUSED(ignored)) #endif /* defined(HAVE_TIMES) */ +#if defined(HAVE_TIMERFD_CREATE) + +PyDoc_STRVAR(os_timerfd_create__doc__, +"timerfd_create($module, clockid, /, *, flags=0)\n" +"--\n" +"\n" +"Create and return a timer file descriptor.\n" +"\n" +" clockid\n" +" A valid clock ID constant as timer file descriptor.\n" +"\n" +" time.CLOCK_REALTIME\n" +" time.CLOCK_MONOTONIC\n" +" time.CLOCK_BOOTTIME\n" +" flags\n" +" 0 or a bit mask of os.TFD_NONBLOCK or os.TFD_CLOEXEC.\n" +"\n" +" os.TFD_NONBLOCK\n" +" If *TFD_NONBLOCK* is set as a flag, read doesn\'t blocks.\n" +" If *TFD_NONBLOCK* is not set as a flag, read block until the timer fires.\n" +"\n" +" os.TFD_CLOEXEC\n" +" If *TFD_CLOEXEC* is set as a flag, enable the close-on-exec flag"); + +#define OS_TIMERFD_CREATE_METHODDEF \ + {"timerfd_create", _PyCFunction_CAST(os_timerfd_create), METH_FASTCALL|METH_KEYWORDS, os_timerfd_create__doc__}, + +static PyObject * +os_timerfd_create_impl(PyObject *module, int clockid, int flags); + +static PyObject * +os_timerfd_create(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(flags), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + + static const char * const _keywords[] = {"", "flags", NULL}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "timerfd_create", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + PyObject *argsbuf[2]; + Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; + int clockid; + int flags = 0; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, argsbuf); + if (!args) { + goto exit; + } + clockid = PyLong_AsInt(args[0]); + if (clockid == -1 && PyErr_Occurred()) { + goto exit; + } + if (!noptargs) { + goto skip_optional_kwonly; + } + flags = PyLong_AsInt(args[1]); + if (flags == -1 && PyErr_Occurred()) { + goto exit; + } +skip_optional_kwonly: + return_value = os_timerfd_create_impl(module, clockid, flags); + +exit: + return return_value; +} + +#endif /* defined(HAVE_TIMERFD_CREATE) */ + +#if defined(HAVE_TIMERFD_CREATE) + +PyDoc_STRVAR(os_timerfd_settime__doc__, +"timerfd_settime($module, fd, /, *, flags=0, initial=0.0, interval=0.0)\n" +"--\n" +"\n" +"Alter a timer file descriptor\'s internal timer in seconds.\n" +"\n" +" fd\n" +" A timer file descriptor.\n" +" flags\n" +" 0 or a bit mask of TFD_TIMER_ABSTIME or TFD_TIMER_CANCEL_ON_SET.\n" +" initial\n" +" The initial expiration time, in seconds.\n" +" interval\n" +" The timer\'s interval, in seconds."); + +#define OS_TIMERFD_SETTIME_METHODDEF \ + {"timerfd_settime", _PyCFunction_CAST(os_timerfd_settime), METH_FASTCALL|METH_KEYWORDS, os_timerfd_settime__doc__}, + +static PyObject * +os_timerfd_settime_impl(PyObject *module, int fd, int flags, double initial, + double interval); + +static PyObject * +os_timerfd_settime(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 3 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(flags), &_Py_ID(initial), &_Py_ID(interval), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + + static const char * const _keywords[] = {"", "flags", "initial", "interval", NULL}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "timerfd_settime", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + PyObject *argsbuf[4]; + Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; + int fd; + int flags = 0; + double initial = 0.0; + double interval = 0.0; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, argsbuf); + if (!args) { + goto exit; + } + if (!_PyLong_FileDescriptor_Converter(args[0], &fd)) { + goto exit; + } + if (!noptargs) { + goto skip_optional_kwonly; + } + if (args[1]) { + flags = PyLong_AsInt(args[1]); + if (flags == -1 && PyErr_Occurred()) { + goto exit; + } + if (!--noptargs) { + goto skip_optional_kwonly; + } + } + if (args[2]) { + if (PyFloat_CheckExact(args[2])) { + initial = PyFloat_AS_DOUBLE(args[2]); + } + else + { + initial = PyFloat_AsDouble(args[2]); + if (initial == -1.0 && PyErr_Occurred()) { + goto exit; + } + } + if (!--noptargs) { + goto skip_optional_kwonly; + } + } + if (PyFloat_CheckExact(args[3])) { + interval = PyFloat_AS_DOUBLE(args[3]); + } + else + { + interval = PyFloat_AsDouble(args[3]); + if (interval == -1.0 && PyErr_Occurred()) { + goto exit; + } + } +skip_optional_kwonly: + return_value = os_timerfd_settime_impl(module, fd, flags, initial, interval); + +exit: + return return_value; +} + +#endif /* defined(HAVE_TIMERFD_CREATE) */ + +#if defined(HAVE_TIMERFD_CREATE) + +PyDoc_STRVAR(os_timerfd_settime_ns__doc__, +"timerfd_settime_ns($module, fd, /, *, flags=0, initial=0, interval=0)\n" +"--\n" +"\n" +"Alter a timer file descriptor\'s internal timer in nanoseconds.\n" +"\n" +" fd\n" +" A timer file descriptor.\n" +" flags\n" +" 0 or a bit mask of TFD_TIMER_ABSTIME or TFD_TIMER_CANCEL_ON_SET.\n" +" initial\n" +" initial expiration timing in seconds.\n" +" interval\n" +" interval for the timer in seconds."); + +#define OS_TIMERFD_SETTIME_NS_METHODDEF \ + {"timerfd_settime_ns", _PyCFunction_CAST(os_timerfd_settime_ns), METH_FASTCALL|METH_KEYWORDS, os_timerfd_settime_ns__doc__}, + +static PyObject * +os_timerfd_settime_ns_impl(PyObject *module, int fd, int flags, + long long initial, long long interval); + +static PyObject * +os_timerfd_settime_ns(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 3 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(flags), &_Py_ID(initial), &_Py_ID(interval), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + + static const char * const _keywords[] = {"", "flags", "initial", "interval", NULL}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "timerfd_settime_ns", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + PyObject *argsbuf[4]; + Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; + int fd; + int flags = 0; + long long initial = 0; + long long interval = 0; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, argsbuf); + if (!args) { + goto exit; + } + if (!_PyLong_FileDescriptor_Converter(args[0], &fd)) { + goto exit; + } + if (!noptargs) { + goto skip_optional_kwonly; + } + if (args[1]) { + flags = PyLong_AsInt(args[1]); + if (flags == -1 && PyErr_Occurred()) { + goto exit; + } + if (!--noptargs) { + goto skip_optional_kwonly; + } + } + if (args[2]) { + initial = PyLong_AsLongLong(args[2]); + if (initial == -1 && PyErr_Occurred()) { + goto exit; + } + if (!--noptargs) { + goto skip_optional_kwonly; + } + } + interval = PyLong_AsLongLong(args[3]); + if (interval == -1 && PyErr_Occurred()) { + goto exit; + } +skip_optional_kwonly: + return_value = os_timerfd_settime_ns_impl(module, fd, flags, initial, interval); + +exit: + return return_value; +} + +#endif /* defined(HAVE_TIMERFD_CREATE) */ + +#if defined(HAVE_TIMERFD_CREATE) + +PyDoc_STRVAR(os_timerfd_gettime__doc__, +"timerfd_gettime($module, fd, /)\n" +"--\n" +"\n" +"Return a tuple of a timer file descriptor\'s (interval, next expiration) in float seconds.\n" +"\n" +" fd\n" +" A timer file descriptor."); + +#define OS_TIMERFD_GETTIME_METHODDEF \ + {"timerfd_gettime", (PyCFunction)os_timerfd_gettime, METH_O, os_timerfd_gettime__doc__}, + +static PyObject * +os_timerfd_gettime_impl(PyObject *module, int fd); + +static PyObject * +os_timerfd_gettime(PyObject *module, PyObject *arg) +{ + PyObject *return_value = NULL; + int fd; + + if (!_PyLong_FileDescriptor_Converter(arg, &fd)) { + goto exit; + } + return_value = os_timerfd_gettime_impl(module, fd); + +exit: + return return_value; +} + +#endif /* defined(HAVE_TIMERFD_CREATE) */ + +#if defined(HAVE_TIMERFD_CREATE) + +PyDoc_STRVAR(os_timerfd_gettime_ns__doc__, +"timerfd_gettime_ns($module, fd, /)\n" +"--\n" +"\n" +"Return a tuple of a timer file descriptor\'s (interval, next expiration) in nanoseconds.\n" +"\n" +" fd\n" +" A timer file descriptor."); + +#define OS_TIMERFD_GETTIME_NS_METHODDEF \ + {"timerfd_gettime_ns", (PyCFunction)os_timerfd_gettime_ns, METH_O, os_timerfd_gettime_ns__doc__}, + +static PyObject * +os_timerfd_gettime_ns_impl(PyObject *module, int fd); + +static PyObject * +os_timerfd_gettime_ns(PyObject *module, PyObject *arg) +{ + PyObject *return_value = NULL; + int fd; + + if (!_PyLong_FileDescriptor_Converter(arg, &fd)) { + goto exit; + } + return_value = os_timerfd_gettime_ns_impl(module, fd); + +exit: + return return_value; +} + +#endif /* defined(HAVE_TIMERFD_CREATE) */ + #if defined(HAVE_GETSID) PyDoc_STRVAR(os_getsid__doc__, @@ -11761,6 +12131,26 @@ exit: #define OS_TIMES_METHODDEF #endif /* !defined(OS_TIMES_METHODDEF) */ +#ifndef OS_TIMERFD_CREATE_METHODDEF + #define OS_TIMERFD_CREATE_METHODDEF +#endif /* !defined(OS_TIMERFD_CREATE_METHODDEF) */ + +#ifndef OS_TIMERFD_SETTIME_METHODDEF + #define OS_TIMERFD_SETTIME_METHODDEF +#endif /* !defined(OS_TIMERFD_SETTIME_METHODDEF) */ + +#ifndef OS_TIMERFD_SETTIME_NS_METHODDEF + #define OS_TIMERFD_SETTIME_NS_METHODDEF +#endif /* !defined(OS_TIMERFD_SETTIME_NS_METHODDEF) */ + +#ifndef OS_TIMERFD_GETTIME_METHODDEF + #define OS_TIMERFD_GETTIME_METHODDEF +#endif /* !defined(OS_TIMERFD_GETTIME_METHODDEF) */ + +#ifndef OS_TIMERFD_GETTIME_NS_METHODDEF + #define OS_TIMERFD_GETTIME_NS_METHODDEF +#endif /* !defined(OS_TIMERFD_GETTIME_NS_METHODDEF) */ + #ifndef OS_GETSID_METHODDEF #define OS_GETSID_METHODDEF #endif /* !defined(OS_GETSID_METHODDEF) */ @@ -12024,4 +12414,4 @@ exit: #ifndef OS_WAITSTATUS_TO_EXITCODE_METHODDEF #define OS_WAITSTATUS_TO_EXITCODE_METHODDEF #endif /* !defined(OS_WAITSTATUS_TO_EXITCODE_METHODDEF) */ -/*[clinic end generated code: output=a36904281a8a7507 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=7c3058135ed49d20 input=a9049054013a1b77]*/ diff --git a/Modules/posixmodule.c b/Modules/posixmodule.c index 2c32a45..0975ef7 100644 --- a/Modules/posixmodule.c +++ b/Modules/posixmodule.c @@ -550,6 +550,11 @@ extern char *ctermid_r(char *); # include <sys/eventfd.h> #endif +/* timerfd_create() */ +#ifdef HAVE_SYS_TIMERFD_H +# include <sys/timerfd.h> +#endif + #ifdef _Py_MEMORY_SANITIZER # include <sanitizer/msan_interface.h> #endif @@ -10096,6 +10101,227 @@ os_times_impl(PyObject *module) #endif /* HAVE_TIMES */ +#if defined(HAVE_TIMERFD_CREATE) +#define ONE_SECOND_IN_NS (1000 * 1000 * 1000) +#define EXTRACT_NSEC(value) (long)( ( (double)(value) - (time_t)(value) ) * 1e9) +#define CONVERT_SEC_AND_NSEC_TO_DOUBLE(sec, nsec) ( (double)(sec) + (double)(nsec) * 1e-9 ) + +static PyObject * +build_itimerspec(const struct itimerspec* curr_value) +{ + double _value = CONVERT_SEC_AND_NSEC_TO_DOUBLE(curr_value->it_value.tv_sec, + curr_value->it_value.tv_nsec); + PyObject *value = PyFloat_FromDouble(_value); + if (value == NULL) { + return NULL; + } + double _interval = CONVERT_SEC_AND_NSEC_TO_DOUBLE(curr_value->it_interval.tv_sec, + curr_value->it_interval.tv_nsec); + PyObject *interval = PyFloat_FromDouble(_interval); + if (interval == NULL) { + Py_DECREF(value); + return NULL; + } + PyObject *tuple = PyTuple_Pack(2, value, interval); + Py_DECREF(interval); + Py_DECREF(value); + return tuple; +} + +static PyObject * +build_itimerspec_ns(const struct itimerspec* curr_value) +{ + _PyTime_t value, interval; + if (_PyTime_FromTimespec(&value, &curr_value->it_value) < 0) { + return NULL; + } + if (_PyTime_FromTimespec(&interval, &curr_value->it_interval) < 0) { + return NULL; + } + return Py_BuildValue("LL", value, interval); +} + +/*[clinic input] +os.timerfd_create + + clockid: int + A valid clock ID constant as timer file descriptor. + + time.CLOCK_REALTIME + time.CLOCK_MONOTONIC + time.CLOCK_BOOTTIME + / + * + flags: int = 0 + 0 or a bit mask of os.TFD_NONBLOCK or os.TFD_CLOEXEC. + + os.TFD_NONBLOCK + If *TFD_NONBLOCK* is set as a flag, read doesn't blocks. + If *TFD_NONBLOCK* is not set as a flag, read block until the timer fires. + + os.TFD_CLOEXEC + If *TFD_CLOEXEC* is set as a flag, enable the close-on-exec flag + +Create and return a timer file descriptor. +[clinic start generated code]*/ + +static PyObject * +os_timerfd_create_impl(PyObject *module, int clockid, int flags) +/*[clinic end generated code: output=1caae80fb168004a input=64b7020c5ac0b8f4]*/ + +{ + int fd; + Py_BEGIN_ALLOW_THREADS + flags |= TFD_CLOEXEC; // PEP 446: always create non-inheritable FD + fd = timerfd_create(clockid, flags); + Py_END_ALLOW_THREADS + if (fd == -1) { + return PyErr_SetFromErrno(PyExc_OSError); + } + return PyLong_FromLong(fd); +} + +/*[clinic input] +os.timerfd_settime + + fd: fildes + A timer file descriptor. + / + * + flags: int = 0 + 0 or a bit mask of TFD_TIMER_ABSTIME or TFD_TIMER_CANCEL_ON_SET. + initial: double = 0.0 + The initial expiration time, in seconds. + interval: double = 0.0 + The timer's interval, in seconds. + +Alter a timer file descriptor's internal timer in seconds. +[clinic start generated code]*/ + +static PyObject * +os_timerfd_settime_impl(PyObject *module, int fd, int flags, double initial, + double interval) +/*[clinic end generated code: output=0dda31115317adb9 input=6c24e47e7a4d799e]*/ +{ + struct itimerspec new_value; + struct itimerspec old_value; + int result; + if (_PyTime_AsTimespec(_PyTime_FromSecondsDouble(initial, _PyTime_ROUND_FLOOR), &new_value.it_value) < 0) { + PyErr_SetString(PyExc_ValueError, "invalid initial value"); + return NULL; + } + if (_PyTime_AsTimespec(_PyTime_FromSecondsDouble(interval, _PyTime_ROUND_FLOOR), &new_value.it_interval) < 0) { + PyErr_SetString(PyExc_ValueError, "invalid interval value"); + return NULL; + } + Py_BEGIN_ALLOW_THREADS + result = timerfd_settime(fd, flags, &new_value, &old_value); + Py_END_ALLOW_THREADS + if (result == -1) { + return PyErr_SetFromErrno(PyExc_OSError); + } + return build_itimerspec(&old_value); +} + + +/*[clinic input] +os.timerfd_settime_ns + + fd: fildes + A timer file descriptor. + / + * + flags: int = 0 + 0 or a bit mask of TFD_TIMER_ABSTIME or TFD_TIMER_CANCEL_ON_SET. + initial: long_long = 0 + initial expiration timing in seconds. + interval: long_long = 0 + interval for the timer in seconds. + +Alter a timer file descriptor's internal timer in nanoseconds. +[clinic start generated code]*/ + +static PyObject * +os_timerfd_settime_ns_impl(PyObject *module, int fd, int flags, + long long initial, long long interval) +/*[clinic end generated code: output=6273ec7d7b4cc0b3 input=261e105d6e42f5bc]*/ +{ + struct itimerspec new_value; + struct itimerspec old_value; + int result; + if (_PyTime_AsTimespec(initial, &new_value.it_value) < 0) { + PyErr_SetString(PyExc_ValueError, "invalid initial value"); + return NULL; + } + if (_PyTime_AsTimespec(interval, &new_value.it_interval) < 0) { + PyErr_SetString(PyExc_ValueError, "invalid interval value"); + return NULL; + } + Py_BEGIN_ALLOW_THREADS + result = timerfd_settime(fd, flags, &new_value, &old_value); + Py_END_ALLOW_THREADS + if (result == -1) { + return PyErr_SetFromErrno(PyExc_OSError); + } + return build_itimerspec_ns(&old_value); +} + +/*[clinic input] +os.timerfd_gettime + + fd: fildes + A timer file descriptor. + / + +Return a tuple of a timer file descriptor's (interval, next expiration) in float seconds. +[clinic start generated code]*/ + +static PyObject * +os_timerfd_gettime_impl(PyObject *module, int fd) +/*[clinic end generated code: output=ec5a94a66cfe6ab4 input=8148e3430870da1c]*/ +{ + struct itimerspec curr_value; + int result; + Py_BEGIN_ALLOW_THREADS + result = timerfd_gettime(fd, &curr_value); + Py_END_ALLOW_THREADS + if (result == -1) { + return PyErr_SetFromErrno(PyExc_OSError); + } + return build_itimerspec(&curr_value); +} + + +/*[clinic input] +os.timerfd_gettime_ns + + fd: fildes + A timer file descriptor. + / + +Return a tuple of a timer file descriptor's (interval, next expiration) in nanoseconds. +[clinic start generated code]*/ + +static PyObject * +os_timerfd_gettime_ns_impl(PyObject *module, int fd) +/*[clinic end generated code: output=580633a4465f39fe input=a825443e4c6b40ac]*/ +{ + struct itimerspec curr_value; + int result; + Py_BEGIN_ALLOW_THREADS + result = timerfd_gettime(fd, &curr_value); + Py_END_ALLOW_THREADS + if (result == -1) { + return PyErr_SetFromErrno(PyExc_OSError); + } + return build_itimerspec_ns(&curr_value); +} + +#undef ONE_SECOND_IN_NS +#undef EXTRACT_NSEC + +#endif /* HAVE_TIMERFD_CREATE */ + #ifdef HAVE_GETSID /*[clinic input] os.getsid @@ -16028,6 +16254,11 @@ static PyMethodDef posix_methods[] = { OS_WAITSTATUS_TO_EXITCODE_METHODDEF OS_SETNS_METHODDEF OS_UNSHARE_METHODDEF + OS_TIMERFD_CREATE_METHODDEF + OS_TIMERFD_SETTIME_METHODDEF + OS_TIMERFD_SETTIME_NS_METHODDEF + OS_TIMERFD_GETTIME_METHODDEF + OS_TIMERFD_GETTIME_NS_METHODDEF OS__PATH_ISDEVDRIVE_METHODDEF OS__PATH_ISDIR_METHODDEF @@ -16343,6 +16574,19 @@ all_ins(PyObject *m) if (PyModule_AddIntMacro(m, SF_NOCACHE)) return -1; #endif +#ifdef TFD_NONBLOCK + if (PyModule_AddIntMacro(m, TFD_NONBLOCK)) return -1; +#endif +#ifdef TFD_CLOEXEC + if (PyModule_AddIntMacro(m, TFD_CLOEXEC)) return -1; +#endif +#ifdef TFD_TIMER_ABSTIME + if (PyModule_AddIntMacro(m, TFD_TIMER_ABSTIME)) return -1; +#endif +#ifdef TFD_TIMER_CANCEL_ON_SET + if (PyModule_AddIntMacro(m, TFD_TIMER_CANCEL_ON_SET)) return -1; +#endif + /* constants for posix_fadvise */ #ifdef POSIX_FADV_NORMAL if (PyModule_AddIntMacro(m, POSIX_FADV_NORMAL)) return -1; @@ -16741,6 +16985,10 @@ static const struct have_function { {"HAVE_EVENTFD", NULL}, #endif +#ifdef HAVE_TIMERFD_CREATE + {"HAVE_TIMERFD_CREATE", NULL}, +#endif + #ifdef HAVE_FACCESSAT { "HAVE_FACCESSAT", probe_faccessat }, #endif |