summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGiampaolo Rodola <g.rodola@gmail.com>2020-10-23 20:57:58 +0300
committerGiampaolo Rodola <g.rodola@gmail.com>2020-10-23 20:57:58 +0300
commitb56ba3e10214d0df7113409923adac1a9b7ab7e8 (patch)
treea60ded4dfbcded036e41c9e8d994d536875a2508
parent02cd86a57443be9d78d98461730aee4ead564df4 (diff)
parent89ae354ab7704db69a3f6c880234d21719558511 (diff)
downloadpsutil-b56ba3e10214d0df7113409923adac1a9b7ab7e8.tar.gz
Merge branch 'master' of github.com:giampaolo/psutil
-rw-r--r--HISTORY.rst3
-rw-r--r--docs/_static/css/custom.css2
-rw-r--r--docs/index.rst85
-rw-r--r--psutil/__init__.py72
-rw-r--r--psutil/_psbsd.py12
-rw-r--r--psutil/_pslinux.py6
-rw-r--r--psutil/_psutil_bsd.c4
-rw-r--r--psutil/_psutil_linux.c43
-rw-r--r--psutil/_psutil_posix.c99
-rw-r--r--psutil/arch/freebsd/specific.c85
-rw-r--r--psutil/arch/freebsd/specific.h2
-rwxr-xr-xpsutil/tests/test_bsd.py1
-rwxr-xr-xpsutil/tests/test_contracts.py30
-rwxr-xr-xpsutil/tests/test_process.py5
-rwxr-xr-xscripts/procinfo.py5
15 files changed, 303 insertions, 151 deletions
diff --git a/HISTORY.rst b/HISTORY.rst
index 1ef5573a..d92dce73 100644
--- a/HISTORY.rst
+++ b/HISTORY.rst
@@ -7,7 +7,8 @@ XXXX-XX-XX
**Enhancements**
-- 893_: implement `Process.environ()` on BSD family. (patch by Armin Gruner)
+- 809_: [FreeBSD] add support for `Process.rlimit()`.
+- 893_: [BSD] add support for `Process.environ()` (patch by Armin Gruner)
- 1830_: [UNIX] `net_if_stats()`'s `isup` also checks whether the NIC is
running (meaning Wi-Fi or ethernet cable is connected). (patch by Chris Burger)
- 1837_: [Linux] improved battery detection and charge "secsleft" calculation
diff --git a/docs/_static/css/custom.css b/docs/_static/css/custom.css
index c5c201e4..e88f5307 100644
--- a/docs/_static/css/custom.css
+++ b/docs/_static/css/custom.css
@@ -4,7 +4,7 @@
}
.rst-content dl:not(.docutils) {
- margin: 0px 0px 0px 0px;
+ margin: 0px 0px 0px 0px !important;
}
.data dd {
diff --git a/docs/index.rst b/docs/index.rst
index 3898f9da..c4ff6a25 100644
--- a/docs/index.rst
+++ b/docs/index.rst
@@ -1348,16 +1348,17 @@ Process class
>>> import psutil
>>> p = psutil.Process()
- >>> # process may open no more than 128 file descriptors
- >>> p.rlimit(psutil.RLIMIT_NOFILE, (128, 128))
- >>> # process may create files no bigger than 1024 bytes
- >>> p.rlimit(psutil.RLIMIT_FSIZE, (1024, 1024))
- >>> # get
- >>> p.rlimit(psutil.RLIMIT_FSIZE)
+ >>> p.rlimit(psutil.RLIMIT_NOFILE, (128, 128)) # process can open max 128 file descriptors
+ >>> p.rlimit(psutil.RLIMIT_FSIZE, (1024, 1024)) # can create files no bigger than 1024 bytes
+ >>> p.rlimit(psutil.RLIMIT_FSIZE) # get
(1024, 1024)
>>>
- Availability: Linux
+ Also see `procinfo.py`_ script.
+
+ Availability: Linux, FreeBSD
+
+ .. versionchanged:: 5.7.3 added FreeBSD support
.. method:: io_counters()
@@ -2247,29 +2248,43 @@ Process priority constants
Process resources constants
---------------------------
-.. data:: RLIM_INFINITY
-.. data:: RLIMIT_AS
-.. data:: RLIMIT_CORE
-.. data:: RLIMIT_CPU
-.. data:: RLIMIT_DATA
-.. data:: RLIMIT_FSIZE
-.. data:: RLIMIT_LOCKS
-.. data:: RLIMIT_MEMLOCK
-.. data:: RLIMIT_MSGQUEUE
-.. data:: RLIMIT_NICE
-.. data:: RLIMIT_NOFILE
-.. data:: RLIMIT_NPROC
-.. data:: RLIMIT_RSS
-.. data:: RLIMIT_RTPRIO
-.. data:: RLIMIT_RTTIME
-.. data:: RLIMIT_SIGPENDING
-.. data:: RLIMIT_STACK
-
- Constants used for getting and setting process resource limits to be used in
- conjunction with :meth:`psutil.Process.rlimit()`. See `man prlimit`_ for
- further information.
+Linux / FreeBSD:
- Availability: Linux
+ .. data:: RLIM_INFINITY
+ .. data:: RLIMIT_AS
+ .. data:: RLIMIT_CORE
+ .. data:: RLIMIT_CPU
+ .. data:: RLIMIT_DATA
+ .. data:: RLIMIT_FSIZE
+ .. data:: RLIMIT_MEMLOCK
+ .. data:: RLIMIT_NOFILE
+ .. data:: RLIMIT_NPROC
+ .. data:: RLIMIT_RSS
+ .. data:: RLIMIT_STACK
+
+Linux specific:
+
+ .. data:: RLIMIT_LOCKS
+ .. data:: RLIMIT_MSGQUEUE
+ .. data:: RLIMIT_NICE
+ .. data:: RLIMIT_RTPRIO
+ .. data:: RLIMIT_RTTIME
+ .. data:: RLIMIT_SIGPENDING
+
+FreeBSD specific:
+
+ .. data:: RLIMIT_SWAP
+ .. data:: RLIMIT_SBSIZE
+ .. data:: RLIMIT_NPTS
+
+Constants used for getting and setting process resource limits to be used in
+conjunction with :meth:`psutil.Process.rlimit()`. See `resource.getrlimit`_
+for further information.
+
+Availability: Linux, FreeBSD
+
+.. versionchanged:: 5.7.3 added FreeBSD support, added ``RLIMIT_SWAP``,
+ ``RLIMIT_SBSIZE``, ``RLIMIT_NPTS``.
Connections constants
---------------------
@@ -2513,11 +2528,6 @@ Security
To report a security vulnerability, please use the `Tidelift security
contact`_. Tidelift will coordinate the fix and disclosure.
-.. _`Giampaolo Rodola`: https://gmpy.dev/about
-.. _`donation`: https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=A9ZS7PKKRM3S8
-.. _Tidelift security contact: https://tidelift.com/security
-.. _Tidelift Subscription: https://tidelift.com/subscription/pkg/pypi-psutil?utm_source=pypi-psutil&utm_medium=referral&utm_campaign=readme
-
Development guide
=================
@@ -2874,13 +2884,12 @@ Timeline
.. _`cpu_distribution.py`: https://github.com/giampaolo/psutil/blob/master/scripts/cpu_distribution.py
.. _`development guide`: https://github.com/giampaolo/psutil/blob/master/docs/DEVGUIDE.rst
.. _`disk_usage.py`: https://github.com/giampaolo/psutil/blob/master/scripts/disk_usage.py
-.. _`donation`: https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=A9ZS7PKKRM3S8
.. _`enum`: https://docs.python.org/3/library/enum.html#module-enum
.. _`fans.py`: https://github.com/giampaolo/psutil/blob/master/scripts/fans.py
.. _`GetDriveType`: https://docs.microsoft.com/en-us/windows/desktop/api/fileapi/nf-fileapi-getdrivetypea
+.. _`GetExitCodeProcess`: https://docs.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-getexitcodeprocess
.. _`getfsstat`: http://www.manpagez.com/man/2/getfsstat/
.. _`GetPriorityClass`: https://docs.microsoft.com/en-us/windows/desktop/api/processthreadsapi/nf-processthreadsapi-getpriorityclass
-.. _`GetExitCodeProcess`: https://docs.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-getexitcodeprocess
.. _`Giampaolo Rodola`: https://gmpy.dev/about
.. _`hash`: https://docs.python.org/3/library/functions.html#hash
.. _`ifconfig.py`: https://github.com/giampaolo/psutil/blob/master/scripts/ifconfig.py
@@ -2908,6 +2917,7 @@ Timeline
.. _`os.times`: https://docs.python.org//library/os.html#os.times
.. _`pmap.py`: https://github.com/giampaolo/psutil/blob/master/scripts/pmap.py
.. _`PROCESS_MEMORY_COUNTERS_EX`: https://docs.microsoft.com/en-us/windows/desktop/api/psapi/ns-psapi-_process_memory_counters_ex
+.. _`procinfo.py`: https://github.com/giampaolo/psutil/blob/master/scripts/procinfo.py
.. _`procsmem.py`: https://github.com/giampaolo/psutil/blob/master/scripts/procsmem.py
.. _`resource.getrlimit`: https://docs.python.org/3/library/resource.html#resource.getrlimit
.. _`resource.setrlimit`: https://docs.python.org/3/library/resource.html#resource.setrlimit
@@ -2920,9 +2930,10 @@ Timeline
.. _`SOCK_SEQPACKET`: https://docs.python.org/3/library/socket.html#socket.SOCK_SEQPACKET
.. _`SOCK_STREAM`: https://docs.python.org/3/library/socket.html#socket.SOCK_STREAM
.. _`socket.fromfd`: https://docs.python.org/3/library/socket.html#socket.fromfd
-.. _`subprocess.Popen`: https://docs.python.org/3/library/subprocess.html#subprocess.Popen
.. _`subprocess.Popen.wait`: https://docs.python.org/3/library/subprocess.html#subprocess.Popen.wait
+.. _`subprocess.Popen`: https://docs.python.org/3/library/subprocess.html#subprocess.Popen
.. _`temperatures.py`: https://github.com/giampaolo/psutil/blob/master/scripts/temperatures.py
.. _`TerminateProcess`: https://docs.microsoft.com/en-us/windows/desktop/api/processthreadsapi/nf-processthreadsapi-terminateprocess
.. _Tidelift security contact: https://tidelift.com/security
.. _Tidelift Subscription: https://tidelift.com/subscription/pkg/pypi-psutil?utm_source=pypi-psutil&utm_medium=referral&utm_campaign=readme
+.. _Tidelift Subscription: https://tidelift.com/subscription/pkg/pypi-psutil?utm_source=pypi-psutil&utm_medium=referral&utm_campaign=readme
diff --git a/psutil/__init__.py b/psutil/__init__.py
index 2108a40e..cc4e79cc 100644
--- a/psutil/__init__.py
+++ b/psutil/__init__.py
@@ -102,44 +102,6 @@ if LINUX:
from ._pslinux import IOPRIO_CLASS_IDLE # NOQA
from ._pslinux import IOPRIO_CLASS_NONE # NOQA
from ._pslinux import IOPRIO_CLASS_RT # NOQA
- # Linux >= 2.6.36
- if _psplatform.HAS_PRLIMIT:
- from ._psutil_linux import RLIM_INFINITY # NOQA
- from ._psutil_linux import RLIMIT_AS # NOQA
- from ._psutil_linux import RLIMIT_CORE # NOQA
- from ._psutil_linux import RLIMIT_CPU # NOQA
- from ._psutil_linux import RLIMIT_DATA # NOQA
- from ._psutil_linux import RLIMIT_FSIZE # NOQA
- from ._psutil_linux import RLIMIT_LOCKS # NOQA
- from ._psutil_linux import RLIMIT_MEMLOCK # NOQA
- from ._psutil_linux import RLIMIT_NOFILE # NOQA
- from ._psutil_linux import RLIMIT_NPROC # NOQA
- from ._psutil_linux import RLIMIT_RSS # NOQA
- from ._psutil_linux import RLIMIT_STACK # NOQA
- # Kinda ugly but considerably faster than using hasattr() and
- # setattr() against the module object (we are at import time:
- # speed matters).
- from . import _psutil_linux
- try:
- RLIMIT_MSGQUEUE = _psutil_linux.RLIMIT_MSGQUEUE
- except AttributeError:
- pass
- try:
- RLIMIT_NICE = _psutil_linux.RLIMIT_NICE
- except AttributeError:
- pass
- try:
- RLIMIT_RTPRIO = _psutil_linux.RLIMIT_RTPRIO
- except AttributeError:
- pass
- try:
- RLIMIT_RTTIME = _psutil_linux.RLIMIT_RTTIME
- except AttributeError:
- pass
- try:
- RLIMIT_SIGPENDING = _psutil_linux.RLIMIT_SIGPENDING
- except AttributeError:
- pass
elif WINDOWS:
from . import _pswindows as _psplatform
@@ -197,6 +159,7 @@ __all__ = [
"CONN_ESTABLISHED", "CONN_SYN_SENT", "CONN_SYN_RECV", "CONN_FIN_WAIT1",
"CONN_FIN_WAIT2", "CONN_TIME_WAIT", "CONN_CLOSE", "CONN_CLOSE_WAIT",
"CONN_LAST_ACK", "CONN_LISTEN", "CONN_CLOSING", "CONN_NONE",
+ # "CONN_IDLE", "CONN_BOUND",
"AF_LINK",
@@ -207,6 +170,11 @@ __all__ = [
"BSD", "FREEBSD", "LINUX", "NETBSD", "OPENBSD", "MACOS", "OSX", "POSIX",
"SUNOS", "WINDOWS", "AIX",
+ # "RLIM_INFINITY", "RLIMIT_AS", "RLIMIT_CORE", "RLIMIT_CPU", "RLIMIT_DATA",
+ # "RLIMIT_FSIZE", "RLIMIT_LOCKS", "RLIMIT_MEMLOCK", "RLIMIT_NOFILE",
+ # "RLIMIT_NPROC", "RLIMIT_RSS", "RLIMIT_STACK", "RLIMIT_MSGQUEUE",
+ # "RLIMIT_NICE", "RLIMIT_RTPRIO", "RLIMIT_RTTIME", "RLIMIT_SIGPENDING",
+
# classes
"Process", "Popen",
@@ -222,9 +190,22 @@ __all__ = [
"users", "boot_time", # others
]
+__all__.extend(_psplatform.__extra__all__)
+
+if LINUX or FREEBSD:
+ # Populate global namespace with RLIM* constants.
+ from . import _psutil_posix
+
+ _globals = globals()
+ _name = None
+ for _name in dir(_psutil_posix):
+ if _name.startswith('RLIM') and _name.isupper():
+ _globals[_name] = getattr(_psutil_posix, _name)
+ __all__.append(_name)
+ del _globals, _name
+
AF_LINK = _psplatform.AF_LINK
-__all__.extend(_psplatform.__extra__all__)
__author__ = "Giampaolo Rodola'"
__version__ = "5.7.3"
version_info = tuple([int(num) for num in __version__.split('.')])
@@ -801,7 +782,7 @@ class Process(object):
else:
return self._proc.ionice_set(ioclass, value)
- # Linux only
+ # Linux / FreeBSD only
if hasattr(_psplatform.Process, "rlimit"):
def rlimit(self, resource, limits=None):
@@ -809,15 +790,12 @@ class Process(object):
tuple.
*resource* is one of the RLIMIT_* constants.
- *limits* is supposed to be a (soft, hard) tuple.
+ *limits* is supposed to be a (soft, hard) tuple.
See "man prlimit" for further info.
- Available on Linux only.
+ Available on Linux and FreeBSD only.
"""
- if limits is None:
- return self._proc.rlimit(resource)
- else:
- return self._proc.rlimit(resource, limits)
+ return self._proc.rlimit(resource, limits)
# Windows, Linux and FreeBSD only
if hasattr(_psplatform.Process, "cpu_affinity_get"):
@@ -831,7 +809,7 @@ class Process(object):
(Windows, Linux and BSD only).
"""
if cpus is None:
- return list(set(self._proc.cpu_affinity_get()))
+ return sorted(set(self._proc.cpu_affinity_get()))
else:
if not cpus:
if hasattr(self._proc, "_get_eligible_cpus"):
diff --git a/psutil/_psbsd.py b/psutil/_psbsd.py
index 9565406b..428c8bde 100644
--- a/psutil/_psbsd.py
+++ b/psutil/_psbsd.py
@@ -904,3 +904,15 @@ class Process(object):
@wrap_exceptions
def memory_maps(self):
return cext.proc_memory_maps(self.pid)
+
+ @wrap_exceptions
+ def rlimit(self, resource, limits=None):
+ if limits is None:
+ return cext.proc_getrlimit(self.pid, resource)
+ else:
+ if len(limits) != 2:
+ raise ValueError(
+ "second argument must be a (soft, hard) tuple, "
+ "got %s" % repr(limits))
+ soft, hard = limits
+ return cext.proc_setrlimit(self.pid, resource, soft, hard)
diff --git a/psutil/_pslinux.py b/psutil/_pslinux.py
index d5ce358c..683cef5d 100644
--- a/psutil/_pslinux.py
+++ b/psutil/_pslinux.py
@@ -80,12 +80,6 @@ HAS_PROC_IO_PRIORITY = hasattr(cext, "proc_ioprio_get")
HAS_CPU_AFFINITY = hasattr(cext, "proc_cpu_affinity_get")
_DEFAULT = object()
-# RLIMIT_* constants, not guaranteed to be present on all kernels
-if HAS_PRLIMIT:
- for name in dir(cext):
- if name.startswith('RLIM'):
- __extra__all__.append(name)
-
# Number of clock ticks per second
CLOCK_TICKS = os.sysconf("SC_CLK_TCK")
PAGESIZE = os.sysconf("SC_PAGE_SIZE")
diff --git a/psutil/_psutil_bsd.c b/psutil/_psutil_bsd.c
index c4450d7d..6933260a 100644
--- a/psutil/_psutil_bsd.c
+++ b/psutil/_psutil_bsd.c
@@ -1097,6 +1097,10 @@ static PyMethodDef mod_methods[] = {
"Return process CPU affinity."},
{"proc_cpu_affinity_set", psutil_proc_cpu_affinity_set, METH_VARARGS,
"Set process CPU affinity."},
+ {"proc_getrlimit", psutil_proc_getrlimit, METH_VARARGS,
+ "Get process resource limits."},
+ {"proc_setrlimit", psutil_proc_setrlimit, METH_VARARGS,
+ "Set process resource limits."},
{"cpu_count_phys", psutil_cpu_count_phys, METH_VARARGS,
"Return an XML string to determine the number physical CPUs."},
#endif
diff --git a/psutil/_psutil_linux.c b/psutil/_psutil_linux.c
index 41547438..4def9692 100644
--- a/psutil/_psutil_linux.c
+++ b/psutil/_psutil_linux.c
@@ -606,7 +606,6 @@ static PyMethodDef mod_methods[] = {
void init_psutil_linux(void)
#endif /* PY_MAJOR_VERSION */
{
- PyObject *v;
#if PY_MAJOR_VERSION >= 3
PyObject *mod = PyModule_Create(&moduledef);
#else
@@ -616,48 +615,6 @@ static PyMethodDef mod_methods[] = {
INITERR;
if (PyModule_AddIntConstant(mod, "version", PSUTIL_VERSION)) INITERR;
-#if PSUTIL_HAVE_PRLIMIT
- if (PyModule_AddIntConstant(mod, "RLIMIT_AS", RLIMIT_AS)) INITERR;
- if (PyModule_AddIntConstant(mod, "RLIMIT_CORE", RLIMIT_CORE)) INITERR;
- if (PyModule_AddIntConstant(mod, "RLIMIT_CPU", RLIMIT_CPU)) INITERR;
- if (PyModule_AddIntConstant(mod, "RLIMIT_DATA", RLIMIT_DATA)) INITERR;
- if (PyModule_AddIntConstant(mod, "RLIMIT_FSIZE", RLIMIT_FSIZE)) INITERR;
- if (PyModule_AddIntConstant(mod, "RLIMIT_LOCKS", RLIMIT_LOCKS)) INITERR;
- if (PyModule_AddIntConstant(mod, "RLIMIT_MEMLOCK", RLIMIT_MEMLOCK)) INITERR;
- if (PyModule_AddIntConstant(mod, "RLIMIT_NOFILE", RLIMIT_NOFILE)) INITERR;
- if (PyModule_AddIntConstant(mod, "RLIMIT_NPROC", RLIMIT_NPROC)) INITERR;
- if (PyModule_AddIntConstant(mod, "RLIMIT_RSS", RLIMIT_RSS)) INITERR;
- if (PyModule_AddIntConstant(mod, "RLIMIT_STACK", RLIMIT_STACK)) INITERR;
-
-#if defined(HAVE_LONG_LONG)
- if (sizeof(RLIM_INFINITY) > sizeof(long)) {
- v = PyLong_FromLongLong((PY_LONG_LONG) RLIM_INFINITY);
- } else
-#endif
- {
- v = PyLong_FromLong((long) RLIM_INFINITY);
- }
- if (v) {
- PyModule_AddObject(mod, "RLIM_INFINITY", v);
- }
-
-#ifdef RLIMIT_MSGQUEUE
- if (PyModule_AddIntConstant(mod, "RLIMIT_MSGQUEUE", RLIMIT_MSGQUEUE)) INITERR;
-#endif
-#ifdef RLIMIT_NICE
- if (PyModule_AddIntConstant(mod, "RLIMIT_NICE", RLIMIT_NICE)) INITERR;
-#endif
-#ifdef RLIMIT_RTPRIO
- if (PyModule_AddIntConstant(mod, "RLIMIT_RTPRIO", RLIMIT_RTPRIO)) INITERR;
-#endif
-#ifdef RLIMIT_RTTIME
- if (PyModule_AddIntConstant(mod, "RLIMIT_RTTIME", RLIMIT_RTTIME)) INITERR;
-#endif
-#ifdef RLIMIT_SIGPENDING
- if (PyModule_AddIntConstant(mod, "RLIMIT_SIGPENDING", RLIMIT_SIGPENDING))
- INITERR;
-#endif
-#endif
if (PyModule_AddIntConstant(mod, "DUPLEX_HALF", DUPLEX_HALF)) INITERR;
if (PyModule_AddIntConstant(mod, "DUPLEX_FULL", DUPLEX_FULL)) INITERR;
if (PyModule_AddIntConstant(mod, "DUPLEX_UNKNOWN", DUPLEX_UNKNOWN)) INITERR;
diff --git a/psutil/_psutil_posix.c b/psutil/_psutil_posix.c
index 1182765d..876b4129 100644
--- a/psutil/_psutil_posix.c
+++ b/psutil/_psutil_posix.c
@@ -41,6 +41,9 @@
#elif defined(PSUTIL_AIX)
#include <netdb.h>
#endif
+#if defined(PSUTIL_LINUX) || defined(PSUTIL_FREEBSD)
+ #include <sys/resource.h>
+#endif
#include "_psutil_common.h"
@@ -668,6 +671,102 @@ static PyMethodDef mod_methods[] = {
if (PyModule_AddIntConstant(mod, "AF_LINK", AF_LINK)) INITERR;
#endif
+#if defined(PSUTIL_LINUX) || defined(PSUTIL_FREEBSD)
+ PyObject *v;
+
+#ifdef RLIMIT_AS
+ if (PyModule_AddIntConstant(mod, "RLIMIT_AS", RLIMIT_AS)) INITERR;
+#endif
+
+#ifdef RLIMIT_CORE
+ if (PyModule_AddIntConstant(mod, "RLIMIT_CORE", RLIMIT_CORE)) INITERR;
+#endif
+
+#ifdef RLIMIT_CPU
+ if (PyModule_AddIntConstant(mod, "RLIMIT_CPU", RLIMIT_CPU)) INITERR;
+#endif
+
+#ifdef RLIMIT_DATA
+ if (PyModule_AddIntConstant(mod, "RLIMIT_DATA", RLIMIT_DATA)) INITERR;
+#endif
+
+#ifdef RLIMIT_FSIZE
+ if (PyModule_AddIntConstant(mod, "RLIMIT_FSIZE", RLIMIT_FSIZE)) INITERR;
+#endif
+
+#ifdef RLIMIT_MEMLOCK
+ if (PyModule_AddIntConstant(mod, "RLIMIT_MEMLOCK", RLIMIT_MEMLOCK)) INITERR;
+#endif
+
+#ifdef RLIMIT_NOFILE
+ if (PyModule_AddIntConstant(mod, "RLIMIT_NOFILE", RLIMIT_NOFILE)) INITERR;
+#endif
+
+#ifdef RLIMIT_NPROC
+ if (PyModule_AddIntConstant(mod, "RLIMIT_NPROC", RLIMIT_NPROC)) INITERR;
+#endif
+
+#ifdef RLIMIT_RSS
+ if (PyModule_AddIntConstant(mod, "RLIMIT_RSS", RLIMIT_RSS)) INITERR;
+#endif
+
+#ifdef RLIMIT_STACK
+ if (PyModule_AddIntConstant(mod, "RLIMIT_STACK", RLIMIT_STACK)) INITERR;
+#endif
+
+// Linux specific
+
+#ifdef RLIMIT_LOCKS
+ if (PyModule_AddIntConstant(mod, "RLIMIT_LOCKS", RLIMIT_LOCKS)) INITERR;
+#endif
+
+#ifdef RLIMIT_MSGQUEUE
+ if (PyModule_AddIntConstant(mod, "RLIMIT_MSGQUEUE", RLIMIT_MSGQUEUE)) INITERR;
+#endif
+
+#ifdef RLIMIT_NICE
+ if (PyModule_AddIntConstant(mod, "RLIMIT_NICE", RLIMIT_NICE)) INITERR;
+#endif
+
+#ifdef RLIMIT_RTPRIO
+ if (PyModule_AddIntConstant(mod, "RLIMIT_RTPRIO", RLIMIT_RTPRIO)) INITERR;
+#endif
+
+#ifdef RLIMIT_RTTIME
+ if (PyModule_AddIntConstant(mod, "RLIMIT_RTTIME", RLIMIT_RTTIME)) INITERR;
+#endif
+
+#ifdef RLIMIT_SIGPENDING
+ if (PyModule_AddIntConstant(mod, "RLIMIT_SIGPENDING", RLIMIT_SIGPENDING)) INITERR;
+#endif
+
+// Free specific
+
+#ifdef RLIMIT_SWAP
+ if (PyModule_AddIntConstant(mod, "RLIMIT_SWAP", RLIMIT_SWAP)) INITERR;
+#endif
+
+#ifdef RLIMIT_SBSIZE
+ if (PyModule_AddIntConstant(mod, "RLIMIT_SBSIZE", RLIMIT_SBSIZE)) INITERR;
+#endif
+
+#ifdef RLIMIT_NPTS
+ if (PyModule_AddIntConstant(mod, "RLIMIT_NPTS", RLIMIT_NPTS)) INITERR;
+#endif
+
+#if defined(HAVE_LONG_LONG)
+ if (sizeof(RLIM_INFINITY) > sizeof(long)) {
+ v = PyLong_FromLongLong((PY_LONG_LONG) RLIM_INFINITY);
+ } else
+#endif
+ {
+ v = PyLong_FromLong((long) RLIM_INFINITY);
+ }
+ if (v) {
+ PyModule_AddObject(mod, "RLIM_INFINITY", v);
+ }
+#endif // defined(PSUTIL_LINUX) || defined(PSUTIL_FREEBSD)
+
if (mod == NULL)
INITERR;
#if PY_MAJOR_VERSION >= 3
diff --git a/psutil/arch/freebsd/specific.c b/psutil/arch/freebsd/specific.c
index c7832647..fcfce131 100644
--- a/psutil/arch/freebsd/specific.c
+++ b/psutil/arch/freebsd/specific.c
@@ -1077,3 +1077,88 @@ error:
PyErr_SetFromErrno(PyExc_OSError);
return NULL;
}
+
+
+/*
+ * An emulation of Linux prlimit(). Returns a (soft, hard) tuple.
+ */
+PyObject *
+psutil_proc_getrlimit(PyObject *self, PyObject *args) {
+ pid_t pid;
+ int ret;
+ int resource;
+ size_t len;
+ int name[5];
+ struct rlimit rlp;
+
+ if (! PyArg_ParseTuple(args, _Py_PARSE_PID "i", &pid, &resource))
+ return NULL;
+
+ name[0] = CTL_KERN;
+ name[1] = KERN_PROC;
+ name[2] = KERN_PROC_RLIMIT;
+ name[3] = pid;
+ name[4] = resource;
+ len = sizeof(rlp);
+
+ ret = sysctl(name, 5, &rlp, &len, NULL, 0);
+ if (ret == -1)
+ return PyErr_SetFromErrno(PyExc_OSError);
+
+#if defined(HAVE_LONG_LONG)
+ return Py_BuildValue("LL",
+ (PY_LONG_LONG) rlp.rlim_cur,
+ (PY_LONG_LONG) rlp.rlim_max);
+#else
+ return Py_BuildValue("ll",
+ (long) rlp.rlim_cur,
+ (long) rlp.rlim_max);
+#endif
+}
+
+
+/*
+ * An emulation of Linux prlimit() (set).
+ */
+PyObject *
+psutil_proc_setrlimit(PyObject *self, PyObject *args) {
+ pid_t pid;
+ int ret;
+ int resource;
+ int name[5];
+ struct rlimit new;
+ struct rlimit *newp = NULL;
+ PyObject *py_soft = NULL;
+ PyObject *py_hard = NULL;
+
+ if (! PyArg_ParseTuple(
+ args, _Py_PARSE_PID "iOO", &pid, &resource, &py_soft, &py_hard))
+ return NULL;
+
+ name[0] = CTL_KERN;
+ name[1] = KERN_PROC;
+ name[2] = KERN_PROC_RLIMIT;
+ name[3] = pid;
+ name[4] = resource;
+
+#if defined(HAVE_LONG_LONG)
+ new.rlim_cur = PyLong_AsLongLong(py_soft);
+ if (new.rlim_cur == (rlim_t) - 1 && PyErr_Occurred())
+ return NULL;
+ new.rlim_max = PyLong_AsLongLong(py_hard);
+ if (new.rlim_max == (rlim_t) - 1 && PyErr_Occurred())
+ return NULL;
+#else
+ new.rlim_cur = PyLong_AsLong(py_soft);
+ if (new.rlim_cur == (rlim_t) - 1 && PyErr_Occurred())
+ return NULL;
+ new.rlim_max = PyLong_AsLong(py_hard);
+ if (new.rlim_max == (rlim_t) - 1 && PyErr_Occurred())
+ return NULL;
+#endif
+ newp = &new;
+ ret = sysctl(name, 5, NULL, 0, newp, sizeof(*newp));
+ if (ret == -1)
+ return PyErr_SetFromErrno(PyExc_OSError);
+ Py_RETURN_NONE;
+}
diff --git a/psutil/arch/freebsd/specific.h b/psutil/arch/freebsd/specific.h
index 875c8166..61c3f07b 100644
--- a/psutil/arch/freebsd/specific.h
+++ b/psutil/arch/freebsd/specific.h
@@ -24,6 +24,8 @@ PyObject* psutil_proc_memory_maps(PyObject* self, PyObject* args);
PyObject* psutil_proc_num_fds(PyObject* self, PyObject* args);
PyObject* psutil_proc_num_threads(PyObject* self, PyObject* args);
PyObject* psutil_proc_threads(PyObject* self, PyObject* args);
+PyObject* psutil_proc_getrlimit(PyObject* self, PyObject* args);
+PyObject* psutil_proc_setrlimit(PyObject* self, PyObject* args);
PyObject* psutil_swap_mem(PyObject* self, PyObject* args);
PyObject* psutil_virtual_mem(PyObject* self, PyObject* args);
PyObject* psutil_cpu_stats(PyObject* self, PyObject* args);
diff --git a/psutil/tests/test_bsd.py b/psutil/tests/test_bsd.py
index c91ee3a5..06a65087 100755
--- a/psutil/tests/test_bsd.py
+++ b/psutil/tests/test_bsd.py
@@ -474,6 +474,7 @@ class FreeBSDSystemTestCase(PsutilTestCase):
psutil.sensors_temperatures()["coretemp"][cpu].high,
sysctl_result)
+
# =====================================================================
# --- OpenBSD
# =====================================================================
diff --git a/psutil/tests/test_contracts.py b/psutil/tests/test_contracts.py
index 2d9e5917..39a52569 100755
--- a/psutil/tests/test_contracts.py
+++ b/psutil/tests/test_contracts.py
@@ -89,25 +89,29 @@ class TestAvailConstantsAPIs(PsutilTestCase):
@unittest.skipIf(GITHUB_WHEELS, "not exposed via GITHUB_WHEELS")
def test_linux_rlimit(self):
ae = self.assertEqual
- ae(hasattr(psutil, "RLIM_INFINITY"), LINUX)
- ae(hasattr(psutil, "RLIMIT_AS"), LINUX)
- ae(hasattr(psutil, "RLIMIT_CORE"), LINUX)
- ae(hasattr(psutil, "RLIMIT_CPU"), LINUX)
- ae(hasattr(psutil, "RLIMIT_DATA"), LINUX)
- ae(hasattr(psutil, "RLIMIT_FSIZE"), LINUX)
- ae(hasattr(psutil, "RLIMIT_LOCKS"), LINUX)
- ae(hasattr(psutil, "RLIMIT_MEMLOCK"), LINUX)
- ae(hasattr(psutil, "RLIMIT_NOFILE"), LINUX)
- ae(hasattr(psutil, "RLIMIT_NPROC"), LINUX)
- ae(hasattr(psutil, "RLIMIT_RSS"), LINUX)
- ae(hasattr(psutil, "RLIMIT_STACK"), LINUX)
+ ae(hasattr(psutil, "RLIM_INFINITY"), LINUX or FREEBSD)
+ ae(hasattr(psutil, "RLIMIT_AS"), LINUX or FREEBSD)
+ ae(hasattr(psutil, "RLIMIT_CORE"), LINUX or FREEBSD)
+ ae(hasattr(psutil, "RLIMIT_CPU"), LINUX or FREEBSD)
+ ae(hasattr(psutil, "RLIMIT_DATA"), LINUX or FREEBSD)
+ ae(hasattr(psutil, "RLIMIT_FSIZE"), LINUX or FREEBSD)
+ ae(hasattr(psutil, "RLIMIT_MEMLOCK"), LINUX or FREEBSD)
+ ae(hasattr(psutil, "RLIMIT_NOFILE"), LINUX or FREEBSD)
+ ae(hasattr(psutil, "RLIMIT_NPROC"), LINUX or FREEBSD)
+ ae(hasattr(psutil, "RLIMIT_RSS"), LINUX or FREEBSD)
+ ae(hasattr(psutil, "RLIMIT_STACK"), LINUX or FREEBSD)
+ ae(hasattr(psutil, "RLIMIT_LOCKS"), LINUX)
ae(hasattr(psutil, "RLIMIT_MSGQUEUE"), LINUX) # requires Linux 2.6.8
ae(hasattr(psutil, "RLIMIT_NICE"), LINUX) # requires Linux 2.6.12
ae(hasattr(psutil, "RLIMIT_RTPRIO"), LINUX) # requires Linux 2.6.12
ae(hasattr(psutil, "RLIMIT_RTTIME"), LINUX) # requires Linux 2.6.25
ae(hasattr(psutil, "RLIMIT_SIGPENDING"), LINUX) # requires Linux 2.6.8
+ ae(hasattr(psutil, "RLIMIT_SWAP"), FREEBSD)
+ ae(hasattr(psutil, "RLIMIT_SBSIZE"), FREEBSD)
+ ae(hasattr(psutil, "RLIMIT_NPTS"), FREEBSD)
+
class TestAvailSystemAPIs(PsutilTestCase):
@@ -155,7 +159,7 @@ class TestAvailProcessAPIs(PsutilTestCase):
@unittest.skipIf(GITHUB_WHEELS, "not exposed via GITHUB_WHEELS")
def test_rlimit(self):
# requires Linux 2.6.36
- self.assertEqual(hasattr(psutil.Process, "rlimit"), LINUX)
+ self.assertEqual(hasattr(psutil.Process, "rlimit"), LINUX or FREEBSD)
def test_io_counters(self):
hasit = hasattr(psutil.Process, "io_counters")
diff --git a/psutil/tests/test_process.py b/psutil/tests/test_process.py
index b2328ba2..0d63979b 100755
--- a/psutil/tests/test_process.py
+++ b/psutil/tests/test_process.py
@@ -448,8 +448,9 @@ class TestProcess(PsutilTestCase):
self.assertEqual(p.rlimit(psutil.RLIMIT_NOFILE), (5, 5))
# If pid is 0 prlimit() applies to the calling process and
# we don't want that.
- with self.assertRaises(ValueError):
- psutil._psplatform.Process(0).rlimit(0)
+ if LINUX:
+ with self.assertRaisesRegex(ValueError, "can't use prlimit"):
+ psutil._psplatform.Process(0).rlimit(0)
with self.assertRaises(ValueError):
p.rlimit(psutil.RLIMIT_NOFILE, (5, 5, 5))
diff --git a/scripts/procinfo.py b/scripts/procinfo.py
index f0605386..8eea3377 100755
--- a/scripts/procinfo.py
+++ b/scripts/procinfo.py
@@ -108,11 +108,14 @@ RLIMITS_MAP = {
"RLIMIT_NICE": "nice",
"RLIMIT_NOFILE": "openfiles",
"RLIMIT_NPROC": "maxprocesses",
+ "RLIMIT_NPTS": "pseudoterms",
"RLIMIT_RSS": "rss",
"RLIMIT_RTPRIO": "realtimeprio",
"RLIMIT_RTTIME": "rtimesched",
+ "RLIMIT_SBSIZE": "sockbufsize",
"RLIMIT_SIGPENDING": "sigspending",
"RLIMIT_STACK": "stack",
+ "RLIMIT_SWAP": "swapuse",
}
@@ -317,7 +320,7 @@ def run(pid, verbose=False):
def main(argv=None):
parser = argparse.ArgumentParser(
description="print information about a process")
- parser.add_argument("pid", type=int, help="process pid")
+ parser.add_argument("pid", type=int, help="process pid", nargs='?')
parser.add_argument('--verbose', '-v', action='store_true',
help="print more info")
args = parser.parse_args()