[Python-modules-commits] [python-prctl] 01/14: Import python-prctl_1.6.1.orig.tar.gz

Felix Geyer fgeyer at moszumanska.debian.org
Sat May 6 19:33:46 UTC 2017


This is an automated email from the git hooks/post-receive script.

fgeyer pushed a commit to branch master
in repository python-prctl.

commit 0dfd1a33ab7e05e249322527929b5010a875fc9f
Author: Felix Geyer <fgeyer at debian.org>
Date:   Wed May 3 20:11:49 2017 +0200

    Import python-prctl_1.6.1.orig.tar.gz
---
 PKG-INFO       |  18 ++
 README         |  35 +++
 _prctlmodule.c | 771 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
 docs/Makefile  |  89 +++++++
 docs/conf.py   | 194 ++++++++++++++
 docs/index.rst | 802 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 prctl.py       | 185 +++++++++++++
 securebits.h   |  21 ++
 setup.py       |  74 ++++++
 test_prctl.py  | 385 +++++++++++++++++++++++++++
 10 files changed, 2574 insertions(+)

diff --git a/PKG-INFO b/PKG-INFO
new file mode 100644
index 0000000..28ad399
--- /dev/null
+++ b/PKG-INFO
@@ -0,0 +1,18 @@
+Metadata-Version: 1.1
+Name: python-prctl
+Version: 1.6.1
+Summary: Python(ic) interface to the linux prctl syscall
+Home-page: http://github.com/seveas/python-prctl
+Author: Dennis Kaarsemaker
+Author-email: dennis at kaarsemaker.net
+License: UNKNOWN
+Description: UNKNOWN
+Platform: UNKNOWN
+Classifier: Development Status :: 5 - Production/Stable
+Classifier: Intended Audience :: Developers
+Classifier: License :: OSI Approved :: GNU General Public License (GPL)
+Classifier: Operating System :: POSIX :: Linux
+Classifier: Programming Language :: C
+Classifier: Programming Language :: Python
+Classifier: Programming Language :: Python :: 3
+Classifier: Topic :: Security
diff --git a/README b/README
new file mode 100644
index 0000000..6f8e31b
--- /dev/null
+++ b/README
@@ -0,0 +1,35 @@
+python-prctl -- Control process attributes through prctl
+========================================================
+
+The linux prctl function allows you to control specific characteristics of a
+process' behaviour. Usage of the function is fairly messy though, due to
+limitations in C and linux. This module provides a nice non-messy python(ic)
+interface.
+
+Besides prctl, this library also wraps libcap for complete capability handling
+and allows you to set the process name as seen in ps and top.
+
+See docs/index.rst for the documentation. An HTML version can be found on
+http://packages.python.org/python-prctl/
+
+Quick install instructions
+==========================
+Before installing python-prctl, you need GCC, libc headers and libcap headers.
+On Debian/Ubuntu:
+
+$ sudo apt-get install build-essential libcap-dev
+
+On fedora:
+
+$ sudo yum install gcc glibc-devel libcap-devel
+
+Stable version:
+
+$ sudo easy_install python-prctl
+
+Latest code:
+
+$ git clone http://github.com/seveas/python-prctl
+$ cd python-prctl
+$ python setup.py build
+$ sudo python setup.py install
diff --git a/_prctlmodule.c b/_prctlmodule.c
new file mode 100644
index 0000000..14121c3
--- /dev/null
+++ b/_prctlmodule.c
@@ -0,0 +1,771 @@
+/*
+ * python-pctrl -- python interface to the prctl function
+ * (c)2010-2015 Dennis Kaarsemaker <dennis at kaarsemaker.net
+ * See COPYING for licensing details
+ */
+
+#include <Python.h>
+#if PY_MAJOR_VERSION >= 3
+#define PyInt_FromLong PyLong_FromLong
+#define PyInt_Check PyLong_Check
+#define PyInt_AsLong PyLong_AsLong
+#endif
+#include "securebits.h"
+#include <sys/capability.h>
+#include <sys/prctl.h>
+#include <sys/signal.h>
+
+/* New in 2.6.32, but named and implemented inconsistently. The linux
+ * implementation has two ways of setting the policy to the default, and thus
+ * needs an extra argument. We ignore the first argument and always call
+ * PR_MCE_KILL_SET. This makes our implementation simpler and keeps the prctl
+ * interface more consistent
+ */
+#ifdef PR_MCE_KILL
+#define PR_GET_MCE_KILL PR_MCE_KILL_GET
+#define PR_SET_MCE_KILL PR_MCE_KILL
+#endif
+
+/* New in 2.6.XX (Ubuntu 10.10) */
+#define NOT_SET (-1)
+#ifdef PR_SET_PTRACER
+/* This one has no getter for some reason, but guard agains that being fixed  */
+#ifndef PR_GET_PTRACER
+#define PR_GET_PTRACER NOT_SET
+/* Icky global variable to cache ptracer */
+static int __cached_ptracer = NOT_SET;
+#endif
+#endif
+
+/* This function is not in Python.h, so define it here */
+#if PY_MAJOR_VERSION < 3
+void Py_GetArgcArgv(int*, char***);
+#else
+void Py_GetArgcArgv(int*, wchar_t***);
+#endif
+
+/* The prctl wrapper */
+static PyObject *
+prctl_prctl(PyObject *self, PyObject *args)
+{
+    long option = 0;
+    long arg = 0;
+    char *argstr = NULL;
+    char name[17] = "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0";
+    int result;
+
+    /*
+     * Accept single int, two ints and int+string. That covers all current
+     * prctl possibilities. int+string is required for (and only accepted for)
+     * PR_SET_NAME
+     */
+    if(!PyArg_ParseTuple(args, "l|l", &option, &arg)) {
+        if(!PyArg_ParseTuple(args, "ls", &option, &argstr)) {
+            return NULL;
+        }
+        if(option != PR_SET_NAME) {
+            PyErr_SetString(PyExc_TypeError, "an integer is required");
+            return NULL;
+        }
+        PyErr_Clear();
+    }
+    else {
+        if(option == PR_SET_NAME) {
+            PyErr_SetString(PyExc_TypeError, "a string is required");
+            return NULL;
+        }
+    }
+
+    /* Validate the optional arguments */
+    switch(option) {
+#ifdef PR_CAPBSET_READ
+        case(PR_CAPBSET_READ):
+        case(PR_CAPBSET_DROP):
+            if(!cap_valid(arg)) {
+                PyErr_SetString(PyExc_ValueError, "Unknown capability");
+                return NULL;
+            }
+            break;
+#endif
+        case(PR_SET_DUMPABLE):
+        case(PR_SET_KEEPCAPS):
+            /* Only 0 and 1 are allowed */
+            arg = arg ? 1 : 0;
+            break;
+        case(PR_SET_ENDIAN):
+            if(arg != PR_ENDIAN_LITTLE && arg != PR_ENDIAN_BIG && arg != PR_ENDIAN_PPC_LITTLE) {
+                PyErr_SetString(PyExc_ValueError, "Unknown endianness");
+                return NULL;
+            }
+            break;
+        case(PR_SET_FPEMU):
+            if(arg != PR_FPEMU_NOPRINT && arg != PR_FPEMU_SIGFPE) {
+                PyErr_SetString(PyExc_ValueError, "Unknown floating-point emulation setting");
+                return NULL;
+            }
+            break;
+        case(PR_SET_FPEXC):
+            if(arg & ~(PR_FP_EXC_SW_ENABLE | PR_FP_EXC_DIV | PR_FP_EXC_OVF |
+                       PR_FP_EXC_UND | PR_FP_EXC_RES | PR_FP_EXC_INV |
+                       PR_FP_EXC_DISABLED | PR_FP_EXC_NONRECOV |
+                       PR_FP_EXC_ASYNC | PR_FP_EXC_PRECISE)) {
+                PyErr_SetString(PyExc_ValueError, "Unknown floating-point exception mode");
+                return NULL;
+            }
+            break;
+#ifdef PR_MCE_KILL
+        case(PR_SET_MCE_KILL):
+            if(arg != PR_MCE_KILL_DEFAULT && arg != PR_MCE_KILL_EARLY && arg != PR_MCE_KILL_LATE) {
+                PyErr_SetString(PyExc_ValueError, "Unknown memory corruption kill policy");
+                return NULL;
+            }
+            break;
+#endif
+        case(PR_SET_NAME):
+            if(strlen(argstr) > 16) {
+                /* FIXME: warn */
+            }
+            strncpy(name, argstr, 16);
+            break;
+        case(PR_SET_PDEATHSIG):
+            if(arg < 0 || arg > SIGRTMAX) {
+                PyErr_SetString(PyExc_ValueError, "Unknown signal");
+                return NULL;
+            }
+            break;
+#ifdef PR_SET_SECCOMP
+        case(PR_SET_SECCOMP):
+#ifdef PR_SET_NO_NEW_PRIVS
+        case(PR_SET_NO_NEW_PRIVS):
+#endif
+            if(!arg) {
+                PyErr_SetString(PyExc_ValueError, "Argument must be 1");
+                return NULL;
+            }
+            arg = 1;
+            break;
+#endif
+#ifdef PR_SET_SECUREBITS
+        case(PR_SET_SECUREBITS):
+            if(arg & ~ ((1 << SECURE_NOROOT) | (1 << SECURE_NOROOT_LOCKED) |
+                        (1 << SECURE_NO_SETUID_FIXUP) | (1 << SECURE_NO_SETUID_FIXUP_LOCKED) |
+                        (1 << SECURE_KEEP_CAPS) | (1 << SECURE_KEEP_CAPS_LOCKED))) {
+                PyErr_SetString(PyExc_ValueError, "Invalid securebits set");
+                return NULL;
+            }
+            break;
+#endif
+        case(PR_SET_TIMING):
+            if(arg != PR_TIMING_STATISTICAL && arg != PR_TIMING_TIMESTAMP) {
+                PyErr_SetString(PyExc_ValueError, "Invalid timing constant");
+                return NULL;
+            }
+            break;
+#ifdef PR_SET_TSC
+        case(PR_SET_TSC):
+            if(arg != PR_TSC_ENABLE && arg != PR_TSC_SIGSEGV) {
+                PyErr_SetString(PyExc_ValueError, "Invalid TSC setting");
+                return NULL;
+            }
+            break;
+#endif
+        case(PR_SET_UNALIGN):
+            if(arg != PR_UNALIGN_NOPRINT && arg != PR_UNALIGN_SIGBUS) {
+                PyErr_SetString(PyExc_ValueError, "Invalid TSC setting");
+                return NULL;
+            }
+            break;
+    }
+    /*
+     * Calling prctl
+     * There are 3 basic call modes:
+     * - Setters and getters for which the return value is the result
+     * - Getters for which the result is placed in arg2
+     * - Getters and setters that deal with strings.
+     *
+     * This function takes care of all that and always returns Py_None for
+     * settings or the result of a getter call as a PyInt or PyString.
+     */
+    switch(option) {
+#ifdef PR_CAPBSET_READ
+        case(PR_CAPBSET_READ):
+        case(PR_CAPBSET_DROP):
+#endif
+#ifdef PR_SET_CHILD_SUBREAPER
+        case(PR_SET_CHILD_SUBREAPER):
+#endif
+        case(PR_SET_DUMPABLE):
+        case(PR_GET_DUMPABLE):
+        case(PR_SET_ENDIAN):
+        case(PR_SET_FPEMU):
+        case(PR_SET_FPEXC):
+        case(PR_SET_KEEPCAPS):
+        case(PR_GET_KEEPCAPS):
+#ifdef PR_MCE_KILL
+        case(PR_GET_MCE_KILL):
+#endif
+#ifdef PR_GET_NO_NEW_PRIVS
+        case(PR_GET_NO_NEW_PRIVS):
+        case(PR_SET_NO_NEW_PRIVS):
+#endif
+        case(PR_SET_PDEATHSIG):
+#if defined(PR_GET_PTRACER) && (PR_GET_PTRACER != NOT_SET)
+        case(PR_GET_PTRACER):
+#endif
+#ifdef PR_SET_PTRACER
+        case(PR_SET_PTRACER):
+#endif
+#ifdef PR_SET_SECCOMP
+        case(PR_SET_SECCOMP):
+        case(PR_GET_SECCOMP):
+#endif
+#ifdef PR_SET_SECUREBITS
+        case(PR_SET_SECUREBITS):
+        case(PR_GET_SECUREBITS):
+#endif
+#ifdef PR_GET_TIMERSLACK
+        case(PR_GET_TIMERSLACK):
+        case(PR_SET_TIMERSLACK):
+#endif
+        case(PR_SET_TIMING):
+        case(PR_GET_TIMING):
+#ifdef PR_SET_TSC
+        case(PR_SET_TSC):
+#endif
+        case(PR_SET_UNALIGN):
+            result = prctl(option, arg, 0, 0, 0);
+            if(result < 0) {
+                PyErr_SetFromErrno(PyExc_OSError);
+                return NULL;
+            }
+            switch(option) {
+#ifdef PR_CAPBSET_READ
+                case(PR_CAPBSET_READ):
+#endif
+                case(PR_GET_DUMPABLE):
+                case(PR_GET_KEEPCAPS):
+#ifdef PR_GET_SECCOMP
+                case(PR_GET_SECCOMP):
+#endif
+                case(PR_GET_TIMING):
+                    return PyBool_FromLong(result);
+#ifdef PR_MCE_KILL
+                case(PR_GET_MCE_KILL):
+#endif
+#ifdef PR_GET_NO_NEW_PRIVS
+                case(PR_GET_NO_NEW_PRIVS):
+#endif
+#if defined(PR_GET_PTRACER) && (PR_GET_PTRACER != NOT_SET)
+                case(PR_GET_PTRACER):
+#endif
+#ifdef PR_GET_SECUREBITS
+                case(PR_GET_SECUREBITS):
+#endif
+#ifdef PR_GET_TIMERSLACK
+                case(PR_GET_TIMERSLACK):
+#endif
+                    return PyInt_FromLong(result);
+#if defined(PR_GET_PTRACER) && (PR_GET_PTRACER == NOT_SET)
+                case(PR_SET_PTRACER):
+                    __cached_ptracer = arg;
+                    break;
+#endif
+            }
+            break;
+#ifdef PR_GET_CHILD_SUBREAPER
+        case(PR_GET_CHILD_SUBREAPER):
+#endif
+        case(PR_GET_ENDIAN):
+        case(PR_GET_FPEMU):
+        case(PR_GET_FPEXC):
+        case(PR_GET_PDEATHSIG):
+#ifdef PR_GET_TSC
+        case(PR_GET_TSC):
+#endif
+        case(PR_GET_UNALIGN):
+            result = prctl(option, &arg, 0, 0, 0);
+            if(result < 0) {
+                PyErr_SetFromErrno(PyExc_OSError);
+                return NULL;
+            }
+            return PyInt_FromLong(arg);
+        case(PR_SET_NAME):
+        case(PR_GET_NAME):
+            result = prctl(option, name, 0, 0, 0);
+            if(result < 0) {
+                PyErr_SetFromErrno(PyExc_OSError);
+                return NULL;
+            }
+            if(option == PR_GET_NAME) {
+                return Py_BuildValue("s", name);
+            }
+            break;
+#if defined(PR_GET_PTRACER) && (PR_GET_PTRACER == NOT_SET)
+        case(PR_GET_PTRACER):
+            if(__cached_ptracer == NOT_SET)
+                return PyInt_FromLong(getppid());
+            return PyInt_FromLong(__cached_ptracer);
+#endif
+#ifdef PR_MCE_KILL
+        case(PR_SET_MCE_KILL):
+            result = prctl(option, PR_MCE_KILL_SET, arg, 0, 0);
+            if(result < 0) {
+                PyErr_SetFromErrno(PyExc_OSError);
+                return NULL;
+            }
+            break;
+#endif
+        default:
+            PyErr_SetString(PyExc_ValueError, "Unkown prctl option");
+            return NULL;
+    }
+
+    /* None is returned by default */
+    Py_RETURN_NONE;
+}
+
+/* While not part of prctl, this complements PR_SET_NAME */
+static int __real_argc = -1;
+static char **__real_argv = NULL;
+#if PY_MAJOR_VERSION < 3
+#define _Py_GetArgcArgv Py_GetArgcArgv
+#else
+/* In python 3, Py_GetArgcArgv doesn't actually return the real argv, but an
+ * encoded copy of it. We try to find the real one by going back from the start
+ * of environ.
+ */
+static char * encode(wchar_t *wstr) {
+    PyObject *unicodestr = NULL, *bytesstr = NULL;
+    char *str = NULL;
+
+    unicodestr = PyUnicode_FromWideChar(wstr, -1);
+    if(!unicodestr) {
+        PyErr_Clear();
+        return NULL;
+    }
+
+    bytesstr =  PyUnicode_AsEncodedString(unicodestr, PyUnicode_GetDefaultEncoding(), "strict");
+    if(!bytesstr) {
+        PyErr_Clear();
+        Py_XDECREF(unicodestr);
+        return NULL;
+    }
+
+    str = PyBytes_AsString(bytesstr);
+    Py_XDECREF(unicodestr);
+    Py_XDECREF(bytesstr);
+    return str;
+}
+
+static int _Py_GetArgcArgv(int* argc, char ***argv) {
+    int i = 0;
+    wchar_t **argv_w;
+    char **buf = NULL , *arg0 = NULL, *ptr = 0, *limit = NULL;
+
+    Py_GetArgcArgv(argc, &argv_w);
+
+    buf = (char **)malloc((*argc + 1) * sizeof(char *));
+    buf[*argc] = NULL;
+
+    /* Walk back from environ until you find argc-1 null-terminated strings. */
+    ptr = environ[0] - 1;
+    limit = ptr - 8192;
+    for(i=*argc-1; i >= 1; --i) {
+        ptr--;
+        while (*ptr && ptr-- > limit);
+        if (ptr <= limit) {
+            free(buf);
+            return 0;
+        }
+        buf[i] = (ptr + 1);
+    }
+
+    /* Now try to find argv[0] */
+    arg0 = encode(argv_w[0]);
+    if(!arg0) {
+        free(buf);
+        return 0;
+    }
+    ptr -= strlen(arg0);
+    if(strcmp(ptr, arg0)) {
+        free(buf);
+        return 0;
+    }
+
+    buf[0] = ptr;
+    *argv = buf;
+    return 1;
+}
+#endif
+
+static PyObject *
+prctl_set_proctitle(PyObject *self, PyObject *args)
+{
+    int argc = 0;
+    char **argv;
+    int len;
+    char *title;
+    if(!PyArg_ParseTuple(args, "s", &title)) {
+        return NULL;
+    }
+    if(__real_argc > 0)  {
+        argc = __real_argc;
+        argv = __real_argv;
+    }
+    else {
+        _Py_GetArgcArgv(&argc, &argv);
+        __real_argc = argc;
+        __real_argv = argv;
+    }
+
+    if(argc <= 0) {
+        PyErr_SetString(PyExc_RuntimeError, "Failed to locate argc/argv");
+        return NULL;
+    }
+    /* Determine up to where we can write */
+    len = (size_t)(argv[argc-1]) + strlen(argv[argc-1]) - (size_t)(argv[0]);
+    strncpy(argv[0], title, len);
+    if(strlen(title) < len)
+        memset(argv[0] + strlen(title), 0, len - strlen(title));
+    Py_RETURN_NONE;
+}
+
+/* TODO: Add a getter? */
+
+static PyObject * prctl_get_caps_flag(PyObject *list, cap_t caps, int flag) {
+    int i;
+    PyObject *ret, *item, *val;
+    cap_flag_value_t value;
+
+    if(list && !PySequence_Check(list)) {
+        PyErr_SetString(PyExc_TypeError, "A sequence of integers is required");
+        return NULL;
+    }
+    ret = PyDict_New();
+    if(!list)
+        return ret;
+    for(i=0; i < PyList_Size(list); i++) {
+        item = PyList_GetItem(list, i);
+        if(!PyInt_Check(item)) {
+            PyErr_SetString(PyExc_TypeError, "A sequence of integers is required");
+            return ret; /* Return the list so it can be freed */
+        }
+        if(cap_get_flag(caps, PyInt_AsLong(item), flag, &value) == -1) {
+            PyErr_SetFromErrno(PyExc_OSError);
+            return ret;
+        }
+        val = PyBool_FromLong(value);
+        PyDict_SetItem(ret, item, val);
+        Py_XDECREF(val);
+    }
+    return ret;
+}
+
+static int prctl_set_caps_flag(PyObject *list, cap_t caps, int flag, cap_flag_value_t value) {
+    int i;
+    cap_value_t cap;
+    PyObject *item;
+
+    if(list && !PySequence_Check(list)) {
+        PyErr_SetString(PyExc_TypeError, "A sequence of integers is required");
+        return 0;
+    }
+    if(!list)
+        return 1;
+
+    for(i=0; i < PyList_Size(list); i++) {
+        item = PyList_GetItem(list, i);
+        if(!PyInt_Check(item)) {
+            PyErr_SetString(PyExc_TypeError, "A sequence of integers is required");
+            return 0;
+        }
+        cap = PyInt_AsLong(item);
+        if(cap_set_flag(caps, flag, 1, &cap, value) == -1) {
+            PyErr_SetFromErrno(PyExc_OSError);
+            return 0;
+        }
+    }
+    return 1;
+}
+
+static PyObject * prctl_get_caps(PyObject *self, PyObject *args)
+{
+    PyObject *effective = NULL;
+    PyObject *permitted = NULL;
+    PyObject *inheritable = NULL;
+    PyObject *effective_ = NULL;
+    PyObject *permitted_ = NULL;
+    PyObject *inheritable_ = NULL;
+    PyObject *ret = NULL;
+    PyObject *key = NULL;
+    cap_t caps = NULL;
+
+    if(!PyArg_ParseTuple(args, "O|OO", &effective, &permitted, &inheritable)) {
+        return NULL;
+    }
+    caps = cap_get_proc();
+    if(!caps) {
+        PyErr_SetFromErrno(PyExc_OSError);
+        return NULL;
+    }
+    effective_ = prctl_get_caps_flag(effective, caps, CAP_EFFECTIVE);
+    if(PyErr_Occurred()) goto error;
+    permitted_ = prctl_get_caps_flag(permitted, caps, CAP_PERMITTED);
+    if(PyErr_Occurred()) goto error;
+    inheritable_ = prctl_get_caps_flag(inheritable, caps, CAP_INHERITABLE);
+    if(PyErr_Occurred()) goto error;
+
+    /* Now build the dict */
+    ret = PyDict_New();
+    key = PyInt_FromLong(CAP_EFFECTIVE);
+    PyDict_SetItem(ret, key, effective_);
+    Py_XDECREF(key);
+    key = PyInt_FromLong(CAP_PERMITTED);
+    PyDict_SetItem(ret, key, permitted_);
+    Py_XDECREF(key);
+    key = PyInt_FromLong(CAP_INHERITABLE);
+    PyDict_SetItem(ret, key, inheritable_);
+    Py_XDECREF(key);
+
+error:
+    cap_free(caps);
+    Py_XDECREF(effective_);
+    Py_XDECREF(permitted_);
+    Py_XDECREF(inheritable_);
+
+    return ret;
+}
+
+static PyObject * prctl_set_caps(PyObject *self, PyObject *args)
+{
+    PyObject *effective_set = NULL;
+    PyObject *permitted_set = NULL;
+    PyObject *inheritable_set = NULL;
+    PyObject *effective_clear = NULL;
+    PyObject *permitted_clear = NULL;
+    PyObject *inheritable_clear = NULL;
+    cap_t caps = NULL;
+
+    if(!PyArg_ParseTuple(args, "O|OOOOO", &effective_set, &permitted_set, &inheritable_set,
+                                          &effective_clear, &permitted_clear, &inheritable_clear)) {
+        return NULL;
+    }
+    caps = cap_get_proc();
+    if(!caps) {
+        PyErr_SetFromErrno(PyExc_OSError);
+        return NULL;
+    }
+    if(!prctl_set_caps_flag(effective_set, caps, CAP_EFFECTIVE, CAP_SET))
+        return NULL;
+    if(!prctl_set_caps_flag(permitted_set, caps, CAP_PERMITTED, CAP_SET))
+        return NULL;
+    if(!prctl_set_caps_flag(inheritable_set, caps, CAP_INHERITABLE, CAP_SET))
+        return NULL;
+    if(!prctl_set_caps_flag(effective_clear, caps, CAP_EFFECTIVE, CAP_CLEAR))
+        return NULL;
+    if(!prctl_set_caps_flag(permitted_clear, caps, CAP_PERMITTED, CAP_CLEAR))
+        return NULL;
+    if(!prctl_set_caps_flag(inheritable_clear, caps, CAP_INHERITABLE, CAP_CLEAR))
+        return NULL;
+
+    if(cap_set_proc(caps) == -1) {
+        PyErr_SetFromErrno(PyExc_OSError);
+        return NULL;
+    }
+
+    Py_RETURN_NONE;
+}
+
+#ifdef cap_to_name
+static PyObject * prctl_cap_to_name(PyObject *self, PyObject *args) {
+    cap_value_t cap;
+    char *name;
+    PyObject *ret;
+
+    if(!PyArg_ParseTuple(args, "i", &cap)){
+        return NULL;
+    }
+    name = cap_to_name(cap);
+    if(!name) {
+        PyErr_SetFromErrno(PyExc_OSError);
+        return NULL;
+    }
+    ret = Py_BuildValue("s", name+4); /* Exclude the cap_ prefix */
+    cap_free(name);
+    return ret;
+}
+#endif
+
+static PyMethodDef PrctlMethods[] = {
+    {"get_caps", prctl_get_caps, METH_VARARGS, "Get process capabilities"},
+    {"set_caps", prctl_set_caps, METH_VARARGS, "Set process capabilities"},
+#ifdef cap_to_name
+    {"cap_to_name", prctl_cap_to_name, METH_VARARGS, "Convert capability number to name"},
+#endif
+    {"prctl", prctl_prctl, METH_VARARGS, "Call prctl"},
+    {"set_proctitle", prctl_set_proctitle, METH_VARARGS, "Set the process title"},
+    {NULL, NULL, 0, NULL} /* Sentinel */
+};
+
+#if PY_MAJOR_VERSION >= 3
+static struct PyModuleDef prctlmodule = {
+    PyModuleDef_HEAD_INIT,
+    "_prctl",
+    NULL,
+    -1,
+    PrctlMethods
+};
+#endif
+
+/* These macros avoid tediously repeating a name 2 or 4 times */
+#define namedconstant(x) PyModule_AddIntConstant(_prctl, #x, x)
+#define namedattribute(x) do{ \
+    PyModule_AddIntConstant(_prctl, "PR_GET_" #x,  PR_GET_ ## x); \
+    PyModule_AddIntConstant(_prctl, "PR_SET_" #x,  PR_SET_ ## x); \
+} while(0)
+
+PyMODINIT_FUNC
+#if PY_MAJOR_VERSION < 3
+init_prctl(void)
+#else
+PyInit__prctl(void)
+#endif
+{
+#if PY_MAJOR_VERSION < 3
+    PyObject *_prctl = Py_InitModule("_prctl", PrctlMethods);
+#else
+    PyObject *_prctl = PyModule_Create(&prctlmodule);
+#endif
+    /* Add the PR_* constants */
+#ifdef PR_CAPBSET_READ
+    namedconstant(PR_CAPBSET_READ);
+    namedconstant(PR_CAPBSET_DROP);
+#endif
+    namedattribute(DUMPABLE);
+    namedattribute(ENDIAN);
+    namedconstant(PR_ENDIAN_BIG);
+    namedconstant(PR_ENDIAN_LITTLE);
+    namedconstant(PR_ENDIAN_PPC_LITTLE);
+    namedattribute(FPEMU);
+    namedconstant(PR_FPEMU_NOPRINT);
+    namedconstant(PR_FPEMU_SIGFPE);
+    namedattribute(FPEXC);
+    namedconstant(PR_FP_EXC_SW_ENABLE);
+    namedconstant(PR_FP_EXC_DIV);
+    namedconstant(PR_FP_EXC_OVF);
+    namedconstant(PR_FP_EXC_UND);
+    namedconstant(PR_FP_EXC_RES);
+    namedconstant(PR_FP_EXC_INV);
+    namedconstant(PR_FP_EXC_DISABLED);
+    namedconstant(PR_FP_EXC_NONRECOV);
+    namedconstant(PR_FP_EXC_ASYNC);
+    namedconstant(PR_FP_EXC_PRECISE);
+    namedattribute(KEEPCAPS);
+#ifdef PR_MCE_KILL
+    namedattribute(MCE_KILL);
+    namedconstant(PR_MCE_KILL_DEFAULT);
+    namedconstant(PR_MCE_KILL_EARLY);
+    namedconstant(PR_MCE_KILL_LATE);
+#endif
+    namedattribute(NAME);
+    namedattribute(PDEATHSIG);
+#ifdef PR_SET_PTRACER
+    namedattribute(PTRACER);
+#endif
+#ifdef PR_SET_PTRACER_ANY
+    namedconstant(PR_SET_PTRACER_ANY);
+#endif
+#ifdef PR_SET_CHILD_SUBREAPER
+    namedattribute(CHILD_SUBREAPER);
+#endif
+#ifdef PR_SET_NO_NEW_PRIVS
+    namedattribute(NO_NEW_PRIVS);
+#endif
+
+#ifdef PR_GET_SECCOMP
+    namedattribute(SECCOMP);
+#endif
+#ifdef PR_GET_SECUREBITS
+    namedattribute(SECUREBITS);
+#endif
+#ifdef PR_GET_TIMERSLACK
+    namedattribute(TIMERSLACK);
+#endif
+    namedattribute(TIMING);
+    namedconstant(PR_TIMING_STATISTICAL);
+    namedconstant(PR_TIMING_TIMESTAMP);
+#ifdef PR_SET_TSC
+    namedattribute(TSC);
+    namedconstant(PR_TSC_ENABLE);
+    namedconstant(PR_TSC_SIGSEGV);
+#endif
+    namedattribute(UNALIGN);
+    namedconstant(PR_UNALIGN_NOPRINT);
+    namedconstant(PR_UNALIGN_SIGBUS);
+    /* Add the CAP_* constants too */
+    namedconstant(CAP_EFFECTIVE);
+    namedconstant(CAP_PERMITTED);
+    namedconstant(CAP_INHERITABLE);
+    namedconstant(CAP_CHOWN);
+    namedconstant(CAP_DAC_OVERRIDE);
+    namedconstant(CAP_DAC_READ_SEARCH);
+    namedconstant(CAP_FOWNER);
+    namedconstant(CAP_FSETID);
+    namedconstant(CAP_KILL);
+    namedconstant(CAP_SETGID);
+    namedconstant(CAP_SETUID);
+    namedconstant(CAP_SETPCAP);
+    namedconstant(CAP_LINUX_IMMUTABLE);
+    namedconstant(CAP_NET_BIND_SERVICE);
+    namedconstant(CAP_NET_BROADCAST);
+    namedconstant(CAP_NET_ADMIN);
+    namedconstant(CAP_NET_RAW);
+    namedconstant(CAP_IPC_LOCK);
+    namedconstant(CAP_IPC_OWNER);
+    namedconstant(CAP_SYS_MODULE);
+    namedconstant(CAP_SYS_RAWIO);
+    namedconstant(CAP_SYS_CHROOT);
+    namedconstant(CAP_SYS_PTRACE);
+    namedconstant(CAP_SYS_PACCT);
+    namedconstant(CAP_SYS_ADMIN);
+    namedconstant(CAP_SYS_BOOT);
+    namedconstant(CAP_SYS_NICE);
+    namedconstant(CAP_SYS_RESOURCE);
+    namedconstant(CAP_SYS_TIME);
+    namedconstant(CAP_SYS_TTY_CONFIG);
+    namedconstant(CAP_MKNOD);
+    namedconstant(CAP_LEASE);
+    namedconstant(CAP_AUDIT_WRITE);
+    namedconstant(CAP_AUDIT_CONTROL);
+#ifdef CAP_SETFCAP
+    namedconstant(CAP_SETFCAP);
+#endif
+#ifdef CAP_MAC_OVERRIDE
+    namedconstant(CAP_MAC_OVERRIDE);
+#endif
+#ifdef CAP_MAC_ADMIN
+    namedconstant(CAP_MAC_ADMIN);
+#endif
+#ifdef CAP_SYSLOG
+    namedconstant(CAP_SYSLOG);
+#endif
+#ifdef CAP_WAKE_ALARM
+    namedconstant(CAP_WAKE_ALARM);
+#endif
+    /* And the securebits constants */
+    namedconstant(SECURE_KEEP_CAPS);
+    namedconstant(SECURE_NO_SETUID_FIXUP);
+    namedconstant(SECURE_NOROOT);
+    namedconstant(SECURE_KEEP_CAPS_LOCKED);
+    namedconstant(SECURE_NO_SETUID_FIXUP_LOCKED);
+    namedconstant(SECURE_NOROOT_LOCKED);
+    namedconstant(SECBIT_KEEP_CAPS);
+    namedconstant(SECBIT_NO_SETUID_FIXUP);
+    namedconstant(SECBIT_NOROOT);
+    namedconstant(SECBIT_KEEP_CAPS_LOCKED);
+    namedconstant(SECBIT_NO_SETUID_FIXUP_LOCKED);
+    namedconstant(SECBIT_NOROOT_LOCKED);
+#if PY_MAJOR_VERSION >= 3
+    return _prctl;
+#endif
+}
diff --git a/docs/Makefile b/docs/Makefile
new file mode 100644
index 0000000..e9effba
--- /dev/null
+++ b/docs/Makefile
@@ -0,0 +1,89 @@
+# Makefile for Sphinx documentation
+#
+
+# You can set these variables from the command line.
+SPHINXOPTS    =
+SPHINXBUILD   = sphinx-build
+PAPER         =
+BUILDDIR      = _build
+
+# Internal variables.
+PAPEROPT_a4     = -D latex_paper_size=a4
+PAPEROPT_letter = -D latex_paper_size=letter
+ALLSPHINXOPTS   = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) .
+
+.PHONY: help clean html dirhtml pickle json htmlhelp qthelp latex changes linkcheck doctest
+
+help:
+	@echo "Please use \`make <target>' where <target> is one of"
+	@echo "  html      to make standalone HTML files"
+	@echo "  dirhtml   to make HTML files named index.html in directories"
+	@echo "  pickle    to make pickle files"
+	@echo "  json      to make JSON files"
+	@echo "  htmlhelp  to make HTML files and a HTML help project"
+	@echo "  qthelp    to make HTML files and a qthelp project"
+	@echo "  latex     to make LaTeX files, you can set PAPER=a4 or PAPER=letter"
+	@echo "  changes   to make an overview of all changed/added/deprecated items"
+	@echo "  linkcheck to check all external links for integrity"
+	@echo "  doctest   to run all doctests embedded in the documentation (if enabled)"
+
+clean:
+	-rm -rf $(BUILDDIR)/*
+
+html:
+	$(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html
+	@echo
+	@echo "Build finished. The HTML pages are in $(BUILDDIR)/html."
+
+dirhtml:
+	$(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml
+	@echo
+	@echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml."
+
+pickle:
+	$(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle
+	@echo
+	@echo "Build finished; now you can process the pickle files."
+
+json:
+	$(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json
+	@echo
+	@echo "Build finished; now you can process the JSON files."
+
+htmlhelp:
+	$(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp
+	@echo
+	@echo "Build finished; now you can run HTML Help Workshop with the" \
+	      ".hhp project file in $(BUILDDIR)/htmlhelp."
+
+qthelp:
+	$(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp
+	@echo
+	@echo "Build finished; now you can run "qcollectiongenerator" with the" \
+	      ".qhcp project file in $(BUILDDIR)/qthelp, like this:"
+	@echo "# qcollectiongenerator $(BUILDDIR)/qthelp/python-prctl.qhcp"
+	@echo "To view the help file:"
+	@echo "# assistant -collectionFile $(BUILDDIR)/qthelp/python-prctl.qhc"
+
+latex:
+	$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
+	@echo
+	@echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex."
+	@echo "Run \`make all-pdf' or \`make all-ps' in that directory to" \
+	      "run these through (pdf)latex."
+
+changes:
+	$(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes
+	@echo
+	@echo "The overview file is in $(BUILDDIR)/changes."
+
+linkcheck:
+	$(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck
+	@echo
+	@echo "Link check complete; look for any errors in the above output " \
+	      "or in $(BUILDDIR)/linkcheck/output.txt."
+
+doctest:
+	$(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest
+	@echo "Testing of doctests in the sources finished, look at the " \
+	      "results in $(BUILDDIR)/doctest/output.txt."
diff --git a/docs/conf.py b/docs/conf.py
new file mode 100644
index 0000000..e577e07
--- /dev/null
+++ b/docs/conf.py
@@ -0,0 +1,194 @@
+# -*- coding: utf-8 -*-
+#
+# python-prctl documentation build configuration file, created by
+# sphinx-quickstart on Wed Mar 10 23:08:02 2010.
+#
+# This file is execfile()d with the current directory set to its containing dir.
+#
+# Note that not all possible configuration values are present in this
+# autogenerated file.
+#
+# All configuration values have a default; values that are commented out
+# serve to show the default.
+
+import sys, os
+
+# If extensions (or modules to document with autodoc) are in another directory,
+# add these directories to sys.path here. If the directory is relative to the
+# documentation root, use os.path.abspath to make it absolute, like shown here.
+#sys.path.append(os.path.abspath('.'))
+
+# -- General configuration -----------------------------------------------------
+
+# Add any Sphinx extension module names here, as strings. They can be extensions
+# coming with Sphinx (named 'sphinx.ext.*') or your custom ones.
+extensions = ['sphinx.ext.todo']
+
+# Add any paths that contain templates here, relative to this directory.
+templates_path = ['_templates']
+
+# The suffix of source filenames.
+source_suffix = '.rst'
+
+# The encoding of source files.
+#source_encoding = 'utf-8'
+
+# The master toctree document.
+master_doc = 'index'
+
+# General information about the project.
... 1652 lines suppressed ...

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/python-modules/packages/python-prctl.git



More information about the Python-modules-commits mailing list