1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120
|
/*
* Copyright (c) 2009, Giampaolo Rodola'. All rights reserved.
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#include <signal.h>
#include <sys/resource.h>
#include "../../arch/all/init.h"
// Check if PID exists. Return values:
// 1: exists
// 0: does not exist
// -1: error (Python exception is set)
int
psutil_pid_exists(pid_t pid) {
int ret;
// No negative PID exists, plus -1 is an alias for sending signal
// too all processes except system ones. Not what we want.
if (pid < 0)
return 0;
// As per "man 2 kill" PID 0 is an alias for sending the signal to
// every process in the process group of the calling process.
// Not what we want. Some platforms have PID 0, some do not.
// We decide that at runtime.
if (pid == 0) {
#if defined(PSUTIL_LINUX) || defined(PSUTIL_FREEBSD)
return 0;
#else
return 1;
#endif
}
ret = kill(pid , 0);
if (ret == 0)
return 1;
else {
if (errno == ESRCH) {
// ESRCH == No such process
return 0;
}
else if (errno == EPERM) {
// EPERM clearly indicates there's a process to deny
// access to.
return 1;
}
else {
// According to "man 2 kill" possible error values are
// (EINVAL, EPERM, ESRCH) therefore we should never get
// here. If we do let's be explicit in considering this
// an error.
PyErr_SetFromErrno(PyExc_OSError);
return -1;
}
}
}
// Utility used for those syscalls which do not return a meaningful
// error that we can translate into an exception which makes sense. As
// such, we'll have to guess. On UNIX, if errno is set, we return that
// one (OSError). Else, if PID does not exist we assume the syscall
// failed because of that so we raise NoSuchProcess. If none of this is
// true we giveup and raise RuntimeError(msg). This will always set a
// Python exception and return NULL.
void
psutil_raise_for_pid(pid_t pid, char *syscall) {
if (errno != 0)
psutil_PyErr_SetFromOSErrnoWithSyscall(syscall);
else if (psutil_pid_exists(pid) == 0)
NoSuchProcess(syscall);
else
PyErr_Format(PyExc_RuntimeError, "%s syscall failed", syscall);
}
// Get PID priority.
PyObject *
psutil_posix_getpriority(PyObject *self, PyObject *args) {
pid_t pid;
int priority;
errno = 0;
if (! PyArg_ParseTuple(args, _Py_PARSE_PID, &pid))
return NULL;
#ifdef PSUTIL_OSX
priority = getpriority(PRIO_PROCESS, (id_t)pid);
#else
priority = getpriority(PRIO_PROCESS, pid);
#endif
if (errno != 0)
return PyErr_SetFromErrno(PyExc_OSError);
return Py_BuildValue("i", priority);
}
// Set PID priority.
PyObject *
psutil_posix_setpriority(PyObject *self, PyObject *args) {
pid_t pid;
int priority;
int retval;
if (! PyArg_ParseTuple(args, _Py_PARSE_PID "i", &pid, &priority))
return NULL;
#ifdef PSUTIL_OSX
retval = setpriority(PRIO_PROCESS, (id_t)pid, priority);
#else
retval = setpriority(PRIO_PROCESS, pid, priority);
#endif
if (retval == -1)
return PyErr_SetFromErrno(PyExc_OSError);
Py_RETURN_NONE;
}
|