summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGiampaolo Rodola <g.rodola@gmail.com>2016-01-13 23:50:30 +0100
committerGiampaolo Rodola <g.rodola@gmail.com>2016-01-13 23:50:30 +0100
commit89dbd1d1e5b17c03f1252eb734d0c1cd5b445a48 (patch)
treebacce7b30ec4ebb5ab5c715ceff714dacea2e512
parent94c37c17fa1d59e04edb2f5f79ec6a5814cffded (diff)
downloadpsutil-89dbd1d1e5b17c03f1252eb734d0c1cd5b445a48.tar.gz
#734: fix unicode issues on FreeBSD
-rw-r--r--psutil/_common.py4
-rw-r--r--psutil/_psbsd.py11
-rw-r--r--psutil/_psosx.py8
-rw-r--r--psutil/_psutil_bsd.c17
-rw-r--r--psutil/arch/bsd/freebsd.c20
-rw-r--r--test/test_psutil.py17
6 files changed, 49 insertions, 28 deletions
diff --git a/psutil/_common.py b/psutil/_common.py
index 3ff1cb88..c174fdef 100644
--- a/psutil/_common.py
+++ b/psutil/_common.py
@@ -193,6 +193,10 @@ def socktype_to_enum(num):
return num
+def get_encoding_errors_handler():
+ return sys.modules['psutil'].ENCODING_ERRORS_HANDLER
+
+
# --- Process.connections() 'kind' parameter mapping
conn_tmap = {
diff --git a/psutil/_psbsd.py b/psutil/_psbsd.py
index f20a80b7..5b79ea23 100644
--- a/psutil/_psbsd.py
+++ b/psutil/_psbsd.py
@@ -17,12 +17,12 @@ from . import _psposix
from . import _psutil_bsd as cext
from . import _psutil_posix as cext_posix
from ._common import conn_tmap
+from ._common import get_encoding_errors_handler
from ._common import sockfam_to_enum
from ._common import socktype_to_enum
from ._common import usage_percent
from ._compat import which
-
__extra__all__ = []
# --- constants
@@ -357,21 +357,22 @@ def wrap_exceptions_procfs(inst):
class Process(object):
"""Wrapper class around underlying C implementation."""
- __slots__ = ["pid", "_name", "_ppid"]
+ __slots__ = ["pid", "_name", "_ppid", "_encoding_errs"]
def __init__(self, pid):
self.pid = pid
self._name = None
self._ppid = None
+ self._encoding_errs = get_encoding_errors_handler()
@wrap_exceptions
def name(self):
- return cext.proc_name(self.pid)
+ return cext.proc_name(self.pid, self._encoding_errs)
@wrap_exceptions
def exe(self):
if FREEBSD:
- return cext.proc_exe(self.pid)
+ return cext.proc_exe(self.pid, self._encoding_errs)
elif NETBSD:
if self.pid == 0:
# /proc/0 dir exists but /proc/0/exe doesn't
@@ -566,7 +567,7 @@ class Process(object):
elif hasattr(cext, 'proc_open_files'):
# FreeBSD < 8 does not support functions based on
# kinfo_getfile() and kinfo_getvmmap()
- return cext.proc_cwd(self.pid) or None
+ return cext.proc_cwd(self.pid, self._encoding_errs) or None
else:
raise NotImplementedError(
"supported only starting from FreeBSD 8" if
diff --git a/psutil/_psosx.py b/psutil/_psosx.py
index 26f1337f..ff6796e0 100644
--- a/psutil/_psosx.py
+++ b/psutil/_psosx.py
@@ -7,7 +7,6 @@
import errno
import functools
import os
-import sys
from collections import namedtuple
from . import _common
@@ -15,6 +14,7 @@ from . import _psposix
from . import _psutil_osx as cext
from . import _psutil_posix as cext_posix
from ._common import conn_tmap
+from ._common import get_encoding_errors_handler
from ._common import isfile_strict
from ._common import sockfam_to_enum
from ._common import socktype_to_enum
@@ -74,12 +74,6 @@ AccessDenied = None
TimeoutExpired = None
-# --- utils
-
-def get_encoding_errors_handler():
- return sys.modules['psutil'].ENCODING_ERRORS_HANDLER
-
-
# --- functions
def virtual_memory():
diff --git a/psutil/_psutil_bsd.c b/psutil/_psutil_bsd.c
index 5d22d881..1fdb4c00 100644
--- a/psutil/_psutil_bsd.c
+++ b/psutil/_psutil_bsd.c
@@ -192,14 +192,25 @@ static PyObject *
psutil_proc_name(PyObject *self, PyObject *args) {
long pid;
kinfo_proc kp;
- if (! PyArg_ParseTuple(args, "l", &pid))
+ char str[1000];
+ const char *encoding_errs;
+
+ if (! PyArg_ParseTuple(args, "ls", &pid, &encoding_errs))
return NULL;
if (psutil_kinfo_proc(pid, &kp) == -1)
return NULL;
+
#ifdef __FreeBSD__
- return Py_BuildValue("s", kp.ki_comm);
+ sprintf(str, "%s", kp.ki_comm);
#elif defined(__OpenBSD__) || defined(__NetBSD__)
- return Py_BuildValue("s", kp.p_comm);
+ sprintf(str, "%s", kp.p_comm);
+#endif
+
+#if PY_MAJOR_VERSION >= 3
+ return PyUnicode_Decode(
+ str, strlen(str), Py_FileSystemDefaultEncoding, encoding_errs);
+#else
+ return Py_BuildValue("s", str);
#endif
}
diff --git a/psutil/arch/bsd/freebsd.c b/psutil/arch/bsd/freebsd.c
index 3b7fc478..4042ffd1 100644
--- a/psutil/arch/bsd/freebsd.c
+++ b/psutil/arch/bsd/freebsd.c
@@ -317,8 +317,9 @@ psutil_proc_exe(PyObject *self, PyObject *args) {
int mib[4];
int ret;
size_t size;
+ const char *encoding_errs;
- if (! PyArg_ParseTuple(args, "l", &pid))
+ if (! PyArg_ParseTuple(args, "ls", &pid, &encoding_errs))
return NULL;
mib[0] = CTL_KERN;
@@ -341,7 +342,15 @@ psutil_proc_exe(PyObject *self, PyObject *args) {
else
strcpy(pathname, "");
}
+
+#if PY_MAJOR_VERSION >= 3
+ return PyUnicode_Decode(
+ pathname, strlen(pathname), Py_FileSystemDefaultEncoding,
+ encoding_errs);
+#else
return Py_BuildValue("s", pathname);
+#endif
+
}
@@ -574,11 +583,12 @@ psutil_proc_cwd(PyObject *self, PyObject *args) {
struct kinfo_file *freep = NULL;
struct kinfo_file *kif;
struct kinfo_proc kipp;
+ const char *encoding_errs;
PyObject *py_path = NULL;
int i, cnt;
- if (! PyArg_ParseTuple(args, "l", &pid))
+ if (! PyArg_ParseTuple(args, "ls", &pid, &encoding_errs))
goto error;
if (psutil_kinfo_proc(pid, &kipp) == -1)
goto error;
@@ -592,7 +602,13 @@ psutil_proc_cwd(PyObject *self, PyObject *args) {
for (i = 0; i < cnt; i++) {
kif = &freep[i];
if (kif->kf_fd == KF_FD_TYPE_CWD) {
+#if PY_MAJOR_VERSION >= 3
+ py_path = PyUnicode_Decode(
+ kif->kf_path, strlen(kif->kf_path),
+ Py_FileSystemDefaultEncoding, encoding_errs);
+#else
py_path = Py_BuildValue("s", kif->kf_path);
+#endif
if (!py_path)
goto error;
break;
diff --git a/test/test_psutil.py b/test/test_psutil.py
index 333015be..c72a8543 100644
--- a/test/test_psutil.py
+++ b/test/test_psutil.py
@@ -3313,25 +3313,20 @@ class TestNonUnicode(unittest.TestCase):
stdout=subprocess.PIPE,
stderr=subprocess.STDOUT)
p = psutil.Process(subp.pid)
- self.assertIsInstance(p.name(), str)
self.assertEqual(encode_path(os.path.basename(p.name())), b"\xc0\x80")
subp.communicate()
self.assertEqual(subp.returncode, 0)
def test_proc_cmdline(self):
- funny_file = os.path.join(self.temp_directory, b"\xc0\x80")
- open(funny_file, "wb").close()
- self.addCleanup(safe_remove, funny_file)
- cmd = [self.test_executable]
- if WINDOWS:
- cmd.extend(["/K", "type \xc0\x80"])
- subp = get_test_subprocess(cmd=cmd,
+ funny_executable = os.path.join(self.temp_directory, b"\xc0\x80")
+ self.copy_file(self.test_executable, funny_executable)
+ self.addCleanup(safe_remove, funny_executable)
+ subp = get_test_subprocess(cmd=[decode_path(funny_executable)],
stdin=subprocess.PIPE,
stdout=subprocess.PIPE,
- stderr=subprocess.STDOUT,
- cwd=decode_path(self.temp_directory))
+ stderr=subprocess.STDOUT)
p = psutil.Process(subp.pid)
- self.assertEqual(p.cmdline()[1:], cmd[1:])
+ self.assertEqual(p.cmdline(), [decode_path(funny_executable)])
subp.communicate()
self.assertEqual(subp.returncode, 0)