[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