From b5850d3c8da4ee7552a844b7d28dbab5b33df117 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?B=C3=A9n=C3=A9dikt=20Tran?= <10796600+picnixz@users.noreply.github.com> Date: Wed, 31 Jul 2024 13:13:05 +0200 Subject: [PATCH 1/2] simplify conversions --- Modules/clinic/posixmodule.c.h | 192 ++++++++++++++++++++++++++------- Modules/posixmodule.c | 40 ++++++- 2 files changed, 192 insertions(+), 40 deletions(-) diff --git a/Modules/clinic/posixmodule.c.h b/Modules/clinic/posixmodule.c.h index 4b9dbac9af031f..06d41914d8ac51 100644 --- a/Modules/clinic/posixmodule.c.h +++ b/Modules/clinic/posixmodule.c.h @@ -4344,7 +4344,8 @@ os_sched_getscheduler(PyObject *module, PyObject *arg) PyObject *return_value = NULL; pid_t pid; - if (!PyArg_Parse(arg, "" _Py_PARSE_PID ":sched_getscheduler", &pid)) { + pid = PyLong_AsPid(arg); + if (pid == (pid_t)(-1) && PyErr_Occurred()) { goto exit; } return_value = os_sched_getscheduler_impl(module, pid); @@ -4442,10 +4443,18 @@ os_sched_setscheduler(PyObject *module, PyObject *const *args, Py_ssize_t nargs) int policy; PyObject *param_obj; - if (!_PyArg_ParseStack(args, nargs, "" _Py_PARSE_PID "iO:sched_setscheduler", - &pid, &policy, ¶m_obj)) { + if (!_PyArg_CheckPositional("sched_setscheduler", nargs, 3, 3)) { goto exit; } + pid = PyLong_AsPid(args[0]); + if (pid == (pid_t)(-1) && PyErr_Occurred()) { + goto exit; + } + policy = PyLong_AsInt(args[1]); + if (policy == -1 && PyErr_Occurred()) { + goto exit; + } + param_obj = args[2]; return_value = os_sched_setscheduler_impl(module, pid, policy, param_obj); exit: @@ -4477,7 +4486,8 @@ os_sched_getparam(PyObject *module, PyObject *arg) PyObject *return_value = NULL; pid_t pid; - if (!PyArg_Parse(arg, "" _Py_PARSE_PID ":sched_getparam", &pid)) { + pid = PyLong_AsPid(arg); + if (pid == (pid_t)(-1) && PyErr_Occurred()) { goto exit; } return_value = os_sched_getparam_impl(module, pid); @@ -4512,10 +4522,14 @@ os_sched_setparam(PyObject *module, PyObject *const *args, Py_ssize_t nargs) pid_t pid; PyObject *param_obj; - if (!_PyArg_ParseStack(args, nargs, "" _Py_PARSE_PID "O:sched_setparam", - &pid, ¶m_obj)) { + if (!_PyArg_CheckPositional("sched_setparam", nargs, 2, 2)) { goto exit; } + pid = PyLong_AsPid(args[0]); + if (pid == (pid_t)(-1) && PyErr_Occurred()) { + goto exit; + } + param_obj = args[1]; return_value = os_sched_setparam_impl(module, pid, param_obj); exit: @@ -4547,7 +4561,8 @@ os_sched_rr_get_interval(PyObject *module, PyObject *arg) pid_t pid; double _return_value; - if (!PyArg_Parse(arg, "" _Py_PARSE_PID ":sched_rr_get_interval", &pid)) { + pid = PyLong_AsPid(arg); + if (pid == (pid_t)(-1) && PyErr_Occurred()) { goto exit; } _return_value = os_sched_rr_get_interval_impl(module, pid); @@ -4607,10 +4622,14 @@ os_sched_setaffinity(PyObject *module, PyObject *const *args, Py_ssize_t nargs) pid_t pid; PyObject *mask; - if (!_PyArg_ParseStack(args, nargs, "" _Py_PARSE_PID "O:sched_setaffinity", - &pid, &mask)) { + if (!_PyArg_CheckPositional("sched_setaffinity", nargs, 2, 2)) { + goto exit; + } + pid = PyLong_AsPid(args[0]); + if (pid == (pid_t)(-1) && PyErr_Occurred()) { goto exit; } + mask = args[1]; return_value = os_sched_setaffinity_impl(module, pid, mask); exit: @@ -4641,7 +4660,8 @@ os_sched_getaffinity(PyObject *module, PyObject *arg) PyObject *return_value = NULL; pid_t pid; - if (!PyArg_Parse(arg, "" _Py_PARSE_PID ":sched_getaffinity", &pid)) { + pid = PyLong_AsPid(arg); + if (pid == (pid_t)(-1) && PyErr_Occurred()) { goto exit; } return_value = os_sched_getaffinity_impl(module, pid); @@ -5240,14 +5260,19 @@ os_getpgid(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject * static const char * const _keywords[] = {"pid", NULL}; static _PyArg_Parser _parser = { .keywords = _keywords, - .format = "" _Py_PARSE_PID ":getpgid", + .fname = "getpgid", .kwtuple = KWTUPLE, }; #undef KWTUPLE + PyObject *argsbuf[1]; pid_t pid; - if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser, - &pid)) { + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, argsbuf); + if (!args) { + goto exit; + } + pid = PyLong_AsPid(args[0]); + if (pid == (pid_t)(-1) && PyErr_Occurred()) { goto exit; } return_value = os_getpgid_impl(module, pid); @@ -5392,10 +5417,25 @@ os_kill(PyObject *module, PyObject *const *args, Py_ssize_t nargs) pid_t pid; Py_ssize_t signal; - if (!_PyArg_ParseStack(args, nargs, "" _Py_PARSE_PID "n:kill", - &pid, &signal)) { + if (!_PyArg_CheckPositional("kill", nargs, 2, 2)) { + goto exit; + } + pid = PyLong_AsPid(args[0]); + if (pid == (pid_t)(-1) && PyErr_Occurred()) { goto exit; } + { + Py_ssize_t ival = -1; + PyObject *iobj = _PyNumber_Index(args[1]); + if (iobj != NULL) { + ival = PyLong_AsSsize_t(iobj); + Py_DECREF(iobj); + } + if (ival == -1 && PyErr_Occurred()) { + goto exit; + } + signal = ival; + } return_value = os_kill_impl(module, pid, signal); exit: @@ -5425,8 +5465,15 @@ os_killpg(PyObject *module, PyObject *const *args, Py_ssize_t nargs) pid_t pgid; int signal; - if (!_PyArg_ParseStack(args, nargs, "" _Py_PARSE_PID "i:killpg", - &pgid, &signal)) { + if (!_PyArg_CheckPositional("killpg", nargs, 2, 2)) { + goto exit; + } + pgid = PyLong_AsPid(args[0]); + if (pgid == (pid_t)(-1) && PyErr_Occurred()) { + goto exit; + } + signal = PyLong_AsInt(args[1]); + if (signal == -1 && PyErr_Occurred()) { goto exit; } return_value = os_killpg_impl(module, pgid, signal); @@ -5789,15 +5836,24 @@ os_wait4(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kw static const char * const _keywords[] = {"pid", "options", NULL}; static _PyArg_Parser _parser = { .keywords = _keywords, - .format = "" _Py_PARSE_PID "i:wait4", + .fname = "wait4", .kwtuple = KWTUPLE, }; #undef KWTUPLE + PyObject *argsbuf[2]; pid_t pid; int options; - if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser, - &pid, &options)) { + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 2, 2, 0, argsbuf); + if (!args) { + goto exit; + } + pid = PyLong_AsPid(args[0]); + if (pid == (pid_t)(-1) && PyErr_Occurred()) { + goto exit; + } + options = PyLong_AsInt(args[1]); + if (options == -1 && PyErr_Occurred()) { goto exit; } return_value = os_wait4_impl(module, pid, options); @@ -5841,8 +5897,18 @@ os_waitid(PyObject *module, PyObject *const *args, Py_ssize_t nargs) id_t id; int options; - if (!_PyArg_ParseStack(args, nargs, "i" _Py_PARSE_PID "i:waitid", - &idtype, &id, &options)) { + if (!_PyArg_CheckPositional("waitid", nargs, 3, 3)) { + goto exit; + } + if (!idtype_t_converter(args[0], &idtype)) { + goto exit; + } + id = (id_t)PyLong_AsPid(args[1]); + if (id == (id_t)(-1) && PyErr_Occurred()) { + goto exit; + } + options = PyLong_AsInt(args[2]); + if (options == -1 && PyErr_Occurred()) { goto exit; } return_value = os_waitid_impl(module, idtype, id, options); @@ -5879,8 +5945,15 @@ os_waitpid(PyObject *module, PyObject *const *args, Py_ssize_t nargs) pid_t pid; int options; - if (!_PyArg_ParseStack(args, nargs, "" _Py_PARSE_PID "i:waitpid", - &pid, &options)) { + if (!_PyArg_CheckPositional("waitpid", nargs, 2, 2)) { + goto exit; + } + pid = PyLong_AsPid(args[0]); + if (pid == (pid_t)(-1) && PyErr_Occurred()) { + goto exit; + } + options = PyLong_AsInt(args[1]); + if (options == -1 && PyErr_Occurred()) { goto exit; } return_value = os_waitpid_impl(module, pid, options); @@ -5917,8 +5990,15 @@ os_waitpid(PyObject *module, PyObject *const *args, Py_ssize_t nargs) intptr_t pid; int options; - if (!_PyArg_ParseStack(args, nargs, "" _Py_PARSE_INTPTR "i:waitpid", - &pid, &options)) { + if (!_PyArg_CheckPositional("waitpid", nargs, 2, 2)) { + goto exit; + } + pid = (intptr_t)PyLong_AsVoidPtr(args[0]); + if (!pid && PyErr_Occurred()) { + goto exit; + } + options = PyLong_AsInt(args[1]); + if (options == -1 && PyErr_Occurred()) { goto exit; } return_value = os_waitpid_impl(module, pid, options); @@ -5996,17 +6076,30 @@ os_pidfd_open(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObjec static const char * const _keywords[] = {"pid", "flags", NULL}; static _PyArg_Parser _parser = { .keywords = _keywords, - .format = "" _Py_PARSE_PID "|O&:pidfd_open", + .fname = "pidfd_open", .kwtuple = KWTUPLE, }; #undef KWTUPLE + PyObject *argsbuf[2]; + Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; pid_t pid; unsigned int flags = 0; - if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser, - &pid, _PyLong_UnsignedInt_Converter, &flags)) { + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 2, 0, argsbuf); + if (!args) { goto exit; } + pid = PyLong_AsPid(args[0]); + if (pid == (pid_t)(-1) && PyErr_Occurred()) { + goto exit; + } + if (!noptargs) { + goto skip_optional_pos; + } + if (!_PyLong_UnsignedInt_Converter(args[1], &flags)) { + goto exit; + } +skip_optional_pos: return_value = os_pidfd_open_impl(module, pid, flags); exit: @@ -6756,7 +6849,8 @@ os_getsid(PyObject *module, PyObject *arg) PyObject *return_value = NULL; pid_t pid; - if (!PyArg_Parse(arg, "" _Py_PARSE_PID ":getsid", &pid)) { + pid = PyLong_AsPid(arg); + if (pid == (pid_t)(-1) && PyErr_Occurred()) { goto exit; } return_value = os_getsid_impl(module, pid); @@ -6810,8 +6904,15 @@ os_setpgid(PyObject *module, PyObject *const *args, Py_ssize_t nargs) pid_t pid; pid_t pgrp; - if (!_PyArg_ParseStack(args, nargs, "" _Py_PARSE_PID "" _Py_PARSE_PID ":setpgid", - &pid, &pgrp)) { + if (!_PyArg_CheckPositional("setpgid", nargs, 2, 2)) { + goto exit; + } + pid = PyLong_AsPid(args[0]); + if (pid == (pid_t)(-1) && PyErr_Occurred()) { + goto exit; + } + pgrp = PyLong_AsPid(args[1]); + if (pgrp == (pid_t)(-1) && PyErr_Occurred()) { goto exit; } return_value = os_setpgid_impl(module, pid, pgrp); @@ -6875,8 +6976,15 @@ os_tcsetpgrp(PyObject *module, PyObject *const *args, Py_ssize_t nargs) int fd; pid_t pgid; - if (!_PyArg_ParseStack(args, nargs, "i" _Py_PARSE_PID ":tcsetpgrp", - &fd, &pgid)) { + if (!_PyArg_CheckPositional("tcsetpgrp", nargs, 2, 2)) { + goto exit; + } + fd = PyLong_AsInt(args[0]); + if (fd == -1 && PyErr_Occurred()) { + goto exit; + } + pgid = PyLong_AsPid(args[1]); + if (pgid == (pid_t)(-1) && PyErr_Occurred()) { goto exit; } return_value = os_tcsetpgrp_impl(module, fd, pgid); @@ -11258,7 +11366,8 @@ os_get_handle_inheritable(PyObject *module, PyObject *arg) intptr_t handle; int _return_value; - if (!PyArg_Parse(arg, "" _Py_PARSE_INTPTR ":get_handle_inheritable", &handle)) { + handle = (intptr_t)PyLong_AsVoidPtr(arg); + if (!handle && PyErr_Occurred()) { goto exit; } _return_value = os_get_handle_inheritable_impl(module, handle); @@ -11295,8 +11404,15 @@ os_set_handle_inheritable(PyObject *module, PyObject *const *args, Py_ssize_t na intptr_t handle; int inheritable; - if (!_PyArg_ParseStack(args, nargs, "" _Py_PARSE_INTPTR "p:set_handle_inheritable", - &handle, &inheritable)) { + if (!_PyArg_CheckPositional("set_handle_inheritable", nargs, 2, 2)) { + goto exit; + } + handle = (intptr_t)PyLong_AsVoidPtr(args[0]); + if (!handle && PyErr_Occurred()) { + goto exit; + } + inheritable = PyObject_IsTrue(args[1]); + if (inheritable < 0) { goto exit; } return_value = os_set_handle_inheritable_impl(module, handle, inheritable); @@ -12837,4 +12953,4 @@ os__create_environ(PyObject *module, PyObject *Py_UNUSED(ignored)) #ifndef OS__SUPPORTS_VIRTUAL_TERMINAL_METHODDEF #define OS__SUPPORTS_VIRTUAL_TERMINAL_METHODDEF #endif /* !defined(OS__SUPPORTS_VIRTUAL_TERMINAL_METHODDEF) */ -/*[clinic end generated code: output=2fafa0d2814948f8 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=9050dee3181ae057 input=a9049054013a1b77]*/ diff --git a/Modules/posixmodule.c b/Modules/posixmodule.c index f02b6d1779827f..9aaa0427bb90a5 100644 --- a/Modules/posixmodule.c +++ b/Modules/posixmodule.c @@ -1550,6 +1550,17 @@ dir_fd_and_follow_symlinks_invalid(const char *function_name, int dir_fd, typedef off_t Py_off_t; #endif +static int +idtype_t_converter(PyObject *arg, void *addr) +{ + int value = PyLong_AsInt(arg); + if (value == -1 && PyErr_Occurred()) { + return 0; + } + *((idtype_t *)addr) = (idtype_t)(value); + return 1; +} + static int Py_off_t_converter(PyObject *arg, void *addr) { @@ -3048,17 +3059,42 @@ class pid_t_converter(CConverter): type = 'pid_t' format_unit = '" _Py_PARSE_PID "' -class idtype_t_converter(int_converter): + def parse_arg(self, argname, displayname, *, limited_capi): + return self.format_code(""" + {paramname} = PyLong_AsPid({argname}); + if ({paramname} == (pid_t)(-1) && PyErr_Occurred()) {{{{ + goto exit; + }}}} + """, argname=argname) + +class idtype_t_converter(CConverter): type = 'idtype_t' + converter = 'idtype_t_converter' class id_t_converter(CConverter): type = 'id_t' format_unit = '" _Py_PARSE_PID "' + def parse_arg(self, argname, displayname, *, limited_capi): + return self.format_code(""" + {paramname} = (id_t)PyLong_AsPid({argname}); + if ({paramname} == (id_t)(-1) && PyErr_Occurred()) {{{{ + goto exit; + }}}} + """, argname=argname) + class intptr_t_converter(CConverter): type = 'intptr_t' format_unit = '" _Py_PARSE_INTPTR "' + def parse_arg(self, argname, displayname, *, limited_capi): + return self.format_code(""" + {paramname} = (intptr_t)PyLong_AsVoidPtr({argname}); + if (!{paramname} && PyErr_Occurred()) {{{{ + goto exit; + }}}} + """, argname=argname) + class Py_off_t_converter(CConverter): type = 'Py_off_t' converter = 'Py_off_t_converter' @@ -3078,7 +3114,7 @@ class sysconf_confname_converter(path_confname_converter): converter="conv_sysconf_confname" [python start generated code]*/ -/*[python end generated code: output=da39a3ee5e6b4b0d input=577cb476e5d64960]*/ +/*[python end generated code: output=da39a3ee5e6b4b0d input=1860d32584c2a539]*/ /*[clinic input] From 017a294e46a8ec3786cc045f3c5ea13cd7ae3b92 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?B=C3=A9n=C3=A9dikt=20Tran?= <10796600+picnixz@users.noreply.github.com> Date: Wed, 31 Jul 2024 13:35:24 +0200 Subject: [PATCH 2/2] guard converter --- Modules/posixmodule.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/Modules/posixmodule.c b/Modules/posixmodule.c index 9aaa0427bb90a5..0f24b413fd561c 100644 --- a/Modules/posixmodule.c +++ b/Modules/posixmodule.c @@ -1544,12 +1544,7 @@ dir_fd_and_follow_symlinks_invalid(const char *function_name, int dir_fd, return 0; } -#ifdef MS_WINDOWS - typedef long long Py_off_t; -#else - typedef off_t Py_off_t; -#endif - +#if defined(HAVE_WAITID) static int idtype_t_converter(PyObject *arg, void *addr) { @@ -1560,6 +1555,13 @@ idtype_t_converter(PyObject *arg, void *addr) *((idtype_t *)addr) = (idtype_t)(value); return 1; } +#endif + +#ifdef MS_WINDOWS + typedef long long Py_off_t; +#else + typedef off_t Py_off_t; +#endif static int Py_off_t_converter(PyObject *arg, void *addr)