File: proc.c

package info (click to toggle)
python-psutil 7.1.0-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 4,312 kB
  • sloc: python: 19,411; ansic: 15,378; makefile: 465; javascript: 153; sh: 54
file content (120 lines) | stat: -rw-r--r-- 3,301 bytes parent folder | download
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;
}