summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGiampaolo Rodola <g.rodola@gmail.com>2015-08-26 08:58:03 -0700
committerGiampaolo Rodola <g.rodola@gmail.com>2015-08-26 08:58:03 -0700
commitb9823dbb3071d902753e713b0c32d027e73a7946 (patch)
tree1e9c7b9631a43a70866a3b01a9d509f27d6f0956
parentd592453854a6742c2e9efff25b5203d544853d7a (diff)
downloadpsutil-b9823dbb3071d902753e713b0c32d027e73a7946.tar.gz
#650: make cmdline() handle unicode on python 2
-rw-r--r--docs/index.rst4
-rw-r--r--psutil/_pswindows.py15
-rw-r--r--psutil/arch/windows/process_info.c55
-rw-r--r--test/_windows.py6
4 files changed, 38 insertions, 42 deletions
diff --git a/docs/index.rst b/docs/index.rst
index 69edcead..f7dad748 100644
--- a/docs/index.rst
+++ b/docs/index.rst
@@ -697,6 +697,10 @@ Process class
The command line this process has been called with.
+ *Changed in 3.2.0:* (Windows, Python 2) in case one or more parts of the
+ cmdline contains non ASCII characters the returned type is a list of
+ unicode strings.
+
.. method:: create_time()
The process creation time as a floating point number expressed in seconds
diff --git a/psutil/_pswindows.py b/psutil/_pswindows.py
index 479cf770..3c86d994 100644
--- a/psutil/_pswindows.py
+++ b/psutil/_pswindows.py
@@ -315,7 +315,20 @@ class Process(object):
@wrap_exceptions
def cmdline(self):
- return cext.proc_cmdline(self.pid)
+ ret = cext.proc_cmdline(self.pid)
+ if PY3:
+ return ret
+ else:
+ # On Python 2, if one or more bits of the cmdline is unicode
+ # we return a list of unicode strings.
+ new = []
+ for x in ret:
+ x = py2_stringify(x)
+ if isinstance(x, unicode):
+ return ret
+ else:
+ new.append(x)
+ return new
def ppid(self):
try:
diff --git a/psutil/arch/windows/process_info.c b/psutil/arch/windows/process_info.c
index b925b05f..84860413 100644
--- a/psutil/arch/windows/process_info.c
+++ b/psutil/arch/windows/process_info.c
@@ -217,9 +217,8 @@ psutil_get_arg_list(long pid) {
PVOID rtlUserProcParamsAddress;
UNICODE_STRING commandLine;
WCHAR *commandLineContents = NULL;
- PyObject *arg = NULL;
- PyObject *arg_from_wchar = NULL;
- PyObject *argList = NULL;
+ PyObject *py_arg = NULL;
+ PyObject *py_retlist = NULL;
hProcess = psutil_handle_from_pid(pid);
if (hProcess == NULL)
@@ -274,48 +273,27 @@ psutil_get_arg_list(long pid) {
// commandLine.Length is in bytes.
commandLineContents[(commandLine.Length / sizeof(WCHAR))] = '\0';
- // attempt tp parse the command line using Win32 API, fall back
+ // attempt to parse the command line using Win32 API, fall back
// on string cmdline version otherwise
szArglist = CommandLineToArgvW(commandLineContents, &nArgs);
- if (NULL == szArglist) {
- // failed to parse arglist
- // encode as a UTF8 Python string object from WCHAR string
- arg_from_wchar = PyUnicode_FromWideChar(commandLineContents,
- commandLine.Length / 2);
- if (arg_from_wchar == NULL)
- goto error;
-#if PY_MAJOR_VERSION >= 3
- argList = Py_BuildValue("N", PyUnicode_AsUTF8String(arg_from_wchar));
-#else
- argList = Py_BuildValue("N", PyUnicode_FromObject(arg_from_wchar));
-#endif
- if (!argList)
- goto error;
+ if (szArglist == NULL) {
+ PyErr_SetFromWindowsErr(0);
+ goto error;
}
else {
// arglist parsed as array of UNICODE_STRING, so convert each to
// Python string object and add to arg list
- argList = Py_BuildValue("[]");
- if (argList == NULL)
+ py_retlist = Py_BuildValue("[]");
+ if (py_retlist == NULL)
goto error;
for (i = 0; i < nArgs; i++) {
- arg_from_wchar = NULL;
- arg = NULL;
- arg_from_wchar = PyUnicode_FromWideChar(szArglist[i],
- wcslen(szArglist[i]));
- if (arg_from_wchar == NULL)
- goto error;
-#if PY_MAJOR_VERSION >= 3
- arg = PyUnicode_FromObject(arg_from_wchar);
-#else
- arg = PyUnicode_AsUTF8String(arg_from_wchar);
-#endif
- if (arg == NULL)
+ py_arg = PyUnicode_FromWideChar(
+ szArglist[i], wcslen(szArglist[i]));
+ if (py_arg == NULL)
goto error;
- Py_XDECREF(arg_from_wchar);
- if (PyList_Append(argList, arg))
+ if (PyList_Append(py_retlist, py_arg))
goto error;
- Py_XDECREF(arg);
+ Py_XDECREF(py_arg);
}
}
@@ -323,12 +301,11 @@ psutil_get_arg_list(long pid) {
LocalFree(szArglist);
free(commandLineContents);
CloseHandle(hProcess);
- return argList;
+ return py_retlist;
error:
- Py_XDECREF(arg);
- Py_XDECREF(arg_from_wchar);
- Py_XDECREF(argList);
+ Py_XDECREF(py_arg);
+ Py_XDECREF(py_retlist);
if (hProcess != NULL)
CloseHandle(hProcess);
if (commandLineContents != NULL)
diff --git a/test/_windows.py b/test/_windows.py
index 8f2c7a52..70101726 100644
--- a/test/_windows.py
+++ b/test/_windows.py
@@ -491,8 +491,10 @@ class TestUnicode(unittest.TestCase):
shutil.copyfile(sys.executable, self.uexe)
subp = get_test_subprocess(cmd=[self.uexe])
p = psutil.Process(subp.pid)
- self.assertIsInstance("".join(p.cmdline()), unicode)
- self.assertEqual(p.cmdline(), [self.uexe])
+ self.assertIsInstance(u("").join(p.cmdline()), unicode)
+ uexe = self.uexe if PY3 else \
+ unicode(self.uexe, sys.getfilesystemencoding())
+ self.assertEqual(p.cmdline(), [uexe])
def test_proc_cwd(self):
tdir = tempfile.mkdtemp(prefix=u("psutil-รจ-"))