summaryrefslogtreecommitdiffstats
path: root/contrib/tools/python3/Modules/resource.c
diff options
context:
space:
mode:
authorAlexSm <[email protected]>2024-03-05 10:40:59 +0100
committerGitHub <[email protected]>2024-03-05 12:40:59 +0300
commit1ac13c847b5358faba44dbb638a828e24369467b (patch)
tree07672b4dd3604ad3dee540a02c6494cb7d10dc3d /contrib/tools/python3/Modules/resource.c
parentffcca3e7f7958ddc6487b91d3df8c01054bd0638 (diff)
Library import 16 (#2433)
Co-authored-by: robot-piglet <[email protected]> Co-authored-by: deshevoy <[email protected]> Co-authored-by: robot-contrib <[email protected]> Co-authored-by: thegeorg <[email protected]> Co-authored-by: robot-ya-builder <[email protected]> Co-authored-by: svidyuk <[email protected]> Co-authored-by: shadchin <[email protected]> Co-authored-by: robot-ratatosk <[email protected]> Co-authored-by: innokentii <[email protected]> Co-authored-by: arkady-e1ppa <[email protected]> Co-authored-by: snermolaev <[email protected]> Co-authored-by: dimdim11 <[email protected]> Co-authored-by: kickbutt <[email protected]> Co-authored-by: abdullinsaid <[email protected]> Co-authored-by: korsunandrei <[email protected]> Co-authored-by: petrk <[email protected]> Co-authored-by: miroslav2 <[email protected]> Co-authored-by: serjflint <[email protected]> Co-authored-by: akhropov <[email protected]> Co-authored-by: prettyboy <[email protected]> Co-authored-by: ilikepugs <[email protected]> Co-authored-by: hiddenpath <[email protected]> Co-authored-by: mikhnenko <[email protected]> Co-authored-by: spreis <[email protected]> Co-authored-by: andreyshspb <[email protected]> Co-authored-by: dimaandreev <[email protected]> Co-authored-by: rashid <[email protected]> Co-authored-by: robot-ydb-importer <[email protected]> Co-authored-by: r-vetrov <[email protected]> Co-authored-by: ypodlesov <[email protected]> Co-authored-by: zaverden <[email protected]> Co-authored-by: vpozdyayev <[email protected]> Co-authored-by: robot-cozmo <[email protected]> Co-authored-by: v-korovin <[email protected]> Co-authored-by: arikon <[email protected]> Co-authored-by: khoden <[email protected]> Co-authored-by: psydmm <[email protected]> Co-authored-by: robot-javacom <[email protected]> Co-authored-by: dtorilov <[email protected]> Co-authored-by: sennikovmv <[email protected]> Co-authored-by: hcpp <[email protected]>
Diffstat (limited to 'contrib/tools/python3/Modules/resource.c')
-rw-r--r--contrib/tools/python3/Modules/resource.c556
1 files changed, 556 insertions, 0 deletions
diff --git a/contrib/tools/python3/Modules/resource.c b/contrib/tools/python3/Modules/resource.c
new file mode 100644
index 00000000000..3c89468c48c
--- /dev/null
+++ b/contrib/tools/python3/Modules/resource.c
@@ -0,0 +1,556 @@
+
+#include "Python.h"
+#include <sys/resource.h>
+#ifdef HAVE_SYS_TIME_H
+#include <sys/time.h>
+#endif
+#include <time.h>
+#include <string.h>
+#include <errno.h>
+#include <unistd.h>
+
+/* On some systems, these aren't in any header file.
+ On others they are, with inconsistent prototypes.
+ We declare the (default) return type, to shut up gcc -Wall;
+ but we can't declare the prototype, to avoid errors
+ when the header files declare it different.
+ Worse, on some Linuxes, getpagesize() returns a size_t... */
+
+#define doubletime(TV) ((double)(TV).tv_sec + (TV).tv_usec * 0.000001)
+
+/*[clinic input]
+module resource
+[clinic start generated code]*/
+/*[clinic end generated code: output=da39a3ee5e6b4b0d input=e89d38ed52609d7c]*/
+
+/*[python input]
+class pid_t_converter(CConverter):
+ type = 'pid_t'
+ format_unit = '" _Py_PARSE_PID "'
+
+ def parse_arg(self, argname, displayname):
+ return """
+ {paramname} = PyLong_AsPid({argname});
+ if ({paramname} == -1 && PyErr_Occurred()) {{{{
+ goto exit;
+ }}}}
+ """.format(argname=argname, paramname=self.parser_name)
+[python start generated code]*/
+/*[python end generated code: output=da39a3ee5e6b4b0d input=5af1c116d56cbb5a]*/
+
+#include "clinic/resource.c.h"
+
+PyDoc_STRVAR(struct_rusage__doc__,
+"struct_rusage: Result from getrusage.\n\n"
+"This object may be accessed either as a tuple of\n"
+" (utime,stime,maxrss,ixrss,idrss,isrss,minflt,majflt,\n"
+" nswap,inblock,oublock,msgsnd,msgrcv,nsignals,nvcsw,nivcsw)\n"
+"or via the attributes ru_utime, ru_stime, ru_maxrss, and so on.");
+
+static PyStructSequence_Field struct_rusage_fields[] = {
+ {"ru_utime", "user time used"},
+ {"ru_stime", "system time used"},
+ {"ru_maxrss", "max. resident set size"},
+ {"ru_ixrss", "shared memory size"},
+ {"ru_idrss", "unshared data size"},
+ {"ru_isrss", "unshared stack size"},
+ {"ru_minflt", "page faults not requiring I/O"},
+ {"ru_majflt", "page faults requiring I/O"},
+ {"ru_nswap", "number of swap outs"},
+ {"ru_inblock", "block input operations"},
+ {"ru_oublock", "block output operations"},
+ {"ru_msgsnd", "IPC messages sent"},
+ {"ru_msgrcv", "IPC messages received"},
+ {"ru_nsignals", "signals received"},
+ {"ru_nvcsw", "voluntary context switches"},
+ {"ru_nivcsw", "involuntary context switches"},
+ {0}
+};
+
+static PyStructSequence_Desc struct_rusage_desc = {
+ "resource.struct_rusage", /* name */
+ struct_rusage__doc__, /* doc */
+ struct_rusage_fields, /* fields */
+ 16 /* n_in_sequence */
+};
+
+typedef struct {
+ PyTypeObject *StructRUsageType;
+} resourcemodulestate;
+
+
+static inline resourcemodulestate*
+get_resource_state(PyObject *module)
+{
+ void *state = PyModule_GetState(module);
+ assert(state != NULL);
+ return (resourcemodulestate *)state;
+}
+
+static struct PyModuleDef resourcemodule;
+
+#ifdef HAVE_GETRUSAGE
+/*[clinic input]
+resource.getrusage
+
+ who: int
+ /
+
+[clinic start generated code]*/
+
+static PyObject *
+resource_getrusage_impl(PyObject *module, int who)
+/*[clinic end generated code: output=8fad2880ba6a9843 input=5c857bcc5b9ccb1b]*/
+{
+ struct rusage ru;
+ PyObject *result;
+
+ if (getrusage(who, &ru) == -1) {
+ if (errno == EINVAL) {
+ PyErr_SetString(PyExc_ValueError,
+ "invalid who parameter");
+ return NULL;
+ }
+ PyErr_SetFromErrno(PyExc_OSError);
+ return NULL;
+ }
+
+ result = PyStructSequence_New(
+ get_resource_state(module)->StructRUsageType);
+ if (!result)
+ return NULL;
+
+ PyStructSequence_SET_ITEM(result, 0,
+ PyFloat_FromDouble(doubletime(ru.ru_utime)));
+ PyStructSequence_SET_ITEM(result, 1,
+ PyFloat_FromDouble(doubletime(ru.ru_stime)));
+ PyStructSequence_SET_ITEM(result, 2, PyLong_FromLong(ru.ru_maxrss));
+ PyStructSequence_SET_ITEM(result, 3, PyLong_FromLong(ru.ru_ixrss));
+ PyStructSequence_SET_ITEM(result, 4, PyLong_FromLong(ru.ru_idrss));
+ PyStructSequence_SET_ITEM(result, 5, PyLong_FromLong(ru.ru_isrss));
+ PyStructSequence_SET_ITEM(result, 6, PyLong_FromLong(ru.ru_minflt));
+ PyStructSequence_SET_ITEM(result, 7, PyLong_FromLong(ru.ru_majflt));
+ PyStructSequence_SET_ITEM(result, 8, PyLong_FromLong(ru.ru_nswap));
+ PyStructSequence_SET_ITEM(result, 9, PyLong_FromLong(ru.ru_inblock));
+ PyStructSequence_SET_ITEM(result, 10, PyLong_FromLong(ru.ru_oublock));
+ PyStructSequence_SET_ITEM(result, 11, PyLong_FromLong(ru.ru_msgsnd));
+ PyStructSequence_SET_ITEM(result, 12, PyLong_FromLong(ru.ru_msgrcv));
+ PyStructSequence_SET_ITEM(result, 13, PyLong_FromLong(ru.ru_nsignals));
+ PyStructSequence_SET_ITEM(result, 14, PyLong_FromLong(ru.ru_nvcsw));
+ PyStructSequence_SET_ITEM(result, 15, PyLong_FromLong(ru.ru_nivcsw));
+
+ if (PyErr_Occurred()) {
+ Py_DECREF(result);
+ return NULL;
+ }
+
+ return result;
+}
+#endif
+
+static int
+py2rlimit(PyObject *limits, struct rlimit *rl_out)
+{
+ PyObject *curobj, *maxobj;
+ limits = PySequence_Tuple(limits);
+ if (!limits)
+ /* Here limits is a borrowed reference */
+ return -1;
+
+ if (PyTuple_GET_SIZE(limits) != 2) {
+ PyErr_SetString(PyExc_ValueError,
+ "expected a tuple of 2 integers");
+ goto error;
+ }
+ curobj = PyTuple_GET_ITEM(limits, 0);
+ maxobj = PyTuple_GET_ITEM(limits, 1);
+#if !defined(HAVE_LARGEFILE_SUPPORT)
+ rl_out->rlim_cur = PyLong_AsLong(curobj);
+ if (rl_out->rlim_cur == (rlim_t)-1 && PyErr_Occurred())
+ goto error;
+ rl_out->rlim_max = PyLong_AsLong(maxobj);
+ if (rl_out->rlim_max == (rlim_t)-1 && PyErr_Occurred())
+ goto error;
+#else
+ /* The limits are probably bigger than a long */
+ rl_out->rlim_cur = PyLong_AsLongLong(curobj);
+ if (rl_out->rlim_cur == (rlim_t)-1 && PyErr_Occurred())
+ goto error;
+ rl_out->rlim_max = PyLong_AsLongLong(maxobj);
+ if (rl_out->rlim_max == (rlim_t)-1 && PyErr_Occurred())
+ goto error;
+#endif
+
+ Py_DECREF(limits);
+ rl_out->rlim_cur = rl_out->rlim_cur & RLIM_INFINITY;
+ rl_out->rlim_max = rl_out->rlim_max & RLIM_INFINITY;
+ return 0;
+
+error:
+ Py_DECREF(limits);
+ return -1;
+}
+
+static PyObject*
+rlimit2py(struct rlimit rl)
+{
+ if (sizeof(rl.rlim_cur) > sizeof(long)) {
+ return Py_BuildValue("LL",
+ (long long) rl.rlim_cur,
+ (long long) rl.rlim_max);
+ }
+ return Py_BuildValue("ll", (long) rl.rlim_cur, (long) rl.rlim_max);
+}
+
+/*[clinic input]
+resource.getrlimit
+
+ resource: int
+ /
+
+[clinic start generated code]*/
+
+static PyObject *
+resource_getrlimit_impl(PyObject *module, int resource)
+/*[clinic end generated code: output=98327b25061ffe39 input=a697cb0004cb3c36]*/
+{
+ struct rlimit rl;
+
+ if (resource < 0 || resource >= RLIM_NLIMITS) {
+ PyErr_SetString(PyExc_ValueError,
+ "invalid resource specified");
+ return NULL;
+ }
+
+ if (getrlimit(resource, &rl) == -1) {
+ PyErr_SetFromErrno(PyExc_OSError);
+ return NULL;
+ }
+ return rlimit2py(rl);
+}
+
+/*[clinic input]
+resource.setrlimit
+
+ resource: int
+ limits: object
+ /
+
+[clinic start generated code]*/
+
+static PyObject *
+resource_setrlimit_impl(PyObject *module, int resource, PyObject *limits)
+/*[clinic end generated code: output=4e82ec3f34d013d1 input=6235a6ce23b4ca75]*/
+{
+ struct rlimit rl;
+
+ if (resource < 0 || resource >= RLIM_NLIMITS) {
+ PyErr_SetString(PyExc_ValueError,
+ "invalid resource specified");
+ return NULL;
+ }
+
+ if (PySys_Audit("resource.setrlimit", "iO", resource,
+ limits ? limits : Py_None) < 0) {
+ return NULL;
+ }
+
+ if (py2rlimit(limits, &rl) < 0) {
+ return NULL;
+ }
+
+ if (setrlimit(resource, &rl) == -1) {
+ if (errno == EINVAL)
+ PyErr_SetString(PyExc_ValueError,
+ "current limit exceeds maximum limit");
+ else if (errno == EPERM)
+ PyErr_SetString(PyExc_ValueError,
+ "not allowed to raise maximum limit");
+ else
+ PyErr_SetFromErrno(PyExc_OSError);
+ return NULL;
+ }
+ Py_RETURN_NONE;
+}
+
+#ifdef HAVE_PRLIMIT
+/*[clinic input]
+resource.prlimit
+
+ pid: pid_t
+ resource: int
+ limits: object = None
+ /
+
+[clinic start generated code]*/
+
+static PyObject *
+resource_prlimit_impl(PyObject *module, pid_t pid, int resource,
+ PyObject *limits)
+/*[clinic end generated code: output=6ebc49ff8c3a816e input=54bb69c9585e33bf]*/
+{
+ struct rlimit old_limit, new_limit;
+ int retval;
+
+ if (resource < 0 || resource >= RLIM_NLIMITS) {
+ PyErr_SetString(PyExc_ValueError,
+ "invalid resource specified");
+ return NULL;
+ }
+
+ if (PySys_Audit("resource.prlimit", "iiO", pid, resource,
+ limits ? limits : Py_None) < 0) {
+ return NULL;
+ }
+
+ if (limits != Py_None) {
+ if (py2rlimit(limits, &new_limit) < 0) {
+ return NULL;
+ }
+ retval = prlimit(pid, resource, &new_limit, &old_limit);
+ }
+ else {
+ retval = prlimit(pid, resource, NULL, &old_limit);
+ }
+
+ if (retval == -1) {
+ if (errno == EINVAL) {
+ PyErr_SetString(PyExc_ValueError,
+ "current limit exceeds maximum limit");
+ } else {
+ PyErr_SetFromErrno(PyExc_OSError);
+ }
+ return NULL;
+ }
+ return rlimit2py(old_limit);
+}
+#endif /* HAVE_PRLIMIT */
+
+/*[clinic input]
+resource.getpagesize -> int
+[clinic start generated code]*/
+
+static int
+resource_getpagesize_impl(PyObject *module)
+/*[clinic end generated code: output=9ba93eb0f3d6c3a9 input=546545e8c1f42085]*/
+{
+ long pagesize = 0;
+#if defined(HAVE_GETPAGESIZE)
+ pagesize = getpagesize();
+#elif defined(HAVE_SYSCONF) && defined(_SC_PAGE_SIZE)
+ pagesize = sysconf(_SC_PAGE_SIZE);
+#else
+# error "unsupported platform: resource.getpagesize()"
+#endif
+ return pagesize;
+}
+
+/* List of functions */
+
+static struct PyMethodDef
+resource_methods[] = {
+ RESOURCE_GETRUSAGE_METHODDEF
+ RESOURCE_GETRLIMIT_METHODDEF
+ RESOURCE_PRLIMIT_METHODDEF
+ RESOURCE_SETRLIMIT_METHODDEF
+ RESOURCE_GETPAGESIZE_METHODDEF
+ {NULL, NULL} /* sentinel */
+};
+
+
+/* Module initialization */
+
+static int
+resource_exec(PyObject *module)
+{
+ resourcemodulestate *state = get_resource_state(module);
+#define ADD_INT(module, value) \
+ do { \
+ if (PyModule_AddIntConstant(module, #value, value) < 0) { \
+ return -1; \
+ } \
+ } while (0)
+
+ /* Add some symbolic constants to the module */
+ Py_INCREF(PyExc_OSError);
+ if (PyModule_AddObject(module, "error", PyExc_OSError) < 0) {
+ Py_DECREF(PyExc_OSError);
+ return -1;
+ }
+
+ state->StructRUsageType = PyStructSequence_NewType(&struct_rusage_desc);
+ if (state->StructRUsageType == NULL) {
+ return -1;
+ }
+ if (PyModule_AddType(module, state->StructRUsageType) < 0) {
+ return -1;
+ }
+
+ /* insert constants */
+#ifdef RLIMIT_CPU
+ ADD_INT(module, RLIMIT_CPU);
+#endif
+
+#ifdef RLIMIT_FSIZE
+ ADD_INT(module, RLIMIT_FSIZE);
+#endif
+
+#ifdef RLIMIT_DATA
+ ADD_INT(module, RLIMIT_DATA);
+#endif
+
+#ifdef RLIMIT_STACK
+ ADD_INT(module, RLIMIT_STACK);
+#endif
+
+#ifdef RLIMIT_CORE
+ ADD_INT(module, RLIMIT_CORE);
+#endif
+
+#ifdef RLIMIT_NOFILE
+ ADD_INT(module, RLIMIT_NOFILE);
+#endif
+
+#ifdef RLIMIT_OFILE
+ ADD_INT(module, RLIMIT_OFILE);
+#endif
+
+#ifdef RLIMIT_VMEM
+ ADD_INT(module, RLIMIT_VMEM);
+#endif
+
+#ifdef RLIMIT_AS
+ ADD_INT(module, RLIMIT_AS);
+#endif
+
+#ifdef RLIMIT_RSS
+ ADD_INT(module, RLIMIT_RSS);
+#endif
+
+#ifdef RLIMIT_NPROC
+ ADD_INT(module, RLIMIT_NPROC);
+#endif
+
+#ifdef RLIMIT_MEMLOCK
+ ADD_INT(module, RLIMIT_MEMLOCK);
+#endif
+
+#ifdef RLIMIT_SBSIZE
+ ADD_INT(module, RLIMIT_SBSIZE);
+#endif
+
+/* Linux specific */
+#ifdef RLIMIT_MSGQUEUE
+ ADD_INT(module, RLIMIT_MSGQUEUE);
+#endif
+
+#ifdef RLIMIT_NICE
+ ADD_INT(module, RLIMIT_NICE);
+#endif
+
+#ifdef RLIMIT_RTPRIO
+ ADD_INT(module, RLIMIT_RTPRIO);
+#endif
+
+#ifdef RLIMIT_RTTIME
+ ADD_INT(module, RLIMIT_RTTIME);
+#endif
+
+#ifdef RLIMIT_SIGPENDING
+ ADD_INT(module, RLIMIT_SIGPENDING);
+#endif
+
+/* target */
+#ifdef RUSAGE_SELF
+ ADD_INT(module, RUSAGE_SELF);
+#endif
+
+#ifdef RUSAGE_CHILDREN
+ ADD_INT(module, RUSAGE_CHILDREN);
+#endif
+
+#ifdef RUSAGE_BOTH
+ ADD_INT(module, RUSAGE_BOTH);
+#endif
+
+#ifdef RUSAGE_THREAD
+ ADD_INT(module, RUSAGE_THREAD);
+#endif
+
+/* FreeBSD specific */
+
+#ifdef RLIMIT_SWAP
+ ADD_INT(module, RLIMIT_SWAP);
+#endif
+
+#ifdef RLIMIT_SBSIZE
+ ADD_INT(module, RLIMIT_SBSIZE);
+#endif
+
+#ifdef RLIMIT_NPTS
+ ADD_INT(module, RLIMIT_NPTS);
+#endif
+
+#ifdef RLIMIT_KQUEUES
+ ADD_INT(module, RLIMIT_KQUEUES);
+#endif
+
+ PyObject *v;
+ if (sizeof(RLIM_INFINITY) > sizeof(long)) {
+ v = PyLong_FromLongLong((long long) RLIM_INFINITY);
+ } else
+ {
+ v = PyLong_FromLong((long) RLIM_INFINITY);
+ }
+ if (!v) {
+ return -1;
+ }
+
+ if (PyModule_AddObject(module, "RLIM_INFINITY", v) < 0) {
+ Py_DECREF(v);
+ return -1;
+ }
+ return 0;
+
+#undef ADD_INT
+}
+
+static struct PyModuleDef_Slot resource_slots[] = {
+ {Py_mod_exec, resource_exec},
+ {Py_mod_multiple_interpreters, Py_MOD_PER_INTERPRETER_GIL_SUPPORTED},
+ {0, NULL}
+};
+
+static int
+resourcemodule_traverse(PyObject *m, visitproc visit, void *arg) {
+ Py_VISIT(get_resource_state(m)->StructRUsageType);
+ return 0;
+}
+
+static int
+resourcemodule_clear(PyObject *m) {
+ Py_CLEAR(get_resource_state(m)->StructRUsageType);
+ return 0;
+}
+
+static void
+resourcemodule_free(void *m) {
+ resourcemodule_clear((PyObject *)m);
+}
+
+static struct PyModuleDef resourcemodule = {
+ PyModuleDef_HEAD_INIT,
+ .m_name = "resource",
+ .m_size = sizeof(resourcemodulestate),
+ .m_methods = resource_methods,
+ .m_slots = resource_slots,
+ .m_traverse = resourcemodule_traverse,
+ .m_clear = resourcemodule_clear,
+ .m_free = resourcemodule_free,
+};
+
+PyMODINIT_FUNC
+PyInit_resource(void)
+{
+ return PyModuleDef_Init(&resourcemodule);
+}