summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGiampaolo Rodola <g.rodola@gmail.com>2016-10-17 23:35:41 +0200
committerGiampaolo Rodola <g.rodola@gmail.com>2016-10-17 23:35:41 +0200
commit5887f56f92ae3cceb06946508dcd5d077502e992 (patch)
tree143e09b87e910bc9c0c0b43954e67d73f302f57e
parent67eb99259db43172245fca662a647fe38c36b355 (diff)
downloadpsutil-5887f56f92ae3cceb06946508dcd5d077502e992.tar.gz
fix #924: [OSX] Process.exe() for PID 0 erroneously raise ZombieProcess. Also test all process methods with PID 0
-rw-r--r--HISTORY.rst1
-rw-r--r--psutil/_psutil_osx.c5
-rwxr-xr-xpsutil/tests/test_process.py48
3 files changed, 21 insertions, 33 deletions
diff --git a/HISTORY.rst b/HISTORY.rst
index f3e31a1c..200f19a4 100644
--- a/HISTORY.rst
+++ b/HISTORY.rst
@@ -40,6 +40,7 @@ Bug tracker at https://github.com/giampaolo/psutil/issues
- #921: psutil.Popen now defines a __del__ special method which calls the
original one, hopefully helping the gc to free resources.
- #923: [OSX] free memory is wrong (does not match vm_stat command).
+- #924: [OSX] Process.exe() for PID 0 erroneously raise ZombieProcess.
4.3.1 - 2016-09-01
diff --git a/psutil/_psutil_osx.c b/psutil/_psutil_osx.c
index 672ec346..bdd7c559 100644
--- a/psutil/_psutil_osx.c
+++ b/psutil/_psutil_osx.c
@@ -173,7 +173,10 @@ psutil_proc_exe(PyObject *self, PyObject *args) {
errno = 0;
ret = proc_pidpath((pid_t)pid, &buf, sizeof(buf));
if (ret == 0) {
- psutil_raise_for_pid(pid, "proc_pidpath() syscall failed");
+ if (pid == 0)
+ AccessDenied();
+ else
+ psutil_raise_for_pid(pid, "proc_pidpath() syscall failed");
return NULL;
}
#if PY_MAJOR_VERSION >= 3
diff --git a/psutil/tests/test_process.py b/psutil/tests/test_process.py
index ede67664..a6c43525 100755
--- a/psutil/tests/test_process.py
+++ b/psutil/tests/test_process.py
@@ -1402,46 +1402,30 @@ class TestProcess(unittest.TestCase):
def test_pid_0(self):
# Process(0) is supposed to work on all platforms except Linux
- if 0 not in psutil.pids() and not OPENBSD:
+ if 0 not in psutil.pids():
self.assertRaises(psutil.NoSuchProcess, psutil.Process, 0)
return
+ # test all methods
p = psutil.Process(0)
- self.assertTrue(p.name())
-
- if POSIX:
+ for name in psutil._as_dict_attrnames:
+ if name == 'pid':
+ continue
+ meth = getattr(p, name)
try:
- self.assertEqual(p.uids().real, 0)
- self.assertEqual(p.gids().real, 0)
+ ret = meth()
except psutil.AccessDenied:
pass
-
- self.assertRaisesRegex(
- ValueError, "preventing sending signal to process with PID 0",
- p.send_signal, signal.SIGTERM)
-
- self.assertIn(p.ppid(), (0, 1))
- # self.assertEqual(p.exe(), "")
- p.cmdline()
- try:
- p.num_threads()
- except psutil.AccessDenied:
- pass
-
- try:
- p.memory_info()
- except psutil.AccessDenied:
- pass
-
- try:
- if POSIX:
- self.assertEqual(p.username(), 'root')
- elif WINDOWS:
- self.assertEqual(p.username(), 'NT AUTHORITY\\SYSTEM')
else:
- p.username()
- except psutil.AccessDenied:
- pass
+ if name in ("uids", "gids"):
+ self.assertEqual(ret.real, 0)
+ elif name == "username":
+ if POSIX:
+ self.assertEqual(p.username(), 'root')
+ elif WINDOWS:
+ self.assertEqual(p.username(), 'NT AUTHORITY\\SYSTEM')
+ elif name == "name":
+ assert name, name
p.as_dict()