summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGiampaolo Rodola <g.rodola@gmail.com>2020-11-11 01:08:21 +0100
committerGiampaolo Rodola <g.rodola@gmail.com>2020-11-11 01:08:21 +0100
commit7050e73c48b38caf2f19409167ba8dfaa9ab9fd4 (patch)
tree9e9d2dfbfbafba8e0dc31b50dd3b67dc6c881b93
parent1e8fdf27eff0a19a9d68e24973bc76d8a953654a (diff)
downloadpsutil-7050e73c48b38caf2f19409167ba8dfaa9ab9fd4.tar.gz
OSX: put sysctl() + KERN_PROCARGS2 in its own function
-rw-r--r--psutil/arch/osx/process_info.c88
-rw-r--r--psutil/arch/osx/process_info.h1
-rwxr-xr-xpsutil/tests/test_process.py19
-rwxr-xr-xpsutil/tests/test_system.py10
-rwxr-xr-xpsutil/tests/test_unicode.py2
5 files changed, 57 insertions, 63 deletions
diff --git a/psutil/arch/osx/process_info.c b/psutil/arch/osx/process_info.c
index f83cfe47..51df3483 100644
--- a/psutil/arch/osx/process_info.c
+++ b/psutil/arch/osx/process_info.c
@@ -9,13 +9,7 @@
#include <Python.h>
-#include <assert.h>
#include <errno.h>
-#include <limits.h> // for INT_MAX
-#include <stdbool.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <signal.h>
#include <sys/sysctl.h>
#include <libproc.h>
@@ -23,6 +17,7 @@
#include "../../_psutil_posix.h"
#include "process_info.h"
+
/*
* Returns a list of all BSD processes on the system. This routine
* allocates the list and puts it in *procList and a count of the
@@ -33,16 +28,15 @@
*/
int
psutil_get_proc_list(kinfo_proc **procList, size_t *procCount) {
- int mib3[3] = { CTL_KERN, KERN_PROC, KERN_PROC_ALL };
+ int mib[3];
size_t size, size2;
void *ptr;
int err;
int lim = 8; // some limit
- assert( procList != NULL);
- assert(*procList == NULL);
- assert(procCount != NULL);
-
+ mib[0] = CTL_KERN;
+ mib[1] = KERN_PROC;
+ mib[2] = KERN_PROC_ALL;
*procCount = 0;
/*
@@ -59,7 +53,7 @@ psutil_get_proc_list(kinfo_proc **procList, size_t *procCount) {
*/
while (lim-- > 0) {
size = 0;
- if (sysctl((int *)mib3, 3, NULL, &size, NULL, 0) == -1) {
+ if (sysctl((int *)mib, 3, NULL, &size, NULL, 0) == -1) {
PyErr_SetFromOSErrnoWithSyscall("sysctl(KERN_PROC_ALL)");
return 1;
}
@@ -79,7 +73,7 @@ psutil_get_proc_list(kinfo_proc **procList, size_t *procCount) {
return 1;
}
- if (sysctl((int *)mib3, 3, ptr, &size, NULL, 0) == -1) {
+ if (sysctl((int *)mib, 3, ptr, &size, NULL, 0) == -1) {
err = errno;
free(ptr);
if (err != ENOMEM) {
@@ -104,12 +98,15 @@ psutil_get_proc_list(kinfo_proc **procList, size_t *procCount) {
// Read the maximum argument size for processes
-int
-psutil_get_argmax() {
+static int
+psutil_sysctl_argmax() {
int argmax;
- int mib[] = { CTL_KERN, KERN_ARGMAX };
+ int mib[2];
size_t size = sizeof(argmax);
+ mib[0] = CTL_KERN;
+ mib[1] = KERN_ARGMAX;
+
if (sysctl(mib, 2, &argmax, &size, NULL, 0) == 0)
return argmax;
PyErr_SetFromOSErrnoWithSyscall("sysctl(KERN_ARGMAX)");
@@ -117,6 +114,32 @@ psutil_get_argmax() {
}
+// Read process argument space.
+static int
+psutil_sysctl_procargs(pid_t pid, char *procargs, size_t argmax) {
+ int mib[3];
+
+ mib[0] = CTL_KERN;
+ mib[1] = KERN_PROCARGS2;
+ mib[2] = pid;
+
+ if (sysctl(mib, 3, procargs, &argmax, NULL, 0) < 0) {
+ // In case of zombie process we'll get EINVAL. We translate it
+ // to NSP and _psosx.py will translate it to ZP.
+ if ((errno == EINVAL) && (psutil_pid_exists(pid)))
+ NoSuchProcess("sysctl");
+ else if (errno == EIO) {
+ psutil_debug("EIO, pid_exists() = %i\n", psutil_pid_exists(pid));
+ PyErr_SetFromOSErrnoWithSyscall("sysctl(KERN_PROCARGS2)");
+ }
+ else
+ PyErr_SetFromOSErrnoWithSyscall("sysctl(KERN_PROCARGS2)");
+ return 1;
+ }
+ return 0;
+}
+
+
// Return 1 if pid refers to a zombie process else 0.
int
psutil_is_zombie(pid_t pid) {
@@ -128,11 +151,9 @@ psutil_is_zombie(pid_t pid) {
}
-
// return process args as a python list
PyObject *
psutil_get_cmdline(pid_t pid) {
- int mib[3];
int nargs;
size_t len;
char *procargs = NULL;
@@ -149,7 +170,7 @@ psutil_get_cmdline(pid_t pid) {
return Py_BuildValue("[]");
// read argmax and allocate memory for argument space.
- argmax = psutil_get_argmax();
+ argmax = psutil_sysctl_argmax();
if (! argmax)
goto error;
@@ -159,19 +180,8 @@ psutil_get_cmdline(pid_t pid) {
goto error;
}
- // read argument space
- mib[0] = CTL_KERN;
- mib[1] = KERN_PROCARGS2;
- mib[2] = pid;
- if (sysctl(mib, 3, procargs, &argmax, NULL, 0) < 0) {
- // In case of zombie process we'll get EINVAL. We translate it
- // to NSP and _psosx.py will translate it to ZP.
- if ((errno == EINVAL) && (psutil_pid_exists(pid)))
- NoSuchProcess("sysctl");
- else
- PyErr_SetFromErrno(PyExc_OSError);
+ if (psutil_sysctl_procargs(pid, procargs, argmax) != 0)
goto error;
- }
arg_end = &procargs[argmax];
// copy the number of arguments to nargs
@@ -226,7 +236,6 @@ error:
// return process environment as a python string
PyObject *
psutil_get_environ(pid_t pid) {
- int mib[3];
int nargs;
char *procargs = NULL;
char *procenv = NULL;
@@ -241,7 +250,7 @@ psutil_get_environ(pid_t pid) {
goto empty;
// read argmax and allocate memory for argument space.
- argmax = psutil_get_argmax();
+ argmax = psutil_sysctl_argmax();
if (! argmax)
goto error;
@@ -251,19 +260,8 @@ psutil_get_environ(pid_t pid) {
goto error;
}
- // read argument space
- mib[0] = CTL_KERN;
- mib[1] = KERN_PROCARGS2;
- mib[2] = pid;
- if (sysctl(mib, 3, procargs, &argmax, NULL, 0) < 0) {
- // In case of zombie process we'll get EINVAL. We translate it
- // to NSP and _psosx.py will translate it to ZP.
- if ((errno == EINVAL) && (psutil_pid_exists(pid)))
- NoSuchProcess("sysctl");
- else
- PyErr_SetFromOSErrnoWithSyscall("sysctl(KERN_PROCARGS2)");
+ if (psutil_sysctl_procargs(pid, procargs, argmax) != 0)
goto error;
- }
arg_end = &procargs[argmax];
// copy the number of arguments to nargs
diff --git a/psutil/arch/osx/process_info.h b/psutil/arch/osx/process_info.h
index 35755247..ffa6230f 100644
--- a/psutil/arch/osx/process_info.h
+++ b/psutil/arch/osx/process_info.h
@@ -8,7 +8,6 @@
typedef struct kinfo_proc kinfo_proc;
-int psutil_get_argmax(void);
int psutil_is_zombie(pid_t pid);
int psutil_get_kinfo_proc(pid_t pid, struct kinfo_proc *kp);
int psutil_get_proc_list(kinfo_proc **procList, size_t *procCount);
diff --git a/psutil/tests/test_process.py b/psutil/tests/test_process.py
index 0d63979b..33fcbf84 100755
--- a/psutil/tests/test_process.py
+++ b/psutil/tests/test_process.py
@@ -713,18 +713,15 @@ class TestProcess(PsutilTestCase):
def test_cmdline(self):
cmdline = [PYTHON_EXE, "-c", "import time; time.sleep(60)"]
p = self.spawn_psproc(cmdline)
- try:
+ # XXX - most of the times the underlying sysctl() call on Net
+ # and Open BSD returns a truncated string.
+ # Also /proc/pid/cmdline behaves the same so it looks
+ # like this is a kernel bug.
+ # XXX - AIX truncates long arguments in /proc/pid/cmdline
+ if NETBSD or OPENBSD or AIX:
+ self.assertEqual(p.cmdline()[0], PYTHON_EXE)
+ else:
self.assertEqual(' '.join(p.cmdline()), ' '.join(cmdline))
- except AssertionError:
- # XXX - most of the times the underlying sysctl() call on Net
- # and Open BSD returns a truncated string.
- # Also /proc/pid/cmdline behaves the same so it looks
- # like this is a kernel bug.
- # XXX - AIX truncates long arguments in /proc/pid/cmdline
- if NETBSD or OPENBSD or AIX:
- self.assertEqual(p.cmdline()[0], PYTHON_EXE)
- else:
- raise
@unittest.skipIf(PYPY, "broken on PYPY")
def test_long_cmdline(self):
diff --git a/psutil/tests/test_system.py b/psutil/tests/test_system.py
index bb6d2b89..872b8988 100755
--- a/psutil/tests/test_system.py
+++ b/psutil/tests/test_system.py
@@ -597,10 +597,12 @@ class TestDiskAPIs(PsutilTestCase):
self.assertIsInstance(nt.mountpoint, str)
self.assertIsInstance(nt.fstype, str)
self.assertIsInstance(nt.opts, str)
- self.assertIsInstance(nt.maxfile, int)
- self.assertIsInstance(nt.maxpath, int)
- self.assertGreater(nt.maxfile, 0)
- self.assertGreater(nt.maxpath, 0)
+ self.assertIsInstance(nt.maxfile, (int, type(None)))
+ self.assertIsInstance(nt.maxpath, (int, type(None)))
+ if nt.maxfile is not None:
+ self.assertGreater(nt.maxfile, 0)
+ if nt.maxpath is not None:
+ self.assertGreater(nt.maxpath, 0)
# all = False
ls = psutil.disk_partitions(all=False)
diff --git a/psutil/tests/test_unicode.py b/psutil/tests/test_unicode.py
index bae81380..7ec6c497 100755
--- a/psutil/tests/test_unicode.py
+++ b/psutil/tests/test_unicode.py
@@ -135,8 +135,6 @@ def try_unicode(suffix):
"""Return True if both the fs and the subprocess module can
deal with a unicode file name.
"""
- if PY3:
- return True
sproc = None
testfn = get_testfn(suffix=suffix)
try: