From efd7ed3d2c4aca57226572b2a81e5d7ebb9f3b8b Mon Sep 17 00:00:00 2001 From: Giampaolo Rodola Date: Tue, 18 Apr 2023 13:05:04 +0200 Subject: C refact: remove useless cmdline / cwd / environ layers. Call direct functions --- psutil/_psutil_bsd.c | 16 ------- psutil/_psutil_osx.c | 40 ----------------- psutil/_psutil_windows.c | 73 ------------------------------- psutil/arch/freebsd/proc.c | 64 +++++++++------------------ psutil/arch/freebsd/proc.h | 2 +- psutil/arch/netbsd/proc.c | 74 ++++++++++++-------------------- psutil/arch/netbsd/proc.h | 9 ++-- psutil/arch/openbsd/proc.c | 48 ++++++++++----------- psutil/arch/openbsd/proc.h | 2 +- psutil/arch/osx/process_info.c | 24 +++++++---- psutil/arch/osx/process_info.h | 5 ++- psutil/arch/windows/process_info.c | 88 +++++++++++++++++++++++++++++++------- psutil/arch/windows/process_info.h | 6 +-- psutil/tests/test_memleaks.py | 0 14 files changed, 170 insertions(+), 281 deletions(-) mode change 100755 => 100644 psutil/tests/test_memleaks.py diff --git a/psutil/_psutil_bsd.c b/psutil/_psutil_bsd.c index ff5fd72d..dfebf9ff 100644 --- a/psutil/_psutil_bsd.c +++ b/psutil/_psutil_bsd.c @@ -380,22 +380,6 @@ psutil_proc_name(PyObject *self, PyObject *args) { } -/* - * Return process cmdline as a Python list of cmdline arguments. - */ -static PyObject * -psutil_proc_cmdline(PyObject *self, PyObject *args) { - pid_t pid; - PyObject *py_retlist = NULL; - - if (! PyArg_ParseTuple(args, _Py_PARSE_PID, &pid)) - return NULL; - py_retlist = psutil_get_cmdline(pid); - if (py_retlist == NULL) - return NULL; - return Py_BuildValue("N", py_retlist); -} - /* * Return process environment as a Python dictionary diff --git a/psutil/_psutil_osx.c b/psutil/_psutil_osx.c index 9ba0fd2b..713f3d6c 100644 --- a/psutil/_psutil_osx.c +++ b/psutil/_psutil_osx.c @@ -386,46 +386,6 @@ psutil_proc_exe(PyObject *self, PyObject *args) { } -/* - * Return process cmdline as a Python list of cmdline arguments. - */ -static PyObject * -psutil_proc_cmdline(PyObject *self, PyObject *args) { - pid_t pid; - PyObject *py_retlist = NULL; - - if (! PyArg_ParseTuple(args, _Py_PARSE_PID, &pid)) - return NULL; - - // get the commandline, defined in arch/osx/process_info.c - py_retlist = psutil_get_cmdline(pid); - return py_retlist; -} - - -/* - * Return process environment as a Python string. - * On Big Sur this function returns an empty string unless: - * * kernel is DEVELOPMENT || DEBUG - * * target process is same as current_proc() - * * target process is not cs_restricted - * * SIP is off - * * caller has an entitlement - */ -static PyObject * -psutil_proc_environ(PyObject *self, PyObject *args) { - pid_t pid; - PyObject *py_str = NULL; - - if (! PyArg_ParseTuple(args, _Py_PARSE_PID, &pid)) - return NULL; - - // get the environment block, defined in arch/osx/process_info.c - py_str = psutil_get_environ(pid); - return py_str; -} - - /* * Indicates if the given virtual address on the given architecture is in the * shared VM region. diff --git a/psutil/_psutil_windows.c b/psutil/_psutil_windows.c index 11176de7..8e51c0bd 100644 --- a/psutil/_psutil_windows.c +++ b/psutil/_psutil_windows.c @@ -276,59 +276,6 @@ psutil_proc_times(PyObject *self, PyObject *args) { } -/* - * Return process cmdline as a Python list of cmdline arguments. - */ -static PyObject * -psutil_proc_cmdline(PyObject *self, PyObject *args, PyObject *kwdict) { - DWORD pid; - int pid_return; - int use_peb; - PyObject *py_usepeb = Py_True; - static char *keywords[] = {"pid", "use_peb", NULL}; - - if (!PyArg_ParseTupleAndKeywords(args, kwdict, _Py_PARSE_PID "|O", - keywords, &pid, &py_usepeb)) - { - return NULL; - } - if ((pid == 0) || (pid == 4)) - return Py_BuildValue("[]"); - - pid_return = psutil_pid_is_running(pid); - if (pid_return == 0) - return NoSuchProcess("psutil_pid_is_running -> 0"); - if (pid_return == -1) - return NULL; - - use_peb = (py_usepeb == Py_True) ? 1 : 0; - return psutil_get_cmdline(pid, use_peb); -} - - -/* - * Return process cmdline as a Python list of cmdline arguments. - */ -static PyObject * -psutil_proc_environ(PyObject *self, PyObject *args) { - DWORD pid; - int pid_return; - - if (! PyArg_ParseTuple(args, _Py_PARSE_PID, &pid)) - return NULL; - if ((pid == 0) || (pid == 4)) - return Py_BuildValue("s", ""); - - pid_return = psutil_pid_is_running(pid); - if (pid_return == 0) - return NoSuchProcess("psutil_pid_is_running -> 0"); - if (pid_return == -1) - return NULL; - - return psutil_get_environ(pid); -} - - /* * Return process executable path. Works for all processes regardless of * privilege. NtQuerySystemInformation has some sort of internal cache, @@ -604,26 +551,6 @@ psutil_proc_memory_uss(PyObject *self, PyObject *args) { return Py_BuildValue("I", wsCounters.NumberOfPrivatePages); } -/* - * Return process current working directory as a Python string. - */ -static PyObject * -psutil_proc_cwd(PyObject *self, PyObject *args) { - DWORD pid; - int pid_return; - - if (! PyArg_ParseTuple(args, _Py_PARSE_PID, &pid)) - return NULL; - - pid_return = psutil_pid_is_running(pid); - if (pid_return == 0) - return NoSuchProcess("psutil_pid_is_running -> 0"); - if (pid_return == -1) - return NULL; - - return psutil_get_cwd(pid); -} - /* * Resume or suspends a process diff --git a/psutil/arch/freebsd/proc.c b/psutil/arch/freebsd/proc.c index 214dbc48..6528ece4 100644 --- a/psutil/arch/freebsd/proc.c +++ b/psutil/arch/freebsd/proc.c @@ -135,24 +135,24 @@ psutil_get_proc_list(struct kinfo_proc **procList, size_t *procCount) { /* - * XXX no longer used; it probably makese sense to remove it. * Borrowed from psi Python System Information project - * - * Get command arguments and environment variables. - * * Based on code from ps. - * - * Returns: - * 0 for success; - * -1 for failure (Exception raised); - * 1 for insufficient privileges. */ -static char -*psutil_get_cmd_args(pid_t pid, size_t *argsize) { +PyObject * +psutil_proc_cmdline(PyObject *self, PyObject *args) { + pid_t pid; int mib[4]; int argmax; size_t size = sizeof(argmax); char *procargs = NULL; + size_t pos = 0; + PyObject *py_retlist = PyList_New(0); + PyObject *py_arg = NULL; + + if (py_retlist == NULL) + return NULL; + if (! PyArg_ParseTuple(args, _Py_PARSE_PID, &pid)) + goto error; // Get the maximum process arguments size. mib[0] = CTL_KERN; @@ -160,13 +160,13 @@ static char size = sizeof(argmax); if (sysctl(mib, 2, &argmax, &size, NULL, 0) == -1) - return NULL; + goto error; // Allocate space for the arguments. procargs = (char *)malloc(argmax); if (procargs == NULL) { PyErr_NoMemory(); - return NULL; + goto error; } // Make a sysctl() call to get the raw argument space of the process. @@ -177,55 +177,33 @@ static char size = argmax; if (sysctl(mib, 4, procargs, &size, NULL, 0) == -1) { - free(procargs); PyErr_SetFromOSErrnoWithSyscall("sysctl(KERN_PROC_ARGS)"); - return NULL; - } - - // return string and set the length of arguments - *argsize = size; - return procargs; -} - - -// returns the command line as a python list object -PyObject * -psutil_get_cmdline(pid_t pid) { - char *argstr = NULL; - size_t pos = 0; - size_t argsize = 0; - PyObject *py_retlist = Py_BuildValue("[]"); - PyObject *py_arg = NULL; - - if (pid < 0) - return py_retlist; - argstr = psutil_get_cmd_args(pid, &argsize); - if (argstr == NULL) goto error; + } // args are returned as a flattened string with \0 separators between // arguments add each string to the list then step forward to the next // separator - if (argsize > 0) { - while (pos < argsize) { - py_arg = PyUnicode_DecodeFSDefault(&argstr[pos]); + if (size > 0) { + while (pos < size) { + py_arg = PyUnicode_DecodeFSDefault(&procargs[pos]); if (!py_arg) goto error; if (PyList_Append(py_retlist, py_arg)) goto error; Py_DECREF(py_arg); - pos = pos + strlen(&argstr[pos]) + 1; + pos = pos + strlen(&procargs[pos]) + 1; } } - free(argstr); + free(procargs); return py_retlist; error: Py_XDECREF(py_arg); Py_DECREF(py_retlist); - if (argstr != NULL) - free(argstr); + if (procargs != NULL) + free(procargs); return NULL; } diff --git a/psutil/arch/freebsd/proc.h b/psutil/arch/freebsd/proc.h index 9c16f3cb..f24535eb 100644 --- a/psutil/arch/freebsd/proc.h +++ b/psutil/arch/freebsd/proc.h @@ -11,7 +11,7 @@ typedef struct kinfo_proc kinfo_proc; int psutil_get_proc_list(struct kinfo_proc **procList, size_t *procCount); int psutil_kinfo_proc(const pid_t pid, struct kinfo_proc *proc); -PyObject* psutil_get_cmdline(long pid); +PyObject* psutil_proc_cmdline(PyObject* self, PyObject* args); PyObject* psutil_proc_cpu_affinity_get(PyObject* self, PyObject* args); PyObject* psutil_proc_cpu_affinity_set(PyObject* self, PyObject* args); PyObject* psutil_proc_cwd(PyObject* self, PyObject* args); diff --git a/psutil/arch/netbsd/proc.c b/psutil/arch/netbsd/proc.c index d4fa2126..1b05d61a 100644 --- a/psutil/arch/netbsd/proc.c +++ b/psutil/arch/netbsd/proc.c @@ -187,6 +187,7 @@ psutil_proc_exe(PyObject *self, PyObject *args) { } */ + PyObject * psutil_proc_num_threads(PyObject *self, PyObject *args) { // Return number of threads used by process as a Python integer. @@ -199,6 +200,7 @@ psutil_proc_num_threads(PyObject *self, PyObject *args) { return Py_BuildValue("l", (long)kp.p_nlwps); } + PyObject * psutil_proc_threads(PyObject *self, PyObject *args) { pid_t pid; @@ -328,86 +330,64 @@ psutil_get_proc_list(kinfo_proc **procList, size_t *procCount) { } -char * -psutil_get_cmd_args(pid_t pid, size_t *argsize) { +PyObject * +psutil_proc_cmdline(PyObject *self, PyObject *args) { + pid_t pid; int mib[4]; int st; - size_t len; - char *procargs; + size_t len = 0; + size_t pos = 0; + char *procargs = NULL; + PyObject *py_retlist = PyList_New(0); + PyObject *py_arg = NULL; + + if (py_retlist == NULL) + return NULL; + if (! PyArg_ParseTuple(args, _Py_PARSE_PID, &pid)) + goto error; mib[0] = CTL_KERN; mib[1] = KERN_PROC_ARGS; mib[2] = pid; mib[3] = KERN_PROC_ARGV; - len = 0; st = sysctl(mib, __arraycount(mib), NULL, &len, NULL, 0); if (st == -1) { - PyErr_SetFromErrno(PyExc_OSError); - return NULL; + PyErr_SetFromOSErrnoWithSyscall("sysctl(KERN_PROC_ARGV) get size"); + goto error; } procargs = (char *)malloc(len); if (procargs == NULL) { PyErr_NoMemory(); - return NULL; + goto error; } st = sysctl(mib, __arraycount(mib), procargs, &len, NULL, 0); if (st == -1) { - free(procargs); - PyErr_SetFromErrno(PyExc_OSError); - return NULL; - } - - *argsize = len; - return procargs; -} - - -// Return the command line as a python list object. -// XXX - most of the times sysctl() returns a truncated string. -// Also /proc/pid/cmdline behaves the same so it looks like this -// is a kernel bug. -PyObject * -psutil_get_cmdline(pid_t pid) { - char *argstr = NULL; - size_t pos = 0; - size_t argsize = 0; - PyObject *py_arg = NULL; - PyObject *py_retlist = PyList_New(0); - - if (py_retlist == NULL) - return NULL; - if (pid == 0) - return py_retlist; - - argstr = psutil_get_cmd_args(pid, &argsize); - if (argstr == NULL) + PyErr_SetFromOSErrnoWithSyscall("sysctl(KERN_PROC_ARGV)"); goto error; + } - // args are returned as a flattened string with \0 separators between - // arguments add each string to the list then step forward to the next - // separator - if (argsize > 0) { - while (pos < argsize) { - py_arg = PyUnicode_DecodeFSDefault(&argstr[pos]); + if (len > 0) { + while (pos < len) { + py_arg = PyUnicode_DecodeFSDefault(&procargs[pos]); if (!py_arg) goto error; if (PyList_Append(py_retlist, py_arg)) goto error; Py_DECREF(py_arg); - pos = pos + strlen(&argstr[pos]) + 1; + pos = pos + strlen(&procargs[pos]) + 1; } } - free(argstr); + free(procargs); return py_retlist; error: Py_XDECREF(py_arg); Py_DECREF(py_retlist); - if (argstr != NULL) - free(argstr); + if (procargs != NULL) + free(procargs); return NULL; } diff --git a/psutil/arch/netbsd/proc.h b/psutil/arch/netbsd/proc.h index b4c88851..8c51914d 100644 --- a/psutil/arch/netbsd/proc.h +++ b/psutil/arch/netbsd/proc.h @@ -14,11 +14,10 @@ struct kinfo_file * kinfo_getfile(pid_t pid, int* cnt); int psutil_get_proc_list(kinfo_proc **procList, size_t *procCount); char *psutil_get_cmd_args(pid_t pid, size_t *argsize); -// -PyObject *psutil_get_cmdline(pid_t pid); -PyObject *psutil_proc_threads(PyObject *self, PyObject *args); -PyObject *psutil_proc_num_fds(PyObject *self, PyObject *args); +PyObject *psutil_proc_cmdline(PyObject *self, PyObject *args); PyObject *psutil_proc_connections(PyObject *self, PyObject *args); +PyObject *psutil_proc_cwd(PyObject *self, PyObject *args); +PyObject *psutil_proc_num_fds(PyObject *self, PyObject *args); +PyObject *psutil_proc_threads(PyObject *self, PyObject *args); PyObject* psutil_proc_exe(PyObject* self, PyObject* args); PyObject* psutil_proc_num_threads(PyObject* self, PyObject* args); -PyObject *psutil_proc_cwd(PyObject *self, PyObject *args); diff --git a/psutil/arch/openbsd/proc.c b/psutil/arch/openbsd/proc.c index 285467bf..5c984fc5 100644 --- a/psutil/arch/openbsd/proc.c +++ b/psutil/arch/openbsd/proc.c @@ -143,45 +143,42 @@ psutil_get_proc_list(struct kinfo_proc **procList, size_t *procCount) { // TODO: refactor this (it's clunky) -static char ** -_psutil_get_argv(pid_t pid) { +PyObject * +psutil_proc_cmdline(PyObject *self, PyObject *args) { + pid_t pid; + int mib[4]; static char **argv; - int argv_mib[] = {CTL_KERN, KERN_PROC_ARGS, pid, KERN_PROC_ARGV}; + char **p; size_t argv_size = 128; + PyObject *py_retlist = PyList_New(0); + PyObject *py_arg = NULL; + + if (py_retlist == NULL) + return NULL; + if (! PyArg_ParseTuple(args, _Py_PARSE_PID, &pid)) + goto error; + + mib[0] = CTL_KERN; + mib[1] = KERN_PROC_ARGS; + mib[2] = pid; + mib[3] = KERN_PROC_ARGV; + // Loop and reallocate until we have enough space to fit argv. for (;; argv_size *= 2) { if (argv_size >= 8192) { PyErr_SetString(PyExc_RuntimeError, "can't allocate enough space for KERN_PROC_ARGV"); - return NULL; + goto error; } if ((argv = realloc(argv, argv_size)) == NULL) continue; - if (sysctl(argv_mib, 4, argv, &argv_size, NULL, 0) == 0) - return argv; + if (sysctl(mib, 4, argv, &argv_size, NULL, 0) == 0) + break; if (errno == ENOMEM) continue; PyErr_SetFromErrno(PyExc_OSError); - return NULL; - } -} - - -// returns the command line as a python list object -PyObject * -psutil_get_cmdline(pid_t pid) { - static char **argv; - char **p; - PyObject *py_arg = NULL; - PyObject *py_retlist = Py_BuildValue("[]"); - - if (!py_retlist) - return NULL; - if (pid < 0) - return py_retlist; - - if ((argv = _psutil_get_argv(pid)) == NULL) goto error; + } for (p = argv; *p != NULL; p++) { py_arg = PyUnicode_DecodeFSDefault(*p); @@ -191,6 +188,7 @@ psutil_get_cmdline(pid_t pid) { goto error; Py_DECREF(py_arg); } + return py_retlist; error: diff --git a/psutil/arch/openbsd/proc.h b/psutil/arch/openbsd/proc.h index 747507dd..a577e5f1 100644 --- a/psutil/arch/openbsd/proc.h +++ b/psutil/arch/openbsd/proc.h @@ -14,7 +14,7 @@ struct kinfo_file * kinfo_getfile(pid_t pid, int* cnt); int psutil_get_proc_list(struct kinfo_proc **procList, size_t *procCount); char **_psutil_get_argv(pid_t pid); -PyObject *psutil_get_cmdline(pid_t pid); +PyObject *psutil_proc_cmdline(PyObject *self, PyObject *args); PyObject *psutil_proc_threads(PyObject *self, PyObject *args); PyObject *psutil_proc_num_fds(PyObject *self, PyObject *args); PyObject *psutil_proc_cwd(PyObject *self, PyObject *args); diff --git a/psutil/arch/osx/process_info.c b/psutil/arch/osx/process_info.c index 47330ea6..4b98d92a 100644 --- a/psutil/arch/osx/process_info.c +++ b/psutil/arch/osx/process_info.c @@ -161,7 +161,8 @@ psutil_is_zombie(pid_t pid) { // return process args as a python list PyObject * -psutil_get_cmdline(pid_t pid) { +psutil_proc_cmdline(PyObject *self, PyObject *args) { + pid_t pid; int nargs; size_t len; char *procargs = NULL; @@ -169,13 +170,17 @@ psutil_get_cmdline(pid_t pid) { char *arg_end; char *curr_arg; size_t argmax; - + PyObject *py_retlist = PyList_New(0); PyObject *py_arg = NULL; - PyObject *py_retlist = NULL; + + if (py_retlist == NULL) + return NULL; + if (! PyArg_ParseTuple(args, _Py_PARSE_PID, &pid)) + goto error; // special case for PID 0 (kernel_task) where cmdline cannot be fetched if (pid == 0) - return Py_BuildValue("[]"); + return py_retlist; // read argmax and allocate memory for argument space. argmax = psutil_sysctl_argmax(); @@ -201,7 +206,7 @@ psutil_get_cmdline(pid_t pid) { if (arg_ptr == arg_end) { free(procargs); - return Py_BuildValue("[]"); + return py_retlist; } // skip ahead to the first argument @@ -212,9 +217,6 @@ psutil_get_cmdline(pid_t pid) { // iterate through arguments curr_arg = arg_ptr; - py_retlist = Py_BuildValue("[]"); - if (!py_retlist) - goto error; while (arg_ptr < arg_end && nargs > 0) { if (*arg_ptr++ == '\0') { py_arg = PyUnicode_DecodeFSDefault(curr_arg); @@ -250,7 +252,8 @@ error: // * caller has an entitlement // See: https://github.com/apple/darwin-xnu/blob/2ff845c2e033bd0ff64b5b6aa6063a1f8f65aa32/bsd/kern/kern_sysctl.c#L1315-L1321 PyObject * -psutil_get_environ(pid_t pid) { +psutil_proc_environ(PyObject *self, PyObject *args) { + pid_t pid; int nargs; char *procargs = NULL; char *procenv = NULL; @@ -260,6 +263,9 @@ psutil_get_environ(pid_t pid) { size_t argmax; PyObject *py_ret = NULL; + if (! PyArg_ParseTuple(args, _Py_PARSE_PID, &pid)) + return NULL; + // special case for PID 0 (kernel_task) where cmdline cannot be fetched if (pid == 0) goto empty; diff --git a/psutil/arch/osx/process_info.h b/psutil/arch/osx/process_info.h index ffa6230f..08046bcb 100644 --- a/psutil/arch/osx/process_info.h +++ b/psutil/arch/osx/process_info.h @@ -13,5 +13,6 @@ int psutil_get_kinfo_proc(pid_t pid, struct kinfo_proc *kp); int psutil_get_proc_list(kinfo_proc **procList, size_t *procCount); int psutil_proc_pidinfo( pid_t pid, int flavor, uint64_t arg, void *pti, int size); -PyObject* psutil_get_cmdline(pid_t pid); -PyObject* psutil_get_environ(pid_t pid); + +PyObject *psutil_proc_cmdline(PyObject *self, PyObject *args); +PyObject *psutil_proc_environ(PyObject *self, PyObject *args); diff --git a/psutil/arch/windows/process_info.c b/psutil/arch/windows/process_info.c index 1981d306..7a227d4d 100644 --- a/psutil/arch/windows/process_info.c +++ b/psutil/arch/windows/process_info.c @@ -24,6 +24,13 @@ typedef NTSTATUS (NTAPI *__NtQueryInformationProcess)( PDWORD ReturnLength); #endif +#define PSUTIL_FIRST_PROCESS(Processes) ( \ + (PSYSTEM_PROCESS_INFORMATION)(Processes)) +#define PSUTIL_NEXT_PROCESS(Process) ( \ + ((PSYSTEM_PROCESS_INFORMATION)(Process))->NextEntryOffset ? \ + (PSYSTEM_PROCESS_INFORMATION)((PCHAR)(Process) + \ + ((PSYSTEM_PROCESS_INFORMATION)(Process))->NextEntryOffset) : NULL) + /* * Given a pointer into a process's memory, figure out how much @@ -535,15 +542,38 @@ error: * with given pid or NULL on error. */ PyObject * -psutil_get_cmdline(DWORD pid, int use_peb) { - PyObject *ret = NULL; +psutil_proc_cmdline(PyObject *self, PyObject *args, PyObject *kwdict) { WCHAR *data = NULL; + LPWSTR *szArglist = NULL; SIZE_T size; + int nArgs; + int i; + int func_ret; + DWORD pid; + int pid_return; + int use_peb; + // TODO: shouldn't this be decref-ed in case of error on + // PyArg_ParseTuple? + PyObject *py_usepeb = Py_True; PyObject *py_retlist = NULL; PyObject *py_unicode = NULL; - LPWSTR *szArglist = NULL; - int nArgs, i; - int func_ret; + static char *keywords[] = {"pid", "use_peb", NULL}; + + if (! PyArg_ParseTupleAndKeywords(args, kwdict, _Py_PARSE_PID "|O", + keywords, &pid, &py_usepeb)) + { + return NULL; + } + if ((pid == 0) || (pid == 4)) + return Py_BuildValue("[]"); + + pid_return = psutil_pid_is_running(pid); + if (pid_return == 0) + return NoSuchProcess("psutil_pid_is_running -> 0"); + if (pid_return == -1) + return NULL; + + use_peb = (py_usepeb == Py_True) ? 1 : 0; /* Reading the PEB to get the cmdline seem to be the best method if @@ -559,47 +589,60 @@ psutil_get_cmdline(DWORD pid, int use_peb) { else func_ret = psutil_cmdline_query_proc(pid, &data, &size); if (func_ret != 0) - goto out; + goto error; // attempt to parse the command line using Win32 API szArglist = CommandLineToArgvW(data, &nArgs); if (szArglist == NULL) { PyErr_SetFromOSErrnoWithSyscall("CommandLineToArgvW"); - goto out; + goto error; } // arglist parsed as array of UNICODE_STRING, so convert each to // Python string object and add to arg list py_retlist = PyList_New(nArgs); if (py_retlist == NULL) - goto out; + goto error; for (i = 0; i < nArgs; i++) { py_unicode = PyUnicode_FromWideChar(szArglist[i], wcslen(szArglist[i])); if (py_unicode == NULL) - goto out; + goto error; PyList_SetItem(py_retlist, i, py_unicode); py_unicode = NULL; } - ret = py_retlist; - py_retlist = NULL; -out: + LocalFree(szArglist); + free(data); + return py_retlist; + +error: if (szArglist != NULL) LocalFree(szArglist); if (data != NULL) free(data); Py_XDECREF(py_unicode); Py_XDECREF(py_retlist); - return ret; + return NULL; } PyObject * -psutil_get_cwd(DWORD pid) { +psutil_proc_cwd(PyObject *self, PyObject *args) { + DWORD pid; PyObject *ret = NULL; WCHAR *data = NULL; SIZE_T size; + int pid_return; + + if (! PyArg_ParseTuple(args, _Py_PARSE_PID, &pid)) + return NULL; + + pid_return = psutil_pid_is_running(pid); + if (pid_return == 0) + return NoSuchProcess("psutil_pid_is_running -> 0"); + if (pid_return == -1) + return NULL; if (psutil_get_process_data(pid, KIND_CWD, &data, &size) != 0) goto out; @@ -620,10 +663,23 @@ out: * process with given pid or NULL on error. */ PyObject * -psutil_get_environ(DWORD pid) { - PyObject *ret = NULL; +psutil_proc_environ(PyObject *self, PyObject *args) { + DWORD pid; WCHAR *data = NULL; SIZE_T size; + int pid_return; + PyObject *ret = NULL; + + if (! PyArg_ParseTuple(args, _Py_PARSE_PID, &pid)) + return NULL; + if ((pid == 0) || (pid == 4)) + return Py_BuildValue("s", ""); + + pid_return = psutil_pid_is_running(pid); + if (pid_return == 0) + return NoSuchProcess("psutil_pid_is_running -> 0"); + if (pid_return == -1) + return NULL; if (psutil_get_process_data(pid, KIND_ENVIRON, &data, &size) != 0) goto out; diff --git a/psutil/arch/windows/process_info.h b/psutil/arch/windows/process_info.h index 5e89ddeb..26190427 100644 --- a/psutil/arch/windows/process_info.h +++ b/psutil/arch/windows/process_info.h @@ -15,7 +15,7 @@ int psutil_get_proc_info(DWORD pid, PSYSTEM_PROCESS_INFORMATION *retProcess, PVOID *retBuffer); -PyObject* psutil_get_cmdline(DWORD pid, int use_peb); -PyObject* psutil_get_cwd(DWORD pid); -PyObject* psutil_get_environ(DWORD pid); +PyObject* psutil_proc_cmdline(PyObject *self, PyObject *args, PyObject *kwdict); +PyObject* psutil_proc_cwd(PyObject *self, PyObject *args); +PyObject* psutil_proc_environ(PyObject *self, PyObject *args); PyObject* psutil_proc_info(PyObject *self, PyObject *args); diff --git a/psutil/tests/test_memleaks.py b/psutil/tests/test_memleaks.py old mode 100755 new mode 100644 -- cgit v1.2.1