summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGiampaolo Rodola <g.rodola@gmail.com>2015-11-09 13:40:09 +0100
committerGiampaolo Rodola <g.rodola@gmail.com>2015-11-09 13:40:09 +0100
commitba5d61d047c930ead6aedbd4d5ab7ab7990684f5 (patch)
treebf8fd6e3a69e998e6fddfaffafd8c05958205e30
parent4cb337336736e982d14b2d56c0a4411b747a7d6e (diff)
downloadpsutil-ba5d61d047c930ead6aedbd4d5ab7ab7990684f5.tar.gz
#615: fix process status()
-rw-r--r--psutil/__init__.py10
-rw-r--r--psutil/_psbsd.py57
-rw-r--r--psutil/_psutil_openbsd.c23
-rw-r--r--test/test_psutil.py6
4 files changed, 77 insertions, 19 deletions
diff --git a/psutil/__init__.py b/psutil/__init__.py
index 47ef5cfd..d88b844a 100644
--- a/psutil/__init__.py
+++ b/psutil/__init__.py
@@ -1029,8 +1029,14 @@ class Process(object):
os.kill(self.pid, sig)
except OSError as err:
if err.errno == errno.ESRCH:
- self._gone = True
- raise NoSuchProcess(self.pid, self._name)
+ if (sys.platform.startswith("openbsd") and \
+ pid_exists(self.pid)):
+ # We do this because os.kill() lies in case of
+ # zombie processes.
+ raise ZombieProcess(self.pid, self._name, self._ppid)
+ else:
+ self._gone = True
+ raise NoSuchProcess(self.pid, self._name)
if err.errno in (errno.EPERM, errno.EACCES):
raise AccessDenied(self.pid, self._name)
raise
diff --git a/psutil/_psbsd.py b/psutil/_psbsd.py
index 60fcdd48..54e33289 100644
--- a/psutil/_psbsd.py
+++ b/psutil/_psbsd.py
@@ -29,15 +29,37 @@ __extra__all__ = []
FREEBSD = sys.platform.startswith("freebsd")
OPENBSD = sys.platform.startswith("openbsd")
-PROC_STATUSES = {
- cext.SIDL: _common.STATUS_IDLE,
- cext.SRUN: _common.STATUS_RUNNING,
- cext.SSLEEP: _common.STATUS_SLEEPING,
- cext.SSTOP: _common.STATUS_STOPPED,
- cext.SZOMB: _common.STATUS_ZOMBIE,
- cext.SWAIT: _common.STATUS_WAITING,
- cext.SLOCK: _common.STATUS_LOCKED,
-}
+if FREEBSD:
+ PROC_STATUSES = {
+ cext.SIDL: _common.STATUS_IDLE,
+ cext.SRUN: _common.STATUS_RUNNING,
+ cext.SSLEEP: _common.STATUS_SLEEPING,
+ cext.SSTOP: _common.STATUS_STOPPED,
+ cext.SZOMB: _common.STATUS_ZOMBIE,
+ cext.SWAIT: _common.STATUS_WAITING,
+ cext.SLOCK: _common.STATUS_LOCKED,
+ }
+elif OPENBSD:
+ PROC_STATUSES = {
+ cext.SIDL: _common.STATUS_IDLE,
+ cext.SSLEEP: _common.STATUS_SLEEPING,
+ cext.SSTOP: _common.STATUS_STOPPED,
+ # According to /usr/include/sys/proc.h SZOMB is unused.
+ # test_zombie_process() shows that SDEAD is the right
+ # equivalent. Also it appears there's no equivalent of
+ # psutil.STATUS_DEAD. SDEAD really means STATUS_ZOMBIE.
+ # cext.SZOMB: _common.STATUS_ZOMBIE,
+ cext.SDEAD: _common.STATUS_ZOMBIE,
+ # From http://www.eecs.harvard.edu/~margo/cs161/videos/proc.h.txt
+ # OpenBSD has SRUN and SONPROC: SRUN indicates that a process
+ # is runnable but *not* yet running, i.e. is on a run queue.
+ # SONPROC indicates that the process is actually executing on
+ # a CPU, i.e. it is no longer on a run queue.
+ # As such we'll map SRUN to STATUS_WAKING and SONPROC to
+ # STATUS_RUNNING
+ cext.SRUN: _common.STATUS_WAKING,
+ cext.SONPROC: _common.STATUS_RUNNING,
+ }
TCP_STATUSES = {
cext.TCPS_ESTABLISHED: _common.CONN_ESTABLISHED,
@@ -249,8 +271,20 @@ def net_if_stats():
return ret
+if OPENBSD:
+ def pid_exists(pid):
+ exists = _psposix.pid_exists(pid)
+ if not exists:
+ # We do this because _psposix.pid_exists() lies in case of
+ # zombie processes.
+ return pid in pids()
+ else:
+ return True
+else:
+ pid_exists = _psposix.pid_exists
+
+
pids = cext.pids
-pid_exists = _psposix.pid_exists
disk_usage = _psposix.disk_usage
net_io_counters = cext.net_io_counters
disk_io_counters = cext.disk_io_counters
@@ -271,7 +305,8 @@ def wrap_exceptions(fun):
ZombieProcess is None):
raise
if err.errno == errno.ESRCH:
- if not pid_exists(self.pid):
+ # if not pid_exists(self.pid):
+ if self.pid not in pids():
raise NoSuchProcess(self.pid, self._name)
else:
raise ZombieProcess(self.pid, self._name, self._ppid)
diff --git a/psutil/_psutil_openbsd.c b/psutil/_psutil_openbsd.c
index d7ad4c13..1c3c2169 100644
--- a/psutil/_psutil_openbsd.c
+++ b/psutil/_psutil_openbsd.c
@@ -1850,14 +1850,25 @@ void init_psutil_bsd(void)
#endif
PyModule_AddIntConstant(module, "version", PSUTIL_VERSION);
// process status constants
- PyModule_AddIntConstant(module, "SSTOP", SSTOP);
- PyModule_AddIntConstant(module, "SSLEEP", SSLEEP);
- PyModule_AddIntConstant(module, "SRUN", SRUN);
+
+#ifdef __FreeBSD__
PyModule_AddIntConstant(module, "SIDL", SIDL);
- PyModule_AddIntConstant(module, "SWAIT", -1);
- PyModule_AddIntConstant(module, "SLOCK", -1);
+ PyModule_AddIntConstant(module, "SRUN", SRUN);
+ PyModule_AddIntConstant(module, "SSLEEP", SSLEEP);
+ PyModule_AddIntConstant(module, "SSTOP", SSTOP);
PyModule_AddIntConstant(module, "SZOMB", SZOMB);
- PyModule_AddIntConstant(module, "SRUN", SONPROC);
+ PyModule_AddIntConstant(module, "SWAIT", SWAIT);
+ PyModule_AddIntConstant(module, "SLOCK", SLOCK);
+#elif __OpenBSD__
+ PyModule_AddIntConstant(module, "SIDL", SIDL);
+ PyModule_AddIntConstant(module, "SRUN", SRUN);
+ PyModule_AddIntConstant(module, "SSLEEP", SSLEEP);
+ PyModule_AddIntConstant(module, "SSTOP", SSTOP);
+ PyModule_AddIntConstant(module, "SZOMB", SZOMB); // unused
+ PyModule_AddIntConstant(module, "SDEAD", SDEAD);
+ PyModule_AddIntConstant(module, "SONPROC", SONPROC);
+#endif
+
// connection status constants
PyModule_AddIntConstant(module, "TCPS_CLOSED", TCPS_CLOSED);
PyModule_AddIntConstant(module, "TCPS_CLOSING", TCPS_CLOSING);
diff --git a/test/test_psutil.py b/test/test_psutil.py
index 0e4fe2da..9a3a963c 100644
--- a/test/test_psutil.py
+++ b/test/test_psutil.py
@@ -1627,6 +1627,12 @@ class TestProcess(unittest.TestCase):
def test_threads_2(self):
p = psutil.Process()
+ if OPENBSD:
+ try:
+ p.threads()
+ except psutil.AccessDenied:
+ raise unittest.SkipTest(
+ "on OpenBSD this requires root access")
self.assertAlmostEqual(p.cpu_times().user,
p.threads()[0].user_time, delta=0.1)
self.assertAlmostEqual(p.cpu_times().system,