Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit c7f13dd

Browse files
authored
Refact psutil_pids() C code (#2656)
psutil_pids() is now a single python wrapper which calls _psutil_pids(), which returns an array, and builds a Python list with that array.
1 parent e1449d6 commit c7f13dd

22 files changed

Lines changed: 364 additions & 330 deletions

File tree

MANIFEST.in

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ include psutil/arch/aix/net_connections.h
4747
include psutil/arch/aix/net_kernel_structs.h
4848
include psutil/arch/all/init.c
4949
include psutil/arch/all/init.h
50+
include psutil/arch/all/pids.c
5051
include psutil/arch/bsd/cpu.c
5152
include psutil/arch/bsd/disk.c
5253
include psutil/arch/bsd/init.c
@@ -58,6 +59,7 @@ include psutil/arch/freebsd/cpu.c
5859
include psutil/arch/freebsd/disk.c
5960
include psutil/arch/freebsd/init.h
6061
include psutil/arch/freebsd/mem.c
62+
include psutil/arch/freebsd/pids.c
6163
include psutil/arch/freebsd/proc.c
6264
include psutil/arch/freebsd/proc_socks.c
6365
include psutil/arch/freebsd/sensors.c
@@ -71,12 +73,14 @@ include psutil/arch/netbsd/cpu.c
7173
include psutil/arch/netbsd/disk.c
7274
include psutil/arch/netbsd/init.h
7375
include psutil/arch/netbsd/mem.c
76+
include psutil/arch/netbsd/pids.c
7477
include psutil/arch/netbsd/proc.c
7578
include psutil/arch/netbsd/socks.c
7679
include psutil/arch/openbsd/cpu.c
7780
include psutil/arch/openbsd/disk.c
7881
include psutil/arch/openbsd/init.h
7982
include psutil/arch/openbsd/mem.c
83+
include psutil/arch/openbsd/pids.c
8084
include psutil/arch/openbsd/proc.c
8185
include psutil/arch/openbsd/socks.c
8286
include psutil/arch/openbsd/users.c
@@ -86,6 +90,7 @@ include psutil/arch/osx/init.c
8690
include psutil/arch/osx/init.h
8791
include psutil/arch/osx/mem.c
8892
include psutil/arch/osx/net.c
93+
include psutil/arch/osx/pids.c
8994
include psutil/arch/osx/proc.c
9095
include psutil/arch/osx/sensors.c
9196
include psutil/arch/osx/sys.c
@@ -110,6 +115,7 @@ include psutil/arch/windows/init.h
110115
include psutil/arch/windows/mem.c
111116
include psutil/arch/windows/net.c
112117
include psutil/arch/windows/ntextapi.h
118+
include psutil/arch/windows/pids.c
113119
include psutil/arch/windows/proc.c
114120
include psutil/arch/windows/proc_handles.c
115121
include psutil/arch/windows/proc_info.c

psutil/arch/all/init.h

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@
2626
#include "../../arch/osx/init.h"
2727
#elif defined(PSUTIL_FREEBSD)
2828
#include "../../arch/freebsd/init.h"
29-
#elif defined(PSUTIL_OPENSBD)
29+
#elif defined(PSUTIL_OPENBSD)
3030
#include "../../arch/openbsd/init.h"
3131
#elif defined(PSUTIL_NETBSD)
3232
#include "../../arch/netbsd/init.h"
@@ -66,9 +66,9 @@ extern int PSUTIL_CONN_NONE;
6666
// --- Custom exceptions
6767
// ====================================================================
6868

69-
PyObject* AccessDenied(const char *msg);
70-
PyObject* NoSuchProcess(const char *msg);
71-
PyObject* psutil_PyErr_SetFromOSErrnoWithSyscall(const char *syscall);
69+
PyObject *AccessDenied(const char *msg);
70+
PyObject *NoSuchProcess(const char *msg);
71+
PyObject *psutil_PyErr_SetFromOSErrnoWithSyscall(const char *syscall);
7272

7373
// ====================================================================
7474
// --- Backward compatibility with missing Python.h APIs
@@ -118,6 +118,10 @@ PyObject* psutil_PyErr_SetFromOSErrnoWithSyscall(const char *syscall);
118118
#endif
119119
#endif
120120

121-
PyObject* psutil_set_debug(PyObject *self, PyObject *args);
122-
PyObject* psutil_check_pid_range(PyObject *self, PyObject *args);
121+
#if defined(PSUTIL_WINDOWS) || defined(PSUTIL_BSD) || defined(PSUTIL_OSX)
122+
PyObject *psutil_pids(PyObject *self, PyObject *args);
123+
#endif
124+
125+
PyObject *psutil_set_debug(PyObject *self, PyObject *args);
126+
PyObject *psutil_check_pid_range(PyObject *self, PyObject *args);
123127
int psutil_setup(void);

psutil/arch/all/pids.c

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
/*
2+
* Copyright (c) 2009, Giampaolo Rodola'. All rights reserved.
3+
* Use of this source code is governed by a BSD-style license that can be
4+
* found in the LICENSE file.
5+
*/
6+
7+
#if defined(PSUTIL_WINDOWS) || defined(PSUTIL_BSD) || defined(PSUTIL_OSX)
8+
#include <Python.h>
9+
10+
#include "init.h"
11+
12+
13+
PyObject *
14+
psutil_pids(PyObject *self, PyObject *args) {
15+
#ifdef PSUTIL_WINDOWS
16+
DWORD *pids_array = NULL;
17+
#else
18+
pid_t *pids_array = NULL;
19+
#endif
20+
int pids_count = 0;
21+
int i;
22+
PyObject *py_retlist = PyList_New(0);
23+
PyObject *py_pid = NULL;
24+
25+
if (!py_retlist)
26+
return NULL;
27+
28+
if (_psutil_pids(&pids_array, &pids_count) != 0)
29+
goto error;
30+
31+
if (pids_count == 0) {
32+
PyErr_Format(PyExc_RuntimeError, "no PIDs found");
33+
goto error;
34+
}
35+
36+
for (i = 0; i < pids_count; i++) {
37+
py_pid = PyLong_FromPid(pids_array[i]);
38+
if (!py_pid)
39+
goto error;
40+
if (PyList_Append(py_retlist, py_pid))
41+
goto error;
42+
Py_CLEAR(py_pid);
43+
}
44+
45+
free(pids_array);
46+
return py_retlist;
47+
48+
error:
49+
Py_XDECREF(py_pid);
50+
Py_DECREF(py_retlist);
51+
free(pids_array);
52+
return NULL;
53+
}
54+
#endif

psutil/arch/bsd/init.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@ PyObject *psutil_cpu_count_logical(PyObject *self, PyObject *args);
1919
PyObject *psutil_cpu_times(PyObject *self, PyObject *args);
2020
PyObject *psutil_disk_partitions(PyObject *self, PyObject *args);
2121
PyObject *psutil_net_io_counters(PyObject *self, PyObject *args);
22-
PyObject *psutil_pids(PyObject *self, PyObject *args);
2322
PyObject *psutil_proc_environ(PyObject *self, PyObject *args);
2423
PyObject *psutil_proc_name(PyObject *self, PyObject *args);
2524
PyObject *psutil_proc_oneshot_info(PyObject *self, PyObject *args);

psutil/arch/bsd/proc.c

Lines changed: 0 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -60,58 +60,6 @@ kinfo_getfile(pid_t pid, int *cnt) {
6060
#endif // PSUTIL_HASNT_KINFO_GETFILE
6161

6262

63-
/*
64-
* Return a Python list of all the PIDs running on the system.
65-
*/
66-
PyObject *
67-
psutil_pids(PyObject *self, PyObject *args) {
68-
#ifdef PSUTIL_NETBSD
69-
struct kinfo_proc2 *proclist = NULL;
70-
struct kinfo_proc2 *orig_address = NULL;
71-
#else
72-
struct kinfo_proc *proclist = NULL;
73-
struct kinfo_proc *orig_address = NULL;
74-
#endif
75-
size_t num_processes;
76-
size_t idx;
77-
PyObject *py_retlist = PyList_New(0);
78-
PyObject *py_pid = NULL;
79-
80-
if (py_retlist == NULL)
81-
return NULL;
82-
83-
if (_psutil_pids(&proclist, &num_processes) != 0)
84-
goto error;
85-
86-
if (num_processes > 0) {
87-
orig_address = proclist; // save so we can free it after we're done
88-
for (idx = 0; idx < num_processes; idx++) {
89-
#ifdef PSUTIL_FREEBSD
90-
py_pid = PyLong_FromPid(proclist->ki_pid);
91-
#else
92-
py_pid = PyLong_FromPid(proclist->p_pid);
93-
#endif
94-
if (!py_pid)
95-
goto error;
96-
if (PyList_Append(py_retlist, py_pid))
97-
goto error;
98-
Py_CLEAR(py_pid);
99-
proclist++;
100-
}
101-
free(orig_address);
102-
}
103-
104-
return py_retlist;
105-
106-
error:
107-
Py_XDECREF(py_pid);
108-
Py_DECREF(py_retlist);
109-
if (orig_address != NULL)
110-
free(orig_address);
111-
return NULL;
112-
}
113-
114-
11563
/*
11664
* Collect different info about a process in one shot and return
11765
* them as a big Python tuple.

psutil/arch/freebsd/init.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,8 @@
88
#include <Python.h>
99
#include <sys/user.h>
1010

11+
int _psutil_pids(pid_t **pids_array, int *pids_count);
1112
// TODO: move this stuff. Does not belong here
12-
int _psutil_pids(struct kinfo_proc **proc_list, size_t *proc_count);
1313
int psutil_kinfo_proc(const pid_t pid, struct kinfo_proc *proc);
1414

1515
PyObject *psutil_cpu_freq(PyObject *self, PyObject *args);

psutil/arch/freebsd/pids.c

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
/*
2+
* Copyright (c) 2009, Jay Loden, Giampaolo Rodola'. All rights reserved.
3+
* Use of this source code is governed by a BSD-style license that can be
4+
* found in the LICENSE file.
5+
*/
6+
7+
#include <Python.h>
8+
#include <stdlib.h>
9+
#include <sys/types.h>
10+
#include <sys/sysctl.h>
11+
#include <sys/user.h>
12+
13+
#include "../../arch/all/init.h"
14+
15+
16+
int
17+
_psutil_pids(pid_t **pids_array, int *pids_count) {
18+
int mib[4] = {CTL_KERN, KERN_PROC, KERN_PROC_PROC, 0};
19+
size_t len = 0;
20+
char *buf = NULL;
21+
struct kinfo_proc *proc_list = NULL;
22+
size_t num_procs = 0;
23+
24+
*pids_array = NULL;
25+
*pids_count = 0;
26+
27+
if (psutil_sysctl_malloc(mib, 4, &buf, &len) != 0)
28+
return -1;
29+
30+
if (len == 0) {
31+
PyErr_Format(PyExc_RuntimeError, "no PIDs found");
32+
goto error;
33+
}
34+
35+
proc_list = (struct kinfo_proc *)buf;
36+
num_procs = len / sizeof(struct kinfo_proc);
37+
38+
*pids_array = malloc(num_procs * sizeof(pid_t));
39+
if (!*pids_array) {
40+
PyErr_NoMemory();
41+
goto error;
42+
}
43+
44+
for (size_t i = 0; i < num_procs; i++) {
45+
(*pids_array)[i] = proc_list[i].ki_pid; // FreeBSD PID field
46+
}
47+
48+
*pids_count = (int)num_procs;
49+
free(buf);
50+
return 0;
51+
52+
error:
53+
if (buf != NULL)
54+
free(buf);
55+
return -1;
56+
}

psutil/arch/freebsd/proc.c

Lines changed: 0 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -72,20 +72,6 @@ static void psutil_remove_spaces(char *str) {
7272
// APIS
7373
// ============================================================================
7474

75-
76-
int _psutil_pids(struct kinfo_proc **proc_list, size_t *proc_count) {
77-
int mib[4] = { CTL_KERN, KERN_PROC, KERN_PROC_PROC, 0 };
78-
size_t length = 0;
79-
char *buf = NULL;
80-
81-
if (psutil_sysctl_malloc(mib, 4, &buf, &length) != 0)
82-
return -1;
83-
84-
*proc_list = (struct kinfo_proc *)buf;
85-
*proc_count = length / sizeof(struct kinfo_proc);
86-
return 0;
87-
}
88-
8975
/*
9076
* Borrowed from psi Python System Information project
9177
* Based on code from ps.

psutil/arch/netbsd/init.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,9 @@
99
#include <Python.h>
1010
#include <sys/sysctl.h>
1111

12+
int _psutil_pids(pid_t **pids_array, int *pids_count);
1213
// TODO: refactor this. Does not belong here.
1314
int psutil_kinfo_proc(pid_t pid, struct kinfo_proc2 *proc);
14-
int _psutil_pids(struct kinfo_proc2 **proc_list, size_t *proc_count);
1515
char *psutil_get_cmd_args(pid_t pid, size_t *argsize);
1616

1717
PyObject *psutil_cpu_stats(PyObject *self, PyObject *args);

psutil/arch/netbsd/pids.c

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
/*
2+
* Copyright (c) 2009, Giampaolo Rodola.
3+
* All rights reserved.
4+
* Use of this source code is governed by a BSD-style license that can be
5+
* found in the LICENSE file.
6+
*/
7+
8+
#include <Python.h>
9+
#include <stdlib.h>
10+
#include <kvm.h>
11+
#include <sys/sysctl.h>
12+
13+
14+
int
15+
_psutil_pids(pid_t **pids_array, int *pids_count) {
16+
char errbuf[_POSIX2_LINE_MAX];
17+
kvm_t *kd;
18+
struct kinfo_proc2 *proc_list = NULL;
19+
struct kinfo_proc2 *result;
20+
int cnt;
21+
size_t i;
22+
23+
*pids_array = NULL;
24+
*pids_count = 0;
25+
26+
kd = kvm_openfiles(NULL, NULL, NULL, KVM_NO_FILES, errbuf);
27+
if (kd == NULL) {
28+
PyErr_Format(PyExc_RuntimeError, "kvm_openfiles() failed: %s", errbuf);
29+
return -1;
30+
}
31+
32+
result = kvm_getproc2(kd, KERN_PROC_ALL, 0, sizeof(struct kinfo_proc2), &cnt);
33+
if (result == NULL) {
34+
PyErr_Format(PyExc_RuntimeError, "kvm_getproc2() failed");
35+
kvm_close(kd);
36+
return -1;
37+
}
38+
39+
if (cnt == 0) {
40+
PyErr_Format(PyExc_RuntimeError, "no PIDs found");
41+
kvm_close(kd);
42+
return -1;
43+
}
44+
45+
*pids_array = malloc(cnt * sizeof(pid_t));
46+
if (!*pids_array) {
47+
PyErr_NoMemory();
48+
kvm_close(kd);
49+
return -1;
50+
}
51+
52+
for (i = 0; i < (size_t)cnt; i++) {
53+
(*pids_array)[i] = result[i].p_pid;
54+
}
55+
56+
*pids_count = cnt;
57+
kvm_close(kd);
58+
return 0;
59+
}

0 commit comments

Comments
 (0)