Skip to content

Commit

Permalink
Properly handle PID type in C (#1672)
Browse files Browse the repository at this point in the history
  • Loading branch information
giampaolo authored Jan 28, 2020
1 parent 0e8e5a9 commit 994c429
Show file tree
Hide file tree
Showing 32 changed files with 301 additions and 245 deletions.
1 change: 1 addition & 0 deletions HISTORY.rst
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ XXXX-XX-XX
- 1662_: [Windows] process exe() may raise WinError 0.
- 1665_: [Linux] disk_io_counters() does not take into account extra fields
added to recent kernels. (patch by Mike Hommey)
- 1672_: properly handle PID C type.
- 1673_: [OpenBSD] Process connections(), num_fds() and threads() returned
improper exception if process is gone.

Expand Down
2 changes: 1 addition & 1 deletion INSTALL.rst
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ OpenBSD
::

export PKG_PATH=http://ftp.eu.openbsd.org/pub/OpenBSD/`uname -r`/packages/`uname -m`/
pkg_add -v python3 gcc
pkg_add -v python gcc
python3 -m pip install psutil

NetBSD
Expand Down
1 change: 0 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ DEPS = \
ipaddress \
mock==1.0.1 \
pyperf \
readline \
requests \
setuptools \
sphinx \
Expand Down
8 changes: 1 addition & 7 deletions appveyor.yml
Original file line number Diff line number Diff line change
Expand Up @@ -99,12 +99,6 @@ only_commits:
- psutil/_psutil_windows.*
- psutil/_pswindows.py
- psutil/arch/windows/*
- psutil/tests/__init__.py
- psutil/tests/__main__.py
- psutil/tests/test_memory_leaks.py
- psutil/tests/test_misc.py
- psutil/tests/test_process.py
- psutil/tests/test_system.py
- psutil/tests/test_windows.py
- psutil/tests/*
- scripts/*
- setup.py
4 changes: 1 addition & 3 deletions psutil/_pslinux.py
Original file line number Diff line number Diff line change
Expand Up @@ -1213,7 +1213,7 @@ def sensors_temperatures():
current = float(cat(path)) / 1000.0
path = os.path.join(os.path.dirname(base), 'name')
unit_name = cat(path, binary=False)
except (IOError, OSError, ValueError) as err:
except (IOError, OSError, ValueError):
# A lot of things can go wrong here, so let's just skip the
# whole entry. Sure thing is Linux's /sys/class/hwmon really
# is a stinky broken mess.
Expand All @@ -1222,8 +1222,6 @@ def sensors_temperatures():
# https://github.com/giampaolo/psutil/issues/1129
# https://github.com/giampaolo/psutil/issues/1245
# https://github.com/giampaolo/psutil/issues/1323
warnings.warn("ignoring %r for file %r" % (err, path),
RuntimeWarning)
continue

high = cat(base + '_max', fallback=None)
Expand Down
63 changes: 40 additions & 23 deletions psutil/_psutil_bsd.c
Original file line number Diff line number Diff line change
Expand Up @@ -132,9 +132,9 @@ psutil_pids(PyObject *self, PyObject *args) {
orig_address = proclist; // save so we can free it after we're done
for (idx = 0; idx < num_processes; idx++) {
#ifdef PSUTIL_FREEBSD
py_pid = Py_BuildValue("i", proclist->ki_pid);
py_pid = PyLong_FromPid(proclist->ki_pid);
#elif defined(PSUTIL_OPENBSD) || defined(PSUTIL_NETBSD)
py_pid = Py_BuildValue("i", proclist->p_pid);
py_pid = PyLong_FromPid(proclist->p_pid);
#endif
if (!py_pid)
goto error;
Expand Down Expand Up @@ -180,7 +180,7 @@ psutil_boot_time(PyObject *self, PyObject *args) {
*/
static PyObject *
psutil_proc_oneshot_info(PyObject *self, PyObject *args) {
long pid;
pid_t pid;
long rss;
long vms;
long memtext;
Expand All @@ -191,9 +191,10 @@ psutil_proc_oneshot_info(PyObject *self, PyObject *args) {
long pagesize = sysconf(_SC_PAGESIZE);
char str[1000];
PyObject *py_name;
PyObject *py_ppid;
PyObject *py_retlist;

if (! PyArg_ParseTuple(args, "l", &pid))
if (! PyArg_ParseTuple(args, _Py_PARSE_PID, &pid))
return NULL;
if (psutil_kinfo_proc(pid, &kp) == -1)
return NULL;
Expand Down Expand Up @@ -255,16 +256,25 @@ psutil_proc_oneshot_info(PyObject *self, PyObject *args) {
oncpu = -1;
#endif

#ifdef PSUTIL_FREEBSD
py_ppid = PyLong_FromPid(kp.ki_ppid);
#elif defined(PSUTIL_OPENBSD) || defined(PSUTIL_NETBSD)
py_ppid = PyLong_FromPid(kp.p_ppid);
#else
py_ppid = Py_BuildfValue(-1);
#endif
if (! py_ppid)
return NULL;

// Return a single big tuple with all process info.
py_retlist = Py_BuildValue(
#if defined(__FreeBSD_version) && __FreeBSD_version >= 1200031
"(lillllllLdllllddddlllllbO)",
"(OillllllLdllllddddlllllbO)",
#else
"(lillllllidllllddddlllllbO)",
"(OillllllidllllddddlllllbO)",
#endif
#ifdef PSUTIL_FREEBSD
//
(long)kp.ki_ppid, // (long) ppid
py_ppid, // (pid_t) ppid
(int)kp.ki_stat, // (int) status
// UIDs
(long)kp.ki_ruid, // (long) real uid
Expand Down Expand Up @@ -297,8 +307,7 @@ psutil_proc_oneshot_info(PyObject *self, PyObject *args) {
// others
oncpu, // (int) the CPU we are on
#elif defined(PSUTIL_OPENBSD) || defined(PSUTIL_NETBSD)
//
(long)kp.p_ppid, // (long) ppid
py_ppid, // (pid_t) ppid
(int)kp.p_stat, // (int) status
// UIDs
(long)kp.p_ruid, // (long) real uid
Expand Down Expand Up @@ -337,6 +346,7 @@ psutil_proc_oneshot_info(PyObject *self, PyObject *args) {
);

Py_DECREF(py_name);
Py_DECREF(py_ppid);
return py_retlist;
}

Expand All @@ -346,11 +356,11 @@ psutil_proc_oneshot_info(PyObject *self, PyObject *args) {
*/
static PyObject *
psutil_proc_name(PyObject *self, PyObject *args) {
long pid;
pid_t pid;
kinfo_proc kp;
char str[1000];

if (! PyArg_ParseTuple(args, "l", &pid))
if (! PyArg_ParseTuple(args, _Py_PARSE_PID, &pid))
return NULL;
if (psutil_kinfo_proc(pid, &kp) == -1)
return NULL;
Expand All @@ -369,10 +379,10 @@ psutil_proc_name(PyObject *self, PyObject *args) {
*/
static PyObject *
psutil_proc_cmdline(PyObject *self, PyObject *args) {
long pid;
pid_t pid;
PyObject *py_retlist = NULL;

if (! PyArg_ParseTuple(args, "l", &pid))
if (! PyArg_ParseTuple(args, _Py_PARSE_PID, &pid))
return NULL;
py_retlist = psutil_get_cmdline(pid);
if (py_retlist == NULL)
Expand Down Expand Up @@ -442,7 +452,7 @@ psutil_cpu_times(PyObject *self, PyObject *args) {
#if (defined(__FreeBSD_version) && __FreeBSD_version >= 800000) || PSUTIL_OPENBSD || defined(PSUTIL_NETBSD)
static PyObject *
psutil_proc_open_files(PyObject *self, PyObject *args) {
long pid;
pid_t pid;
int i;
int cnt;
int regular;
Expand All @@ -457,7 +467,7 @@ psutil_proc_open_files(PyObject *self, PyObject *args) {

if (py_retlist == NULL)
return NULL;
if (! PyArg_ParseTuple(args, "l", &pid))
if (! PyArg_ParseTuple(args, _Py_PARSE_PID, &pid))
goto error;
if (psutil_kinfo_proc(pid, &kipp) == -1)
goto error;
Expand Down Expand Up @@ -786,6 +796,7 @@ psutil_users(PyObject *self, PyObject *args) {
PyObject *py_tty = NULL;
PyObject *py_hostname = NULL;
PyObject *py_tuple = NULL;
PyObject *py_pid = NULL;

if (py_retlist == NULL)
return NULL;
Expand Down Expand Up @@ -823,7 +834,7 @@ psutil_users(PyObject *self, PyObject *args) {
#ifdef PSUTIL_OPENBSD
-1 // process id (set to None later)
#else
ut.ut_pid // process id
ut.ut_pid // TODO: use PyLong_FromPid
#endif
);
if (!py_tuple) {
Expand Down Expand Up @@ -856,17 +867,21 @@ psutil_users(PyObject *self, PyObject *args) {
py_hostname = PyUnicode_DecodeFSDefault(utx->ut_host);
if (! py_hostname)
goto error;
#ifdef PSUTIL_OPENBSD
py_pid = Py_BuildValue("i", -1); // set to None later
#else
py_pid = PyLong_FromPid(utx->ut_pid);
#endif
if (! py_pid)
goto error;

py_tuple = Py_BuildValue(
"(OOOfi)",
"(OOOfO)",
py_username, // username
py_tty, // tty
py_hostname, // hostname
(float)utx->ut_tv.tv_sec, // start time
#ifdef PSUTIL_OPENBSD
-1 // process id (set to None later)
#else
utx->ut_pid // process id
#endif
py_pid // process id
);

if (!py_tuple) {
Expand All @@ -881,6 +896,7 @@ psutil_users(PyObject *self, PyObject *args) {
Py_CLEAR(py_tty);
Py_CLEAR(py_hostname);
Py_CLEAR(py_tuple);
Py_CLEAR(py_pid);
}

endutxent();
Expand All @@ -892,6 +908,7 @@ psutil_users(PyObject *self, PyObject *args) {
Py_XDECREF(py_tty);
Py_XDECREF(py_hostname);
Py_XDECREF(py_tuple);
Py_XDECREF(py_pid);
Py_DECREF(py_retlist);
return NULL;
}
Expand Down
2 changes: 1 addition & 1 deletion psutil/_psutil_common.c
Original file line number Diff line number Diff line change
Expand Up @@ -235,7 +235,7 @@ psutil_loadlibs() {
// --- Mandatory
NtQuerySystemInformation = psutil_GetProcAddressFromLib(
"ntdll.dll", "NtQuerySystemInformation");
if (NtQuerySystemInformation == NULL)
if (! NtQuerySystemInformation)
return 1;
NtQueryInformationProcess = psutil_GetProcAddress(
"ntdll.dll", "NtQueryInformationProcess");
Expand Down
39 changes: 38 additions & 1 deletion psutil/_psutil_common.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,14 +23,51 @@ static const int PSUTIL_CONN_NONE = 128;
PyObject* PyUnicode_DecodeFSDefault(char *s);
PyObject* PyUnicode_DecodeFSDefaultAndSize(char *s, Py_ssize_t size);
#endif
PyObject* PyErr_SetFromOSErrnoWithSyscall(const char *syscall);

// Python 2: SIZEOF_PID_T not defined but _getpid() returns an int.
#if defined(PSUTIL_WINDOWS) && !defined(SIZEOF_PID_T)
#define SIZEOF_PID_T SIZEOF_INT
#endif

#if !defined(_Py_PARSE_PID) || PY_MAJOR_VERSION < 3
#if !defined(SIZEOF_PID_T) || !defined(SIZEOF_INT) || !defined(SIZEOF_LONG)
#error "missing SIZEOF* definition"
#endif
#endif

// _Py_PARSE_PID is Python 3 only, but since it's private make sure it's
// always present.
#ifndef _Py_PARSE_PID
#if SIZEOF_PID_T == SIZEOF_INT
#define _Py_PARSE_PID "i"
#elif SIZEOF_PID_T == SIZEOF_LONG
#define _Py_PARSE_PID "l"
#elif defined(SIZEOF_LONG_LONG) && SIZEOF_PID_T == SIZEOF_LONG_LONG
#define _Py_PARSE_PID "L"
#else
#error "_Py_PARSE_PID: sizeof(pid_t) is neither sizeof(int), "
"sizeof(long) or sizeof(long long)"
#endif
#endif

#if PY_MAJOR_VERSION < 3
#if ((SIZEOF_PID_T == SIZEOF_INT) || (SIZEOF_PID_T == SIZEOF_LONG))
#define PyLong_FromPid PyInt_FromLong
#elif defined(SIZEOF_LONG_LONG) && SIZEOF_PID_T == SIZEOF_LONG_LONG
#define PyLong_FromPid PyLong_FromLongLong
#else
#error "PyLong_FromPid: sizeof(pid_t) is neither sizeof(int), "
"sizeof(long) or sizeof(long long)"
#endif
#endif

// ====================================================================
// --- Custom exceptions
// ====================================================================

PyObject* AccessDenied(const char *msg);
PyObject* NoSuchProcess(const char *msg);
PyObject* PyErr_SetFromOSErrnoWithSyscall(const char *syscall);

// ====================================================================
// --- Global utils
Expand Down
27 changes: 16 additions & 11 deletions psutil/_psutil_linux.c
Original file line number Diff line number Diff line change
Expand Up @@ -97,9 +97,9 @@ ioprio_set(int which, int who, int ioprio) {
*/
static PyObject *
psutil_proc_ioprio_get(PyObject *self, PyObject *args) {
long pid;
pid_t pid;
int ioprio, ioclass, iodata;
if (! PyArg_ParseTuple(args, "l", &pid))
if (! PyArg_ParseTuple(args, _Py_PARSE_PID, &pid))
return NULL;
ioprio = ioprio_get(IOPRIO_WHO_PROCESS, pid);
if (ioprio == -1)
Expand All @@ -117,12 +117,14 @@ psutil_proc_ioprio_get(PyObject *self, PyObject *args) {
*/
static PyObject *
psutil_proc_ioprio_set(PyObject *self, PyObject *args) {
long pid;
pid_t pid;
int ioprio, ioclass, iodata;
int retval;

if (! PyArg_ParseTuple(args, "lii", &pid, &ioclass, &iodata))
if (! PyArg_ParseTuple(
args, _Py_PARSE_PID "ii", &pid, &ioclass, &iodata)) {
return NULL;
}
ioprio = IOPRIO_PRIO_VALUE(ioclass, iodata);
retval = ioprio_set(IOPRIO_WHO_PROCESS, pid, ioprio);
if (retval == -1)
Expand All @@ -140,15 +142,17 @@ psutil_proc_ioprio_set(PyObject *self, PyObject *args) {
*/
static PyObject *
psutil_linux_prlimit(PyObject *self, PyObject *args) {
long pid;
pid_t pid;
int ret, resource;
struct rlimit old, new;
struct rlimit *newp = NULL;
PyObject *py_soft = NULL;
PyObject *py_hard = NULL;

if (! PyArg_ParseTuple(args, "li|OO", &pid, &resource, &py_soft, &py_hard))
if (! PyArg_ParseTuple(args, _Py_PARSE_PID "i|OO", &pid, &resource,
&py_soft, &py_hard)) {
return NULL;
}

// get
if (py_soft == NULL && py_hard == NULL) {
Expand Down Expand Up @@ -290,12 +294,12 @@ psutil_linux_sysinfo(PyObject *self, PyObject *args) {
static PyObject *
psutil_proc_cpu_affinity_get(PyObject *self, PyObject *args) {
int cpu, ncpus, count, cpucount_s;
long pid;
pid_t pid;
size_t setsize;
cpu_set_t *mask = NULL;
PyObject *py_list = NULL;

if (!PyArg_ParseTuple(args, "l", &pid))
if (!PyArg_ParseTuple(args, _Py_PARSE_PID, &pid))
return NULL;
ncpus = NCPUS_START;
while (1) {
Expand Down Expand Up @@ -358,12 +362,12 @@ static PyObject *
psutil_proc_cpu_affinity_set(PyObject *self, PyObject *args) {
cpu_set_t cpu_set;
size_t len;
long pid;
pid_t pid;
int i, seq_len;
PyObject *py_cpu_set;
PyObject *py_cpu_seq = NULL;

if (!PyArg_ParseTuple(args, "lO", &pid, &py_cpu_set))
if (!PyArg_ParseTuple(args, _Py_PARSE_PID "O", &pid, &py_cpu_set))
return NULL;

if (!PySequence_Check(py_cpu_set)) {
Expand Down Expand Up @@ -441,8 +445,9 @@ psutil_users(PyObject *self, PyObject *args) {
py_hostname = PyUnicode_DecodeFSDefault(ut->ut_host);
if (! py_hostname)
goto error;

py_tuple = Py_BuildValue(
"(OOOfOi)",
"OOOfO" _Py_PARSE_PID,
py_username, // username
py_tty, // tty
py_hostname, // hostname
Expand Down
Loading

0 comments on commit 994c429

Please sign in to comment.