diff options
author | Giampaolo Rodola <g.rodola@gmail.com> | 2020-11-11 01:10:32 +0100 |
---|---|---|
committer | Giampaolo Rodola <g.rodola@gmail.com> | 2020-11-11 01:10:32 +0100 |
commit | fbec5bfe5b115075be37a820465891dffdf2b9cc (patch) | |
tree | 3093b8cd35cd7119a72ed487a3bd4b1060dc2834 | |
parent | 22e09e5fc6c59f3b3222cd00d741b3562772a8ab (diff) | |
parent | 7050e73c48b38caf2f19409167ba8dfaa9ab9fd4 (diff) | |
download | psutil-fbec5bfe5b115075be37a820465891dffdf2b9cc.tar.gz |
merge from master
-rw-r--r-- | .github/workflows/build_wheel.yml | 1 | ||||
-rw-r--r-- | psutil/arch/osx/process_info.c | 88 | ||||
-rw-r--r-- | psutil/arch/osx/process_info.h | 1 | ||||
-rwxr-xr-x | psutil/tests/test_process.py | 19 | ||||
-rwxr-xr-x | psutil/tests/test_system.py | 10 | ||||
-rwxr-xr-x | psutil/tests/test_unicode.py | 2 |
6 files changed, 58 insertions, 63 deletions
diff --git a/.github/workflows/build_wheel.yml b/.github/workflows/build_wheel.yml index 3a768f00..9765f43f 100644 --- a/.github/workflows/build_wheel.yml +++ b/.github/workflows/build_wheel.yml @@ -6,6 +6,7 @@ jobs: wheel: name: ${{ matrix.os }} runs-on: ${{ matrix.os }} + timeout: 30 strategy: fail-fast: false # whether to exit the whole run on first failure matrix: diff --git a/psutil/arch/osx/process_info.c b/psutil/arch/osx/process_info.c index c76e593a..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(KERN_PROCARGS2) -> EINVAL turned into NSP"); - 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 @@ -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(KERN_PROCARGS2) -> EINVAL turned into NSP"); - 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 605f3c1b..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: |