mirror of
https://github.com/python/cpython.git
synced 2025-11-08 17:41:42 +00:00
[3.14] gh-137044: Support large limit values in getrlimit() and setrlimit() (GH-137338) (#137506)
gh-137044: Support large limit values in getrlimit() and setrlimit() (GH-137338)
* Return large limit values as positive integers instead of negative integers
in resource.getrlimit().
* Accept large values and reject negative values (except RLIM_INFINITY)
for limits in resource.setrlimit().
(cherry picked from commit baefaa6cba)
Co-authored-by: Serhiy Storchaka <storchaka@gmail.com>
This commit is contained in:
parent
b414ad1043
commit
c4be405fe9
4 changed files with 200 additions and 121 deletions
|
|
@ -14,18 +14,27 @@ class ResourceTest(unittest.TestCase):
|
||||||
|
|
||||||
def test_args(self):
|
def test_args(self):
|
||||||
self.assertRaises(TypeError, resource.getrlimit)
|
self.assertRaises(TypeError, resource.getrlimit)
|
||||||
self.assertRaises(TypeError, resource.getrlimit, 42, 42)
|
self.assertRaises(TypeError, resource.getrlimit, 0, 42)
|
||||||
|
self.assertRaises(OverflowError, resource.getrlimit, 2**1000)
|
||||||
|
self.assertRaises(OverflowError, resource.getrlimit, -2**1000)
|
||||||
|
self.assertRaises(TypeError, resource.getrlimit, '0')
|
||||||
self.assertRaises(TypeError, resource.setrlimit)
|
self.assertRaises(TypeError, resource.setrlimit)
|
||||||
self.assertRaises(TypeError, resource.setrlimit, 42, 42, 42)
|
self.assertRaises(TypeError, resource.setrlimit, 0)
|
||||||
|
self.assertRaises(TypeError, resource.setrlimit, 0, 42)
|
||||||
|
self.assertRaises(TypeError, resource.setrlimit, 0, 42, 42)
|
||||||
|
self.assertRaises(OverflowError, resource.setrlimit, 2**1000, (42, 42))
|
||||||
|
self.assertRaises(OverflowError, resource.setrlimit, -2**1000, (42, 42))
|
||||||
|
self.assertRaises(ValueError, resource.setrlimit, 0, (42,))
|
||||||
|
self.assertRaises(ValueError, resource.setrlimit, 0, (42, 42, 42))
|
||||||
|
self.assertRaises(TypeError, resource.setrlimit, '0', (42, 42))
|
||||||
|
self.assertRaises(TypeError, resource.setrlimit, 0, ('42', 42))
|
||||||
|
self.assertRaises(TypeError, resource.setrlimit, 0, (42, '42'))
|
||||||
|
|
||||||
@unittest.skipIf(sys.platform == "vxworks",
|
@unittest.skipIf(sys.platform == "vxworks",
|
||||||
"setting RLIMIT_FSIZE is not supported on VxWorks")
|
"setting RLIMIT_FSIZE is not supported on VxWorks")
|
||||||
|
@unittest.skipUnless(hasattr(resource, 'RLIMIT_FSIZE'), 'requires resource.RLIMIT_FSIZE')
|
||||||
def test_fsize_ismax(self):
|
def test_fsize_ismax(self):
|
||||||
try:
|
|
||||||
(cur, max) = resource.getrlimit(resource.RLIMIT_FSIZE)
|
(cur, max) = resource.getrlimit(resource.RLIMIT_FSIZE)
|
||||||
except AttributeError:
|
|
||||||
pass
|
|
||||||
else:
|
|
||||||
# RLIMIT_FSIZE should be RLIM_INFINITY, which will be a really big
|
# RLIMIT_FSIZE should be RLIM_INFINITY, which will be a really big
|
||||||
# number on a platform with large file support. On these platforms,
|
# number on a platform with large file support. On these platforms,
|
||||||
# we need to test that the get/setrlimit functions properly convert
|
# we need to test that the get/setrlimit functions properly convert
|
||||||
|
|
@ -34,12 +43,11 @@ def test_fsize_ismax(self):
|
||||||
self.assertEqual(resource.RLIM_INFINITY, max)
|
self.assertEqual(resource.RLIM_INFINITY, max)
|
||||||
resource.setrlimit(resource.RLIMIT_FSIZE, (cur, max))
|
resource.setrlimit(resource.RLIMIT_FSIZE, (cur, max))
|
||||||
|
|
||||||
|
@unittest.skipIf(sys.platform == "vxworks",
|
||||||
|
"setting RLIMIT_FSIZE is not supported on VxWorks")
|
||||||
|
@unittest.skipUnless(hasattr(resource, 'RLIMIT_FSIZE'), 'requires resource.RLIMIT_FSIZE')
|
||||||
def test_fsize_enforced(self):
|
def test_fsize_enforced(self):
|
||||||
try:
|
|
||||||
(cur, max) = resource.getrlimit(resource.RLIMIT_FSIZE)
|
(cur, max) = resource.getrlimit(resource.RLIMIT_FSIZE)
|
||||||
except AttributeError:
|
|
||||||
pass
|
|
||||||
else:
|
|
||||||
# Check to see what happens when the RLIMIT_FSIZE is small. Some
|
# Check to see what happens when the RLIMIT_FSIZE is small. Some
|
||||||
# versions of Python were terminated by an uncaught SIGXFSZ, but
|
# versions of Python were terminated by an uncaught SIGXFSZ, but
|
||||||
# pythonrun.c has been fixed to ignore that exception. If so, the
|
# pythonrun.c has been fixed to ignore that exception. If so, the
|
||||||
|
|
@ -81,14 +89,13 @@ def test_fsize_enforced(self):
|
||||||
resource.setrlimit(resource.RLIMIT_FSIZE, (cur, max))
|
resource.setrlimit(resource.RLIMIT_FSIZE, (cur, max))
|
||||||
os_helper.unlink(os_helper.TESTFN)
|
os_helper.unlink(os_helper.TESTFN)
|
||||||
|
|
||||||
def test_fsize_toobig(self):
|
@unittest.skipIf(sys.platform == "vxworks",
|
||||||
|
"setting RLIMIT_FSIZE is not supported on VxWorks")
|
||||||
|
@unittest.skipUnless(hasattr(resource, 'RLIMIT_FSIZE'), 'requires resource.RLIMIT_FSIZE')
|
||||||
|
def test_fsize_too_big(self):
|
||||||
# Be sure that setrlimit is checking for really large values
|
# Be sure that setrlimit is checking for really large values
|
||||||
too_big = 10**50
|
too_big = 10**50
|
||||||
try:
|
|
||||||
(cur, max) = resource.getrlimit(resource.RLIMIT_FSIZE)
|
(cur, max) = resource.getrlimit(resource.RLIMIT_FSIZE)
|
||||||
except AttributeError:
|
|
||||||
pass
|
|
||||||
else:
|
|
||||||
try:
|
try:
|
||||||
resource.setrlimit(resource.RLIMIT_FSIZE, (too_big, max))
|
resource.setrlimit(resource.RLIMIT_FSIZE, (too_big, max))
|
||||||
except (OverflowError, ValueError):
|
except (OverflowError, ValueError):
|
||||||
|
|
@ -98,6 +105,64 @@ def test_fsize_toobig(self):
|
||||||
except (OverflowError, ValueError):
|
except (OverflowError, ValueError):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
@unittest.skipIf(sys.platform == "vxworks",
|
||||||
|
"setting RLIMIT_FSIZE is not supported on VxWorks")
|
||||||
|
@unittest.skipUnless(hasattr(resource, 'RLIMIT_FSIZE'), 'requires resource.RLIMIT_FSIZE')
|
||||||
|
def test_fsize_not_too_big(self):
|
||||||
|
(cur, max) = resource.getrlimit(resource.RLIMIT_FSIZE)
|
||||||
|
self.addCleanup(resource.setrlimit, resource.RLIMIT_FSIZE, (cur, max))
|
||||||
|
|
||||||
|
def expected(cur):
|
||||||
|
if resource.RLIM_INFINITY < 0:
|
||||||
|
return [(cur, max), (resource.RLIM_INFINITY, max)]
|
||||||
|
elif resource.RLIM_INFINITY < cur:
|
||||||
|
return [(resource.RLIM_INFINITY, max)]
|
||||||
|
else:
|
||||||
|
return [(cur, max)]
|
||||||
|
|
||||||
|
resource.setrlimit(resource.RLIMIT_FSIZE, (2**31-5, max))
|
||||||
|
self.assertEqual(resource.getrlimit(resource.RLIMIT_FSIZE), (2**31-5, max))
|
||||||
|
|
||||||
|
try:
|
||||||
|
resource.setrlimit(resource.RLIMIT_FSIZE, (2**32, max))
|
||||||
|
except OverflowError:
|
||||||
|
resource.setrlimit(resource.RLIMIT_FSIZE, (2**31, max))
|
||||||
|
self.assertIn(resource.getrlimit(resource.RLIMIT_FSIZE), expected(2**31))
|
||||||
|
resource.setrlimit(resource.RLIMIT_FSIZE, (2**32-5, max))
|
||||||
|
self.assertIn(resource.getrlimit(resource.RLIMIT_FSIZE), expected(2**32-5))
|
||||||
|
else:
|
||||||
|
self.assertIn(resource.getrlimit(resource.RLIMIT_FSIZE), expected(2**32))
|
||||||
|
resource.setrlimit(resource.RLIMIT_FSIZE, (2**31, max))
|
||||||
|
self.assertEqual(resource.getrlimit(resource.RLIMIT_FSIZE), (2**31, max))
|
||||||
|
resource.setrlimit(resource.RLIMIT_FSIZE, (2**32-5, max))
|
||||||
|
self.assertEqual(resource.getrlimit(resource.RLIMIT_FSIZE), (2**32-5, max))
|
||||||
|
|
||||||
|
resource.setrlimit(resource.RLIMIT_FSIZE, (2**63-5, max))
|
||||||
|
self.assertIn(resource.getrlimit(resource.RLIMIT_FSIZE), expected(2**63-5))
|
||||||
|
try:
|
||||||
|
resource.setrlimit(resource.RLIMIT_FSIZE, (2**63, max))
|
||||||
|
except ValueError:
|
||||||
|
# There is a hard limit on macOS.
|
||||||
|
pass
|
||||||
|
else:
|
||||||
|
self.assertIn(resource.getrlimit(resource.RLIMIT_FSIZE), expected(2**63))
|
||||||
|
resource.setrlimit(resource.RLIMIT_FSIZE, (2**64-5, max))
|
||||||
|
self.assertIn(resource.getrlimit(resource.RLIMIT_FSIZE), expected(2**64-5))
|
||||||
|
|
||||||
|
@unittest.skipIf(sys.platform == "vxworks",
|
||||||
|
"setting RLIMIT_FSIZE is not supported on VxWorks")
|
||||||
|
@unittest.skipUnless(hasattr(resource, 'RLIMIT_FSIZE'), 'requires resource.RLIMIT_FSIZE')
|
||||||
|
def test_fsize_negative(self):
|
||||||
|
(cur, max) = resource.getrlimit(resource.RLIMIT_FSIZE)
|
||||||
|
for value in -5, -2**31, -2**32-5, -2**63, -2**64-5, -2**1000:
|
||||||
|
with self.subTest(value=value):
|
||||||
|
# This test assumes that the values don't map to RLIM_INFINITY,
|
||||||
|
# though Posix doesn't guarantee it.
|
||||||
|
self.assertNotEqual(value, resource.RLIM_INFINITY)
|
||||||
|
|
||||||
|
self.assertRaises(ValueError, resource.setrlimit, resource.RLIMIT_FSIZE, (value, max))
|
||||||
|
self.assertRaises(ValueError, resource.setrlimit, resource.RLIMIT_FSIZE, (cur, value))
|
||||||
|
|
||||||
@unittest.skipUnless(hasattr(resource, "getrusage"), "needs getrusage")
|
@unittest.skipUnless(hasattr(resource, "getrusage"), "needs getrusage")
|
||||||
def test_getrusage(self):
|
def test_getrusage(self):
|
||||||
self.assertRaises(TypeError, resource.getrusage)
|
self.assertRaises(TypeError, resource.getrusage)
|
||||||
|
|
@ -117,12 +182,9 @@ def test_getrusage(self):
|
||||||
# Issue 6083: Reference counting bug
|
# Issue 6083: Reference counting bug
|
||||||
@unittest.skipIf(sys.platform == "vxworks",
|
@unittest.skipIf(sys.platform == "vxworks",
|
||||||
"setting RLIMIT_CPU is not supported on VxWorks")
|
"setting RLIMIT_CPU is not supported on VxWorks")
|
||||||
|
@unittest.skipUnless(hasattr(resource, 'RLIMIT_CPU'), 'requires resource.RLIMIT_CPU')
|
||||||
def test_setrusage_refcount(self):
|
def test_setrusage_refcount(self):
|
||||||
try:
|
|
||||||
limits = resource.getrlimit(resource.RLIMIT_CPU)
|
limits = resource.getrlimit(resource.RLIMIT_CPU)
|
||||||
except AttributeError:
|
|
||||||
pass
|
|
||||||
else:
|
|
||||||
class BadSequence:
|
class BadSequence:
|
||||||
def __len__(self):
|
def __len__(self):
|
||||||
return 2
|
return 2
|
||||||
|
|
@ -168,7 +230,8 @@ class BadSeq:
|
||||||
def __len__(self):
|
def __len__(self):
|
||||||
return 2
|
return 2
|
||||||
def __getitem__(self, key):
|
def __getitem__(self, key):
|
||||||
return limits[key] - 1 # new reference
|
lim = limits[key]
|
||||||
|
return lim - 1 if lim > 0 else lim + sys.maxsize*2 # new reference
|
||||||
|
|
||||||
limits = resource.getrlimit(resource.RLIMIT_AS)
|
limits = resource.getrlimit(resource.RLIMIT_AS)
|
||||||
self.assertEqual(resource.prlimit(0, resource.RLIMIT_AS, BadSeq()),
|
self.assertEqual(resource.prlimit(0, resource.RLIMIT_AS, BadSeq()),
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,4 @@
|
||||||
|
Return large limit values as positive integers instead of negative integers
|
||||||
|
in :func:`resource.getrlimit`. Accept large values and reject negative
|
||||||
|
values (except :data:`~resource.RLIM_INFINITY`) for limits in
|
||||||
|
:func:`resource.setrlimit`.
|
||||||
18
Modules/clinic/resource.c.h
generated
18
Modules/clinic/resource.c.h
generated
|
|
@ -2,6 +2,8 @@
|
||||||
preserve
|
preserve
|
||||||
[clinic start generated code]*/
|
[clinic start generated code]*/
|
||||||
|
|
||||||
|
#include "pycore_modsupport.h" // _PyArg_CheckPositional()
|
||||||
|
|
||||||
#if defined(HAVE_GETRUSAGE)
|
#if defined(HAVE_GETRUSAGE)
|
||||||
|
|
||||||
PyDoc_STRVAR(resource_getrusage__doc__,
|
PyDoc_STRVAR(resource_getrusage__doc__,
|
||||||
|
|
@ -66,7 +68,7 @@ PyDoc_STRVAR(resource_setrlimit__doc__,
|
||||||
"\n");
|
"\n");
|
||||||
|
|
||||||
#define RESOURCE_SETRLIMIT_METHODDEF \
|
#define RESOURCE_SETRLIMIT_METHODDEF \
|
||||||
{"setrlimit", (PyCFunction)(void(*)(void))resource_setrlimit, METH_FASTCALL, resource_setrlimit__doc__},
|
{"setrlimit", _PyCFunction_CAST(resource_setrlimit), METH_FASTCALL, resource_setrlimit__doc__},
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
resource_setrlimit_impl(PyObject *module, int resource, PyObject *limits);
|
resource_setrlimit_impl(PyObject *module, int resource, PyObject *limits);
|
||||||
|
|
@ -78,8 +80,7 @@ resource_setrlimit(PyObject *module, PyObject *const *args, Py_ssize_t nargs)
|
||||||
int resource;
|
int resource;
|
||||||
PyObject *limits;
|
PyObject *limits;
|
||||||
|
|
||||||
if (nargs != 2) {
|
if (!_PyArg_CheckPositional("setrlimit", nargs, 2, 2)) {
|
||||||
PyErr_Format(PyExc_TypeError, "setrlimit expected 2 arguments, got %zd", nargs);
|
|
||||||
goto exit;
|
goto exit;
|
||||||
}
|
}
|
||||||
resource = PyLong_AsInt(args[0]);
|
resource = PyLong_AsInt(args[0]);
|
||||||
|
|
@ -101,7 +102,7 @@ PyDoc_STRVAR(resource_prlimit__doc__,
|
||||||
"\n");
|
"\n");
|
||||||
|
|
||||||
#define RESOURCE_PRLIMIT_METHODDEF \
|
#define RESOURCE_PRLIMIT_METHODDEF \
|
||||||
{"prlimit", (PyCFunction)(void(*)(void))resource_prlimit, METH_FASTCALL, resource_prlimit__doc__},
|
{"prlimit", _PyCFunction_CAST(resource_prlimit), METH_FASTCALL, resource_prlimit__doc__},
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
resource_prlimit_impl(PyObject *module, pid_t pid, int resource,
|
resource_prlimit_impl(PyObject *module, pid_t pid, int resource,
|
||||||
|
|
@ -115,12 +116,7 @@ resource_prlimit(PyObject *module, PyObject *const *args, Py_ssize_t nargs)
|
||||||
int resource;
|
int resource;
|
||||||
PyObject *limits = Py_None;
|
PyObject *limits = Py_None;
|
||||||
|
|
||||||
if (nargs < 2) {
|
if (!_PyArg_CheckPositional("prlimit", nargs, 2, 3)) {
|
||||||
PyErr_Format(PyExc_TypeError, "prlimit expected at least 2 arguments, got %zd", nargs);
|
|
||||||
goto exit;
|
|
||||||
}
|
|
||||||
if (nargs > 3) {
|
|
||||||
PyErr_Format(PyExc_TypeError, "prlimit expected at most 3 arguments, got %zd", nargs);
|
|
||||||
goto exit;
|
goto exit;
|
||||||
}
|
}
|
||||||
pid = PyLong_AsPid(args[0]);
|
pid = PyLong_AsPid(args[0]);
|
||||||
|
|
@ -178,4 +174,4 @@ exit:
|
||||||
#ifndef RESOURCE_PRLIMIT_METHODDEF
|
#ifndef RESOURCE_PRLIMIT_METHODDEF
|
||||||
#define RESOURCE_PRLIMIT_METHODDEF
|
#define RESOURCE_PRLIMIT_METHODDEF
|
||||||
#endif /* !defined(RESOURCE_PRLIMIT_METHODDEF) */
|
#endif /* !defined(RESOURCE_PRLIMIT_METHODDEF) */
|
||||||
/*[clinic end generated code: output=e45883ace510414a input=a9049054013a1b77]*/
|
/*[clinic end generated code: output=8e905b2f5c35170e input=a9049054013a1b77]*/
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,5 @@
|
||||||
// Need limited C API version 3.13 for PySys_Audit()
|
#ifndef Py_BUILD_CORE_BUILTIN
|
||||||
#include "pyconfig.h" // Py_GIL_DISABLED
|
# define Py_BUILD_CORE_MODULE 1
|
||||||
#ifndef Py_GIL_DISABLED
|
|
||||||
# define Py_LIMITED_API 0x030d0000
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "Python.h"
|
#include "Python.h"
|
||||||
|
|
@ -150,6 +148,35 @@ resource_getrusage_impl(PyObject *module, int who)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
static int
|
||||||
|
py2rlim(PyObject *obj, rlim_t *out)
|
||||||
|
{
|
||||||
|
obj = PyNumber_Index(obj);
|
||||||
|
if (obj == NULL) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
int neg = PyLong_IsNegative(obj);
|
||||||
|
assert(neg >= 0);
|
||||||
|
Py_ssize_t bytes = PyLong_AsNativeBytes(obj, out, sizeof(*out),
|
||||||
|
Py_ASNATIVEBYTES_NATIVE_ENDIAN |
|
||||||
|
Py_ASNATIVEBYTES_UNSIGNED_BUFFER);
|
||||||
|
Py_DECREF(obj);
|
||||||
|
if (bytes < 0) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
else if (neg && (*out != RLIM_INFINITY || bytes > (Py_ssize_t)sizeof(*out))) {
|
||||||
|
PyErr_SetString(PyExc_ValueError,
|
||||||
|
"Cannot convert negative int");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
else if (bytes > (Py_ssize_t)sizeof(*out)) {
|
||||||
|
PyErr_SetString(PyExc_OverflowError,
|
||||||
|
"Python int too large to convert to C rlim_t");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
py2rlimit(PyObject *limits, struct rlimit *rl_out)
|
py2rlimit(PyObject *limits, struct rlimit *rl_out)
|
||||||
{
|
{
|
||||||
|
|
@ -166,26 +193,13 @@ py2rlimit(PyObject *limits, struct rlimit *rl_out)
|
||||||
}
|
}
|
||||||
curobj = PyTuple_GetItem(limits, 0); // borrowed
|
curobj = PyTuple_GetItem(limits, 0); // borrowed
|
||||||
maxobj = PyTuple_GetItem(limits, 1); // borrowed
|
maxobj = PyTuple_GetItem(limits, 1); // borrowed
|
||||||
#if !defined(HAVE_LARGEFILE_SUPPORT)
|
if (py2rlim(curobj, &rl_out->rlim_cur) < 0 ||
|
||||||
rl_out->rlim_cur = PyLong_AsLong(curobj);
|
py2rlim(maxobj, &rl_out->rlim_max) < 0)
|
||||||
if (rl_out->rlim_cur == (rlim_t)-1 && PyErr_Occurred())
|
{
|
||||||
goto error;
|
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);
|
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;
|
return 0;
|
||||||
|
|
||||||
error:
|
error:
|
||||||
|
|
@ -193,15 +207,24 @@ py2rlimit(PyObject *limits, struct rlimit *rl_out)
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static PyObject*
|
||||||
|
rlim2py(rlim_t value)
|
||||||
|
{
|
||||||
|
if (value == RLIM_INFINITY) {
|
||||||
|
return PyLong_FromNativeBytes(&value, sizeof(value), -1);
|
||||||
|
}
|
||||||
|
return PyLong_FromUnsignedNativeBytes(&value, sizeof(value), -1);
|
||||||
|
}
|
||||||
|
|
||||||
static PyObject*
|
static PyObject*
|
||||||
rlimit2py(struct rlimit rl)
|
rlimit2py(struct rlimit rl)
|
||||||
{
|
{
|
||||||
if (sizeof(rl.rlim_cur) > sizeof(long)) {
|
PyObject *cur = rlim2py(rl.rlim_cur);
|
||||||
return Py_BuildValue("LL",
|
if (cur == NULL) {
|
||||||
(long long) rl.rlim_cur,
|
return NULL;
|
||||||
(long long) rl.rlim_max);
|
|
||||||
}
|
}
|
||||||
return Py_BuildValue("ll", (long) rl.rlim_cur, (long) rl.rlim_max);
|
PyObject *max = rlim2py(rl.rlim_max);
|
||||||
|
return Py_BuildValue("NN", cur, max);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*[clinic input]
|
/*[clinic input]
|
||||||
|
|
@ -495,14 +518,7 @@ resource_exec(PyObject *module)
|
||||||
ADD_INT(module, RLIMIT_KQUEUES);
|
ADD_INT(module, RLIMIT_KQUEUES);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
PyObject *v;
|
if (PyModule_Add(module, "RLIM_INFINITY", rlim2py(RLIM_INFINITY)) < 0) {
|
||||||
if (sizeof(RLIM_INFINITY) > sizeof(long)) {
|
|
||||||
v = PyLong_FromLongLong((long long) RLIM_INFINITY);
|
|
||||||
} else
|
|
||||||
{
|
|
||||||
v = PyLong_FromLong((long) RLIM_INFINITY);
|
|
||||||
}
|
|
||||||
if (PyModule_Add(module, "RLIM_INFINITY", v) < 0) {
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue