mirror of
https://github.com/systemd/systemd-stable.git
synced 2024-12-22 13:33:56 +03:00
Remove python-systemd
python-system has moved to it's own repository: https://github.com/systemd/python-systemd
This commit is contained in:
parent
fc08079ef2
commit
2799e519ca
165
Makefile.am
165
Makefile.am
@ -5620,164 +5620,6 @@ EXTRA_DIST += \
|
|||||||
test/loopy.service.d \
|
test/loopy.service.d \
|
||||||
test/loopy.service.d/compat.conf
|
test/loopy.service.d/compat.conf
|
||||||
|
|
||||||
# ------------------------------------------------------------------------------
|
|
||||||
if HAVE_PYTHON_DEVEL
|
|
||||||
pkgpyexec_LTLIBRARIES = \
|
|
||||||
_journal.la \
|
|
||||||
id128.la \
|
|
||||||
_daemon.la \
|
|
||||||
_reader.la \
|
|
||||||
login.la
|
|
||||||
|
|
||||||
_journal_la_SOURCES = \
|
|
||||||
src/python-systemd/_journal.c
|
|
||||||
|
|
||||||
_journal_la_CFLAGS = \
|
|
||||||
$(AM_CFLAGS) \
|
|
||||||
-fvisibility=default \
|
|
||||||
$(PYTHON_DEVEL_CFLAGS)
|
|
||||||
|
|
||||||
_journal_la_LDFLAGS = \
|
|
||||||
$(AM_LDFLAGS) \
|
|
||||||
-shared \
|
|
||||||
-module \
|
|
||||||
-avoid-version
|
|
||||||
|
|
||||||
_journal_la_LIBADD = \
|
|
||||||
$(PYTHON_DEVEL_LIBS) \
|
|
||||||
libsystemd.la
|
|
||||||
|
|
||||||
id128_la_SOURCES = \
|
|
||||||
src/python-systemd/id128.c \
|
|
||||||
src/python-systemd/pyutil.c \
|
|
||||||
src/python-systemd/pyutil.h
|
|
||||||
|
|
||||||
nodist_id128_la_SOURCES = \
|
|
||||||
src/python-systemd/id128-constants.h
|
|
||||||
|
|
||||||
id128_la_CFLAGS = \
|
|
||||||
$(AM_CFLAGS) \
|
|
||||||
-fvisibility=default \
|
|
||||||
$(PYTHON_DEVEL_CFLAGS) \
|
|
||||||
-I$(top_builddir)/src/python-systemd
|
|
||||||
|
|
||||||
id128_la_LDFLAGS = \
|
|
||||||
$(AM_LDFLAGS) \
|
|
||||||
-shared \
|
|
||||||
-module \
|
|
||||||
-avoid-version
|
|
||||||
|
|
||||||
id128_la_LIBADD = \
|
|
||||||
$(PYTHON_DEVEL_LIBS) \
|
|
||||||
libshared.la \
|
|
||||||
libsystemd.la
|
|
||||||
|
|
||||||
_daemon_la_SOURCES = \
|
|
||||||
src/python-systemd/_daemon.c \
|
|
||||||
src/python-systemd/pyutil.c \
|
|
||||||
src/python-systemd/pyutil.h
|
|
||||||
|
|
||||||
_daemon_la_CFLAGS = \
|
|
||||||
$(AM_CFLAGS) \
|
|
||||||
-fvisibility=default \
|
|
||||||
$(PYTHON_DEVEL_CFLAGS) \
|
|
||||||
-I$(top_builddir)/src/python-systemd
|
|
||||||
|
|
||||||
_daemon_la_LDFLAGS = \
|
|
||||||
$(AM_LDFLAGS) \
|
|
||||||
-shared \
|
|
||||||
-module \
|
|
||||||
-avoid-version
|
|
||||||
|
|
||||||
_daemon_la_LIBADD = \
|
|
||||||
$(PYTHON_DEVEL_LIBS) \
|
|
||||||
libshared.la \
|
|
||||||
libsystemd.la
|
|
||||||
|
|
||||||
_reader_la_SOURCES = \
|
|
||||||
src/python-systemd/_reader.c \
|
|
||||||
src/python-systemd/pyutil.c \
|
|
||||||
src/python-systemd/pyutil.h
|
|
||||||
|
|
||||||
_reader_la_CFLAGS = \
|
|
||||||
$(AM_CFLAGS) \
|
|
||||||
-fvisibility=default \
|
|
||||||
$(PYTHON_DEVEL_CFLAGS)
|
|
||||||
|
|
||||||
_reader_la_LDFLAGS = \
|
|
||||||
$(AM_LDFLAGS) \
|
|
||||||
-shared \
|
|
||||||
-module \
|
|
||||||
-avoid-version
|
|
||||||
|
|
||||||
_reader_la_LIBADD = \
|
|
||||||
$(PYTHON_DEVEL_LIBS) \
|
|
||||||
libshared.la \
|
|
||||||
libsystemd.la
|
|
||||||
|
|
||||||
login_la_SOURCES = \
|
|
||||||
src/python-systemd/login.c \
|
|
||||||
src/python-systemd/pyutil.c \
|
|
||||||
src/python-systemd/pyutil.h
|
|
||||||
|
|
||||||
login_la_CFLAGS = \
|
|
||||||
$(AM_CFLAGS) \
|
|
||||||
-fvisibility=default \
|
|
||||||
$(PYTHON_DEVEL_CFLAGS)
|
|
||||||
|
|
||||||
login_la_LDFLAGS = \
|
|
||||||
$(AM_LDFLAGS) \
|
|
||||||
-shared \
|
|
||||||
-module \
|
|
||||||
-avoid-version
|
|
||||||
|
|
||||||
login_la_LIBADD = \
|
|
||||||
$(PYTHON_DEVEL_LIBS) \
|
|
||||||
libshared.la \
|
|
||||||
libsystemd.la
|
|
||||||
|
|
||||||
dist_pkgpyexec_PYTHON = \
|
|
||||||
src/python-systemd/journal.py \
|
|
||||||
src/python-systemd/daemon.py \
|
|
||||||
src/python-systemd/__init__.py
|
|
||||||
|
|
||||||
src/python-systemd/id128-constants.h: src/systemd/sd-messages.h
|
|
||||||
$(AM_V_at)$(MKDIR_P) $(dir $@)
|
|
||||||
$(AM_V_GEN)$(SED) -n -r 's/,//g; s/#define (SD_MESSAGE_[A-Z0-9_]+)\s.*/add_id(m, "\1", \1) JOINER/p' <$< >$@
|
|
||||||
|
|
||||||
BUILT_SOURCES += \
|
|
||||||
$(nodist_id128_la_SOURCES)
|
|
||||||
|
|
||||||
SPHINXOPTS = -D version=$(VERSION) -D release=$(VERSION)
|
|
||||||
sphinx-%:
|
|
||||||
$(AM_V_at)test -n "$(SPHINX_BUILD)" || { echo " *** sphinx-build is not available"; exit 1; }
|
|
||||||
$(AM_V_GEN)PYTHONPATH=$(DESTDIR)$(pyexecdir) LD_LIBRARY_PATH=$(DESTDIR)$(libdir) $(SPHINX_BUILD) -b $* $(SPHINXOPTS) $(top_srcdir)/src/python-systemd/docs $(top_builddir)/docs/html/python-systemd/
|
|
||||||
$(AM_V_at)echo Output has been generated in $(abs_top_builddir)/docs/html/python-systemd/
|
|
||||||
|
|
||||||
python-shell:
|
|
||||||
$(AM_V_at)echo "Starting python with $(DESTDIR)$(pyexecdir)"
|
|
||||||
$(AM_V_at)PYTHONPATH=$(DESTDIR)$(pyexecdir) LD_LIBRARY_PATH=$(DESTDIR)$(libdir) $(PYTHON)
|
|
||||||
|
|
||||||
destdir-sphinx: all
|
|
||||||
dir="$$(mktemp -d /tmp/systemd-install.XXXXXX)" && \
|
|
||||||
$(MAKE) DESTDIR="$$dir" install && \
|
|
||||||
$(MAKE) DESTDIR="$$dir" sphinx-html && \
|
|
||||||
rm -rf "$$dir"
|
|
||||||
|
|
||||||
endif
|
|
||||||
|
|
||||||
CLEAN_LOCAL_HOOKS += clean-sphinx
|
|
||||||
|
|
||||||
.PHONY: python-shell destdir-sphinx clean-sphinx clean-python
|
|
||||||
|
|
||||||
clean-sphinx:
|
|
||||||
-rm -rf docs/html/python-systemd/
|
|
||||||
|
|
||||||
# Remove Python stuff, e.g. to force rebuilding for a different Python version.
|
|
||||||
clean-python:
|
|
||||||
-rm -rf src/python-systemd/.libs src/python-systemd/*.l[ao]
|
|
||||||
-rm -f _daemon.la id128.la _journal.la login.la _reader.la
|
|
||||||
|
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
if ENABLE_COMPAT_LIBS
|
if ENABLE_COMPAT_LIBS
|
||||||
libsystemd-%.c: src/compat-libs/libsystemd-%.sym
|
libsystemd-%.c: src/compat-libs/libsystemd-%.sym
|
||||||
@ -5950,7 +5792,6 @@ substitutions = \
|
|||||||
'|RC_LOCAL_SCRIPT_PATH_START=$(RC_LOCAL_SCRIPT_PATH_START)|' \
|
'|RC_LOCAL_SCRIPT_PATH_START=$(RC_LOCAL_SCRIPT_PATH_START)|' \
|
||||||
'|RC_LOCAL_SCRIPT_PATH_STOP=$(RC_LOCAL_SCRIPT_PATH_STOP)|' \
|
'|RC_LOCAL_SCRIPT_PATH_STOP=$(RC_LOCAL_SCRIPT_PATH_STOP)|' \
|
||||||
'|PYTHON=$(PYTHON)|' \
|
'|PYTHON=$(PYTHON)|' \
|
||||||
'|PYTHON_BINARY=$(PYTHON_BINARY)|' \
|
|
||||||
'|NTP_SERVERS=$(NTP_SERVERS)|' \
|
'|NTP_SERVERS=$(NTP_SERVERS)|' \
|
||||||
'|DNS_SERVERS=$(DNS_SERVERS)|' \
|
'|DNS_SERVERS=$(DNS_SERVERS)|' \
|
||||||
'|systemuidmax=$(SYSTEM_UID_MAX)|' \
|
'|systemuidmax=$(SYSTEM_UID_MAX)|' \
|
||||||
@ -6251,11 +6092,6 @@ DISTCHECK_CONFIGURE_FLAGS += \
|
|||||||
--with-sysvrcnd-path=
|
--with-sysvrcnd-path=
|
||||||
endif
|
endif
|
||||||
|
|
||||||
if HAVE_PYTHON
|
|
||||||
DISTCHECK_CONFIGURE_FLAGS += \
|
|
||||||
--with-python
|
|
||||||
endif
|
|
||||||
|
|
||||||
if ENABLE_SPLIT_USR
|
if ENABLE_SPLIT_USR
|
||||||
DISTCHECK_CONFIGURE_FLAGS += \
|
DISTCHECK_CONFIGURE_FLAGS += \
|
||||||
--enable-split-usr
|
--enable-split-usr
|
||||||
@ -6312,7 +6148,6 @@ www_target = www.freedesktop.org:/srv/www.freedesktop.org/www/software/systemd
|
|||||||
.PHONY: doc-sync
|
.PHONY: doc-sync
|
||||||
doc-sync: all destdir-sphinx
|
doc-sync: all destdir-sphinx
|
||||||
rsync -rlv --delete-excluded --include="*.html" --exclude="*" --omit-dir-times man/ $(www_target)/man/
|
rsync -rlv --delete-excluded --include="*.html" --exclude="*" --omit-dir-times man/ $(www_target)/man/
|
||||||
rsync -rlv --delete --omit-dir-times docs/html/python-systemd/ $(www_target)/python-systemd/
|
|
||||||
|
|
||||||
.PHONY: gardel
|
.PHONY: gardel
|
||||||
gardel: upload
|
gardel: upload
|
||||||
|
29
configure.ac
29
configure.ac
@ -238,7 +238,7 @@ AC_CHECK_SIZEOF(rlim_t,,[
|
|||||||
])
|
])
|
||||||
|
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
# we use python to build the man page index, and for systemd-python
|
# we use python to build the man page index
|
||||||
have_python=no
|
have_python=no
|
||||||
AC_ARG_WITH([python],
|
AC_ARG_WITH([python],
|
||||||
[AS_HELP_STRING([--without-python], [Disable building the man page index and systemd-python (default: test)])])
|
[AS_HELP_STRING([--without-python], [Disable building the man page index and systemd-python (default: test)])])
|
||||||
@ -260,30 +260,7 @@ AS_IF([test "$have_python" != "yes"], [
|
|||||||
AS_IF([test "$with_python" != "no"],
|
AS_IF([test "$with_python" != "no"],
|
||||||
[AC_MSG_WARN([*** python support not found, some documentation cannot be built])])
|
[AC_MSG_WARN([*** python support not found, some documentation cannot be built])])
|
||||||
])
|
])
|
||||||
|
|
||||||
AM_CONDITIONAL([HAVE_PYTHON], [test "x$have_python" = "xyes"])
|
AM_CONDITIONAL([HAVE_PYTHON], [test "x$have_python" = "xyes"])
|
||||||
AS_IF([test "x$PYTHON_BINARY" = "x"],
|
|
||||||
[AS_IF([test "x$have_python" = "xyes"],
|
|
||||||
[PYTHON_BINARY="$(which "$PYTHON")"],
|
|
||||||
[PYTHON_BINARY=/usr/bin/python])])
|
|
||||||
AC_ARG_VAR(PYTHON_BINARY, [Python binary used to launch installed scripts])
|
|
||||||
|
|
||||||
AS_IF([test "x$have_python" != "xyes" -a "x$enable_python_devel" = "xyes"],
|
|
||||||
[AC_MSG_ERROR([*** python-devel support requires --with-python])])
|
|
||||||
|
|
||||||
have_python_devel=no
|
|
||||||
AC_ARG_ENABLE(python_devel, AS_HELP_STRING([--disable-python-devel], [Do not build python modules]))
|
|
||||||
AS_IF([test "x$have_python" = "xyes" -a "x$enable_python_devel" != "xno"], [
|
|
||||||
PKG_CHECK_MODULES([PYTHON_DEVEL], [python-${PYTHON_VERSION}],
|
|
||||||
[have_python_devel=yes],
|
|
||||||
[PKG_CHECK_MODULES([PYTHON_DEVEL], [python],
|
|
||||||
[have_python_devel=yes],
|
|
||||||
[have_python_devel=no])])
|
|
||||||
AS_IF([test "x$have_python_devel" = xno -a "x$enable_python_devel" = xyes],
|
|
||||||
[AC_MSG_ERROR([*** python-devel support requested but libraries not found])])
|
|
||||||
AC_PATH_PROGS(SPHINX_BUILD, sphinx-build-${PYTHON_VERSION} sphinx-build)
|
|
||||||
])
|
|
||||||
AM_CONDITIONAL([HAVE_PYTHON_DEVEL], [test "$have_python_devel" = "yes"])
|
|
||||||
|
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
|
|
||||||
@ -1566,7 +1543,6 @@ AC_MSG_RESULT([
|
|||||||
terminal: ${have_terminal}
|
terminal: ${have_terminal}
|
||||||
kdbus: ${have_kdbus}
|
kdbus: ${have_kdbus}
|
||||||
Python: ${have_python}
|
Python: ${have_python}
|
||||||
Python Headers: ${have_python_devel}
|
|
||||||
man pages: ${have_manpages}
|
man pages: ${have_manpages}
|
||||||
test coverage: ${have_coverage}
|
test coverage: ${have_coverage}
|
||||||
Split /usr: ${enable_split_usr}
|
Split /usr: ${enable_split_usr}
|
||||||
@ -1587,7 +1563,6 @@ AC_MSG_RESULT([
|
|||||||
SysV init scripts: ${SYSTEM_SYSVINIT_PATH}
|
SysV init scripts: ${SYSTEM_SYSVINIT_PATH}
|
||||||
SysV rc?.d directories: ${SYSTEM_SYSVRCND_PATH}
|
SysV rc?.d directories: ${SYSTEM_SYSVRCND_PATH}
|
||||||
Build Python: ${PYTHON}
|
Build Python: ${PYTHON}
|
||||||
Installation Python: ${PYTHON_BINARY}
|
|
||||||
sphinx binary: ${SPHINX_BUILD}
|
sphinx binary: ${SPHINX_BUILD}
|
||||||
PAM modules dir: ${with_pamlibdir}
|
PAM modules dir: ${with_pamlibdir}
|
||||||
PAM configuration dir: ${with_pamconfdir}
|
PAM configuration dir: ${with_pamconfdir}
|
||||||
@ -1608,6 +1583,4 @@ AC_MSG_RESULT([
|
|||||||
CFLAGS: ${OUR_CFLAGS} ${CFLAGS}
|
CFLAGS: ${OUR_CFLAGS} ${CFLAGS}
|
||||||
CPPFLAGS: ${OUR_CPPFLAGS} ${CPPFLAGS}
|
CPPFLAGS: ${OUR_CPPFLAGS} ${CPPFLAGS}
|
||||||
LDFLAGS: ${OUR_LDFLAGS} ${LDFLAGS}
|
LDFLAGS: ${OUR_LDFLAGS} ${LDFLAGS}
|
||||||
PYTHON_CFLAGS: ${PYTHON_DEVEL_CFLAGS}
|
|
||||||
PYTHON_LIBS: ${PYTHON_DEVEL_LIBS}
|
|
||||||
])
|
])
|
||||||
|
@ -225,12 +225,6 @@
|
|||||||
<xsl:text>systemd.directives.html</xsl:text>
|
<xsl:text>systemd.directives.html</xsl:text>
|
||||||
</xsl:attribute>
|
</xsl:attribute>
|
||||||
<xsl:text>Directives </xsl:text>
|
<xsl:text>Directives </xsl:text>
|
||||||
</a>·
|
|
||||||
<a>
|
|
||||||
<xsl:attribute name="href">
|
|
||||||
<xsl:text>../python-systemd/index.html</xsl:text>
|
|
||||||
</xsl:attribute>
|
|
||||||
<xsl:text>Python </xsl:text>
|
|
||||||
</a>
|
</a>
|
||||||
|
|
||||||
<span style="float:right">
|
<span style="float:right">
|
||||||
|
2
src/python-systemd/.gitignore
vendored
2
src/python-systemd/.gitignore
vendored
@ -1,2 +0,0 @@
|
|||||||
/id128-constants.h
|
|
||||||
*.py[oc]
|
|
@ -1 +0,0 @@
|
|||||||
../Makefile
|
|
@ -1,18 +0,0 @@
|
|||||||
# -*- Mode: python; indent-tabs-mode: nil -*- */
|
|
||||||
#
|
|
||||||
# This file is part of systemd.
|
|
||||||
#
|
|
||||||
# Copyright 2012 David Strauss
|
|
||||||
#
|
|
||||||
# systemd is free software; you can redistribute it and/or modify it
|
|
||||||
# under the terms of the GNU Lesser General Public License as published by
|
|
||||||
# the Free Software Foundation; either version 2.1 of the License, or
|
|
||||||
# (at your option) any later version.
|
|
||||||
#
|
|
||||||
# systemd is distributed in the hope that it will be useful, but
|
|
||||||
# WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
# Lesser General Public License for more details.
|
|
||||||
#
|
|
||||||
# You should have received a copy of the GNU Lesser General Public License
|
|
||||||
# along with systemd; If not, see <http://www.gnu.org/licenses/>.
|
|
@ -1,331 +0,0 @@
|
|||||||
/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
|
|
||||||
|
|
||||||
/***
|
|
||||||
This file is part of systemd.
|
|
||||||
|
|
||||||
Copyright 2013 Zbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
|
|
||||||
|
|
||||||
systemd is free software; you can redistribute it and/or modify it
|
|
||||||
under the terms of the GNU Lesser General Public License as published by
|
|
||||||
the Free Software Foundation; either version 2.1 of the License, or
|
|
||||||
(at your option) any later version.
|
|
||||||
|
|
||||||
systemd is distributed in the hope that it will be useful, but
|
|
||||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
Lesser General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU Lesser General Public License
|
|
||||||
along with systemd; If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
***/
|
|
||||||
|
|
||||||
#define PY_SSIZE_T_CLEAN
|
|
||||||
#pragma GCC diagnostic push
|
|
||||||
#pragma GCC diagnostic ignored "-Wredundant-decls"
|
|
||||||
#include <Python.h>
|
|
||||||
#pragma GCC diagnostic pop
|
|
||||||
|
|
||||||
#include <stdbool.h>
|
|
||||||
#include <assert.h>
|
|
||||||
#include <sys/socket.h>
|
|
||||||
|
|
||||||
#include "systemd/sd-daemon.h"
|
|
||||||
#include "pyutil.h"
|
|
||||||
#include "macro.h"
|
|
||||||
|
|
||||||
PyDoc_STRVAR(module__doc__,
|
|
||||||
"Python interface to the libsystemd-daemon library.\n\n"
|
|
||||||
"Provides _listen_fds, notify, booted, and is_* functions\n"
|
|
||||||
"which wrap sd_listen_fds, sd_notify, sd_booted, sd_is_* and\n"
|
|
||||||
"useful for socket activation and checking if the system is\n"
|
|
||||||
"running under systemd."
|
|
||||||
);
|
|
||||||
|
|
||||||
PyDoc_STRVAR(booted__doc__,
|
|
||||||
"booted() -> bool\n\n"
|
|
||||||
"Return True iff this system is running under systemd.\n"
|
|
||||||
"Wraps sd_daemon_booted(3)."
|
|
||||||
);
|
|
||||||
|
|
||||||
static PyObject* booted(PyObject *self, PyObject *args) {
|
|
||||||
int r;
|
|
||||||
assert(args == NULL);
|
|
||||||
|
|
||||||
r = sd_booted();
|
|
||||||
if (set_error(r, NULL, NULL) < 0)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
return PyBool_FromLong(r);
|
|
||||||
}
|
|
||||||
|
|
||||||
PyDoc_STRVAR(notify__doc__,
|
|
||||||
"notify(status, unset_environment=False) -> bool\n\n"
|
|
||||||
"Send a message to the init system about a status change.\n"
|
|
||||||
"Wraps sd_notify(3).");
|
|
||||||
|
|
||||||
static PyObject* notify(PyObject *self, PyObject *args, PyObject *keywds) {
|
|
||||||
int r;
|
|
||||||
const char* msg;
|
|
||||||
int unset = false;
|
|
||||||
|
|
||||||
static const char* const kwlist[] = {
|
|
||||||
"status",
|
|
||||||
"unset_environment",
|
|
||||||
NULL,
|
|
||||||
};
|
|
||||||
#if PY_MAJOR_VERSION >=3 && PY_MINOR_VERSION >= 3
|
|
||||||
if (!PyArg_ParseTupleAndKeywords(args, keywds, "s|p:notify",
|
|
||||||
(char**) kwlist, &msg, &unset))
|
|
||||||
return NULL;
|
|
||||||
#else
|
|
||||||
PyObject *obj = NULL;
|
|
||||||
if (!PyArg_ParseTupleAndKeywords(args, keywds, "s|O:notify",
|
|
||||||
(char**) kwlist, &msg, &obj))
|
|
||||||
return NULL;
|
|
||||||
if (obj != NULL)
|
|
||||||
unset = PyObject_IsTrue(obj);
|
|
||||||
if (unset < 0)
|
|
||||||
return NULL;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
r = sd_notify(unset, msg);
|
|
||||||
if (set_error(r, NULL, NULL) < 0)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
return PyBool_FromLong(r);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
PyDoc_STRVAR(listen_fds__doc__,
|
|
||||||
"_listen_fds(unset_environment=True) -> int\n\n"
|
|
||||||
"Return the number of descriptors passed to this process by the init system\n"
|
|
||||||
"as part of the socket-based activation logic.\n"
|
|
||||||
"Wraps sd_listen_fds(3)."
|
|
||||||
);
|
|
||||||
|
|
||||||
static PyObject* listen_fds(PyObject *self, PyObject *args, PyObject *keywds) {
|
|
||||||
int r;
|
|
||||||
int unset = true;
|
|
||||||
|
|
||||||
static const char* const kwlist[] = {"unset_environment", NULL};
|
|
||||||
#if PY_MAJOR_VERSION >=3 && PY_MINOR_VERSION >= 3
|
|
||||||
if (!PyArg_ParseTupleAndKeywords(args, keywds, "|p:_listen_fds",
|
|
||||||
(char**) kwlist, &unset))
|
|
||||||
return NULL;
|
|
||||||
#else
|
|
||||||
PyObject *obj = NULL;
|
|
||||||
if (!PyArg_ParseTupleAndKeywords(args, keywds, "|O:_listen_fds",
|
|
||||||
(char**) kwlist, &obj))
|
|
||||||
return NULL;
|
|
||||||
if (obj != NULL)
|
|
||||||
unset = PyObject_IsTrue(obj);
|
|
||||||
if (unset < 0)
|
|
||||||
return NULL;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
r = sd_listen_fds(unset);
|
|
||||||
if (set_error(r, NULL, NULL) < 0)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
return long_FromLong(r);
|
|
||||||
}
|
|
||||||
|
|
||||||
PyDoc_STRVAR(is_fifo__doc__,
|
|
||||||
"_is_fifo(fd, path) -> bool\n\n"
|
|
||||||
"Returns True iff the descriptor refers to a FIFO or a pipe.\n"
|
|
||||||
"Wraps sd_is_fifo(3)."
|
|
||||||
);
|
|
||||||
|
|
||||||
|
|
||||||
static PyObject* is_fifo(PyObject *self, PyObject *args) {
|
|
||||||
int r;
|
|
||||||
int fd;
|
|
||||||
const char *path = NULL;
|
|
||||||
|
|
||||||
#if PY_MAJOR_VERSION >=3 && PY_MINOR_VERSION >= 1
|
|
||||||
if (!PyArg_ParseTuple(args, "i|O&:_is_fifo",
|
|
||||||
&fd, Unicode_FSConverter, &path))
|
|
||||||
return NULL;
|
|
||||||
#else
|
|
||||||
if (!PyArg_ParseTuple(args, "i|z:_is_fifo", &fd, &path))
|
|
||||||
return NULL;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
r = sd_is_fifo(fd, path);
|
|
||||||
if (set_error(r, path, NULL) < 0)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
return PyBool_FromLong(r);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
PyDoc_STRVAR(is_mq__doc__,
|
|
||||||
"_is_mq(fd, path) -> bool\n\n"
|
|
||||||
"Returns True iff the descriptor refers to a POSIX message queue.\n"
|
|
||||||
"Wraps sd_is_mq(3)."
|
|
||||||
);
|
|
||||||
|
|
||||||
static PyObject* is_mq(PyObject *self, PyObject *args) {
|
|
||||||
int r;
|
|
||||||
int fd;
|
|
||||||
const char *path = NULL;
|
|
||||||
|
|
||||||
#if PY_MAJOR_VERSION >=3 && PY_MINOR_VERSION >= 1
|
|
||||||
if (!PyArg_ParseTuple(args, "i|O&:_is_mq",
|
|
||||||
&fd, Unicode_FSConverter, &path))
|
|
||||||
return NULL;
|
|
||||||
#else
|
|
||||||
if (!PyArg_ParseTuple(args, "i|z:_is_mq", &fd, &path))
|
|
||||||
return NULL;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
r = sd_is_mq(fd, path);
|
|
||||||
if (set_error(r, path, NULL) < 0)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
return PyBool_FromLong(r);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
PyDoc_STRVAR(is_socket__doc__,
|
|
||||||
"_is_socket(fd, family=AF_UNSPEC, type=0, listening=-1) -> bool\n\n"
|
|
||||||
"Returns True iff the descriptor refers to a socket.\n"
|
|
||||||
"Wraps sd_is_socket(3).\n\n"
|
|
||||||
"Constants for `family` are defined in the socket module."
|
|
||||||
);
|
|
||||||
|
|
||||||
static PyObject* is_socket(PyObject *self, PyObject *args) {
|
|
||||||
int r;
|
|
||||||
int fd, family = AF_UNSPEC, type = 0, listening = -1;
|
|
||||||
|
|
||||||
if (!PyArg_ParseTuple(args, "i|iii:_is_socket",
|
|
||||||
&fd, &family, &type, &listening))
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
r = sd_is_socket(fd, family, type, listening);
|
|
||||||
if (set_error(r, NULL, NULL) < 0)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
return PyBool_FromLong(r);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
PyDoc_STRVAR(is_socket_inet__doc__,
|
|
||||||
"_is_socket_inet(fd, family=AF_UNSPEC, type=0, listening=-1, port=0) -> bool\n\n"
|
|
||||||
"Wraps sd_is_socket_inet(3).\n\n"
|
|
||||||
"Constants for `family` are defined in the socket module."
|
|
||||||
);
|
|
||||||
|
|
||||||
static PyObject* is_socket_inet(PyObject *self, PyObject *args) {
|
|
||||||
int r;
|
|
||||||
int fd, family = AF_UNSPEC, type = 0, listening = -1, port = 0;
|
|
||||||
|
|
||||||
if (!PyArg_ParseTuple(args, "i|iiii:_is_socket_inet",
|
|
||||||
&fd, &family, &type, &listening, &port))
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
if (port < 0 || port > UINT16_MAX) {
|
|
||||||
set_error(-EINVAL, NULL, "port must fit into uint16_t");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
r = sd_is_socket_inet(fd, family, type, listening, (uint16_t) port);
|
|
||||||
if (set_error(r, NULL, NULL) < 0)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
return PyBool_FromLong(r);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
PyDoc_STRVAR(is_socket_unix__doc__,
|
|
||||||
"_is_socket_unix(fd, type, listening, path) -> bool\n\n"
|
|
||||||
"Wraps sd_is_socket_unix(3)."
|
|
||||||
);
|
|
||||||
|
|
||||||
static PyObject* is_socket_unix(PyObject *self, PyObject *args) {
|
|
||||||
int r;
|
|
||||||
int fd, type = 0, listening = -1;
|
|
||||||
char* path = NULL;
|
|
||||||
Py_ssize_t length = 0;
|
|
||||||
|
|
||||||
#if PY_MAJOR_VERSION >=3 && PY_MINOR_VERSION >= 1
|
|
||||||
_cleanup_Py_DECREF_ PyObject *_path = NULL;
|
|
||||||
if (!PyArg_ParseTuple(args, "i|iiO&:_is_socket_unix",
|
|
||||||
&fd, &type, &listening, Unicode_FSConverter, &_path))
|
|
||||||
return NULL;
|
|
||||||
if (_path) {
|
|
||||||
assert(PyBytes_Check(_path));
|
|
||||||
if (PyBytes_AsStringAndSize(_path, &path, &length))
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
if (!PyArg_ParseTuple(args, "i|iiz#:_is_socket_unix",
|
|
||||||
&fd, &type, &listening, &path, &length))
|
|
||||||
return NULL;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
r = sd_is_socket_unix(fd, type, listening, path, length);
|
|
||||||
if (set_error(r, path, NULL) < 0)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
return PyBool_FromLong(r);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static PyMethodDef methods[] = {
|
|
||||||
{ "booted", booted, METH_NOARGS, booted__doc__},
|
|
||||||
{ "notify", (PyCFunction) notify, METH_VARARGS | METH_KEYWORDS, notify__doc__},
|
|
||||||
{ "_listen_fds", (PyCFunction) listen_fds, METH_VARARGS | METH_KEYWORDS, listen_fds__doc__},
|
|
||||||
{ "_is_fifo", is_fifo, METH_VARARGS, is_fifo__doc__},
|
|
||||||
{ "_is_mq", is_mq, METH_VARARGS, is_mq__doc__},
|
|
||||||
{ "_is_socket", is_socket, METH_VARARGS, is_socket__doc__},
|
|
||||||
{ "_is_socket_inet", is_socket_inet, METH_VARARGS, is_socket_inet__doc__},
|
|
||||||
{ "_is_socket_unix", is_socket_unix, METH_VARARGS, is_socket_unix__doc__},
|
|
||||||
{ NULL, NULL, 0, NULL } /* Sentinel */
|
|
||||||
};
|
|
||||||
|
|
||||||
#if PY_MAJOR_VERSION < 3
|
|
||||||
|
|
||||||
DISABLE_WARNING_MISSING_PROTOTYPES;
|
|
||||||
PyMODINIT_FUNC init_daemon(void) {
|
|
||||||
PyObject *m;
|
|
||||||
|
|
||||||
m = Py_InitModule3("_daemon", methods, module__doc__);
|
|
||||||
if (m == NULL)
|
|
||||||
return;
|
|
||||||
|
|
||||||
PyModule_AddIntConstant(m, "LISTEN_FDS_START", SD_LISTEN_FDS_START);
|
|
||||||
PyModule_AddStringConstant(m, "__version__", PACKAGE_VERSION);
|
|
||||||
}
|
|
||||||
REENABLE_WARNING;
|
|
||||||
|
|
||||||
#else
|
|
||||||
|
|
||||||
static struct PyModuleDef module = {
|
|
||||||
PyModuleDef_HEAD_INIT,
|
|
||||||
"_daemon", /* name of module */
|
|
||||||
module__doc__, /* module documentation, may be NULL */
|
|
||||||
0, /* size of per-interpreter state of the module */
|
|
||||||
methods
|
|
||||||
};
|
|
||||||
|
|
||||||
DISABLE_WARNING_MISSING_PROTOTYPES;
|
|
||||||
PyMODINIT_FUNC PyInit__daemon(void) {
|
|
||||||
PyObject *m;
|
|
||||||
|
|
||||||
m = PyModule_Create(&module);
|
|
||||||
if (m == NULL)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
if (PyModule_AddIntConstant(m, "LISTEN_FDS_START", SD_LISTEN_FDS_START) ||
|
|
||||||
PyModule_AddStringConstant(m, "__version__", PACKAGE_VERSION)) {
|
|
||||||
Py_DECREF(m);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
return m;
|
|
||||||
}
|
|
||||||
REENABLE_WARNING;
|
|
||||||
|
|
||||||
#endif
|
|
@ -1,157 +0,0 @@
|
|||||||
/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
|
|
||||||
|
|
||||||
/***
|
|
||||||
This file is part of systemd.
|
|
||||||
|
|
||||||
Copyright 2012 David Strauss <david@davidstrauss.net>
|
|
||||||
|
|
||||||
systemd is free software; you can redistribute it and/or modify it
|
|
||||||
under the terms of the GNU Lesser General Public License as published by
|
|
||||||
the Free Software Foundation; either version 2.1 of the License, or
|
|
||||||
(at your option) any later version.
|
|
||||||
|
|
||||||
systemd is distributed in the hope that it will be useful, but
|
|
||||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
Lesser General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU Lesser General Public License
|
|
||||||
along with systemd; If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
***/
|
|
||||||
|
|
||||||
#include <Python.h>
|
|
||||||
|
|
||||||
#include <alloca.h>
|
|
||||||
#include "util.h"
|
|
||||||
|
|
||||||
#define SD_JOURNAL_SUPPRESS_LOCATION
|
|
||||||
#include "systemd/sd-journal.h"
|
|
||||||
|
|
||||||
PyDoc_STRVAR(journal_sendv__doc__,
|
|
||||||
"sendv('FIELD=value', 'FIELD=value', ...) -> None\n\n"
|
|
||||||
"Send an entry to the journal."
|
|
||||||
);
|
|
||||||
|
|
||||||
static PyObject *journal_sendv(PyObject *self, PyObject *args) {
|
|
||||||
struct iovec *iov = NULL;
|
|
||||||
int argc;
|
|
||||||
int i, r;
|
|
||||||
PyObject *ret = NULL;
|
|
||||||
PyObject **encoded;
|
|
||||||
|
|
||||||
/* Allocate an array for the argument strings */
|
|
||||||
argc = PyTuple_Size(args);
|
|
||||||
encoded = alloca0(argc * sizeof(PyObject*));
|
|
||||||
|
|
||||||
/* Allocate sufficient iovector space for the arguments. */
|
|
||||||
iov = alloca(argc * sizeof(struct iovec));
|
|
||||||
|
|
||||||
/* Iterate through the Python arguments and fill the iovector. */
|
|
||||||
for (i = 0; i < argc; ++i) {
|
|
||||||
PyObject *item = PyTuple_GetItem(args, i);
|
|
||||||
char *stritem;
|
|
||||||
Py_ssize_t length;
|
|
||||||
|
|
||||||
if (PyUnicode_Check(item)) {
|
|
||||||
encoded[i] = PyUnicode_AsEncodedString(item, "utf-8", "strict");
|
|
||||||
if (encoded[i] == NULL)
|
|
||||||
goto out;
|
|
||||||
item = encoded[i];
|
|
||||||
}
|
|
||||||
if (PyBytes_AsStringAndSize(item, &stritem, &length))
|
|
||||||
goto out;
|
|
||||||
|
|
||||||
iov[i].iov_base = stritem;
|
|
||||||
iov[i].iov_len = length;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Send the iovector to the journal. */
|
|
||||||
r = sd_journal_sendv(iov, argc);
|
|
||||||
if (r < 0) {
|
|
||||||
errno = -r;
|
|
||||||
PyErr_SetFromErrno(PyExc_IOError);
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* End with success. */
|
|
||||||
Py_INCREF(Py_None);
|
|
||||||
ret = Py_None;
|
|
||||||
|
|
||||||
out:
|
|
||||||
for (i = 0; i < argc; ++i)
|
|
||||||
Py_XDECREF(encoded[i]);
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
PyDoc_STRVAR(journal_stream_fd__doc__,
|
|
||||||
"stream_fd(identifier, priority, level_prefix) -> fd\n\n"
|
|
||||||
"Open a stream to journal by calling sd_journal_stream_fd(3)."
|
|
||||||
);
|
|
||||||
|
|
||||||
static PyObject* journal_stream_fd(PyObject *self, PyObject *args) {
|
|
||||||
const char* identifier;
|
|
||||||
int priority, level_prefix;
|
|
||||||
int fd;
|
|
||||||
|
|
||||||
if (!PyArg_ParseTuple(args, "sii:stream_fd",
|
|
||||||
&identifier, &priority, &level_prefix))
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
fd = sd_journal_stream_fd(identifier, priority, level_prefix);
|
|
||||||
if (fd < 0) {
|
|
||||||
errno = -fd;
|
|
||||||
return PyErr_SetFromErrno(PyExc_IOError);
|
|
||||||
}
|
|
||||||
|
|
||||||
return PyLong_FromLong(fd);
|
|
||||||
}
|
|
||||||
|
|
||||||
static PyMethodDef methods[] = {
|
|
||||||
{ "sendv", journal_sendv, METH_VARARGS, journal_sendv__doc__ },
|
|
||||||
{ "stream_fd", journal_stream_fd, METH_VARARGS, journal_stream_fd__doc__ },
|
|
||||||
{ NULL, NULL, 0, NULL } /* Sentinel */
|
|
||||||
};
|
|
||||||
|
|
||||||
#if PY_MAJOR_VERSION < 3
|
|
||||||
|
|
||||||
DISABLE_WARNING_MISSING_PROTOTYPES;
|
|
||||||
PyMODINIT_FUNC init_journal(void) {
|
|
||||||
PyObject *m;
|
|
||||||
|
|
||||||
m = Py_InitModule("_journal", methods);
|
|
||||||
if (m == NULL)
|
|
||||||
return;
|
|
||||||
|
|
||||||
PyModule_AddStringConstant(m, "__version__", PACKAGE_VERSION);
|
|
||||||
}
|
|
||||||
REENABLE_WARNING;
|
|
||||||
|
|
||||||
#else
|
|
||||||
|
|
||||||
static struct PyModuleDef module = {
|
|
||||||
PyModuleDef_HEAD_INIT,
|
|
||||||
"_journal", /* name of module */
|
|
||||||
NULL, /* module documentation, may be NULL */
|
|
||||||
-1, /* size of per-interpreter state of the module */
|
|
||||||
methods
|
|
||||||
};
|
|
||||||
|
|
||||||
DISABLE_WARNING_MISSING_PROTOTYPES;
|
|
||||||
PyMODINIT_FUNC PyInit__journal(void) {
|
|
||||||
PyObject *m;
|
|
||||||
|
|
||||||
m = PyModule_Create(&module);
|
|
||||||
if (m == NULL)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
if (PyModule_AddStringConstant(m, "__version__", PACKAGE_VERSION)) {
|
|
||||||
Py_DECREF(m);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
return m;
|
|
||||||
}
|
|
||||||
REENABLE_WARNING;
|
|
||||||
|
|
||||||
#endif
|
|
File diff suppressed because it is too large
Load Diff
@ -1,55 +0,0 @@
|
|||||||
from ._daemon import (__version__,
|
|
||||||
booted,
|
|
||||||
notify,
|
|
||||||
_listen_fds,
|
|
||||||
_is_fifo,
|
|
||||||
_is_socket,
|
|
||||||
_is_socket_inet,
|
|
||||||
_is_socket_unix,
|
|
||||||
_is_mq,
|
|
||||||
LISTEN_FDS_START)
|
|
||||||
from socket import AF_UNSPEC as _AF_UNSPEC
|
|
||||||
|
|
||||||
def _convert_fileobj(fileobj):
|
|
||||||
try:
|
|
||||||
return fileobj.fileno()
|
|
||||||
except AttributeError:
|
|
||||||
return fileobj
|
|
||||||
|
|
||||||
def is_fifo(fileobj, path=None):
|
|
||||||
fd = _convert_fileobj(fileobj)
|
|
||||||
return _is_fifo(fd, path)
|
|
||||||
|
|
||||||
def is_socket(fileobj, family=_AF_UNSPEC, type=0, listening=-1):
|
|
||||||
fd = _convert_fileobj(fileobj)
|
|
||||||
return _is_socket(fd, family, type, listening)
|
|
||||||
|
|
||||||
def is_socket_inet(fileobj, family=_AF_UNSPEC, type=0, listening=-1, port=0):
|
|
||||||
fd = _convert_fileobj(fileobj)
|
|
||||||
return _is_socket_inet(fd, family, type, listening, port)
|
|
||||||
|
|
||||||
def is_socket_unix(fileobj, type=0, listening=-1, path=None):
|
|
||||||
fd = _convert_fileobj(fileobj)
|
|
||||||
return _is_socket_unix(fd, type, listening, path)
|
|
||||||
|
|
||||||
def is_mq(fileobj, path=None):
|
|
||||||
fd = _convert_fileobj(fileobj)
|
|
||||||
return _is_mq(fd, path)
|
|
||||||
|
|
||||||
def listen_fds(unset_environment=True):
|
|
||||||
"""Return a list of socket activated descriptors
|
|
||||||
|
|
||||||
Example::
|
|
||||||
|
|
||||||
(in primary window)
|
|
||||||
$ systemd-activate -l 2000 python3 -c \\
|
|
||||||
'from systemd.daemon import listen_fds; print(listen_fds())'
|
|
||||||
(in another window)
|
|
||||||
$ telnet localhost 2000
|
|
||||||
(in primary window)
|
|
||||||
...
|
|
||||||
Execing python3 (...)
|
|
||||||
[3]
|
|
||||||
"""
|
|
||||||
num = _listen_fds(unset_environment)
|
|
||||||
return list(range(LISTEN_FDS_START, LISTEN_FDS_START + num))
|
|
1
src/python-systemd/docs/.gitignore
vendored
1
src/python-systemd/docs/.gitignore
vendored
@ -1 +0,0 @@
|
|||||||
!layout.html
|
|
@ -1,279 +0,0 @@
|
|||||||
# -*- coding: utf-8 -*-
|
|
||||||
#
|
|
||||||
# python-systemd documentation build configuration file, created by
|
|
||||||
# sphinx-quickstart on Sat Feb 9 13:49:42 2013.
|
|
||||||
#
|
|
||||||
# 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.insert(0, os.path.abspath('.'))
|
|
||||||
|
|
||||||
# -- General configuration -----------------------------------------------------
|
|
||||||
|
|
||||||
# If your documentation needs a minimal Sphinx version, state it here.
|
|
||||||
#needs_sphinx = '1.0'
|
|
||||||
|
|
||||||
# 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.autodoc', 'sphinx.ext.doctest', 'sphinx.ext.intersphinx', 'sphinx.ext.coverage', 'sphinx.ext.viewcode']
|
|
||||||
|
|
||||||
# Add any paths that contain templates here, relative to this directory.
|
|
||||||
templates_path = ['.']
|
|
||||||
|
|
||||||
# The suffix of source filenames.
|
|
||||||
source_suffix = '.rst'
|
|
||||||
|
|
||||||
# The encoding of source files.
|
|
||||||
#source_encoding = 'utf-8-sig'
|
|
||||||
|
|
||||||
# The master toctree document.
|
|
||||||
master_doc = 'index'
|
|
||||||
|
|
||||||
# General information about the project.
|
|
||||||
project = u'python-systemd'
|
|
||||||
|
|
||||||
# The language for content autogenerated by Sphinx. Refer to documentation
|
|
||||||
# for a list of supported languages.
|
|
||||||
#language = None
|
|
||||||
|
|
||||||
# There are two options for replacing |today|: either, you set today to some
|
|
||||||
# non-false value, then it is used:
|
|
||||||
#today = ''
|
|
||||||
# Else, today_fmt is used as the format for a strftime call.
|
|
||||||
#today_fmt = '%B %d, %Y'
|
|
||||||
|
|
||||||
# List of patterns, relative to source directory, that match files and
|
|
||||||
# directories to ignore when looking for source files.
|
|
||||||
exclude_patterns = []
|
|
||||||
|
|
||||||
# The reST default role (used for this markup: `text`) to use for all documents.
|
|
||||||
#default_role = None
|
|
||||||
|
|
||||||
# If true, '()' will be appended to :func: etc. cross-reference text.
|
|
||||||
#add_function_parentheses = True
|
|
||||||
|
|
||||||
# If true, the current module name will be prepended to all description
|
|
||||||
# unit titles (such as .. function::).
|
|
||||||
#add_module_names = True
|
|
||||||
|
|
||||||
# If true, sectionauthor and moduleauthor directives will be shown in the
|
|
||||||
# output. They are ignored by default.
|
|
||||||
#show_authors = False
|
|
||||||
|
|
||||||
# The name of the Pygments (syntax highlighting) style to use.
|
|
||||||
pygments_style = 'sphinx'
|
|
||||||
|
|
||||||
# A list of ignored prefixes for module index sorting.
|
|
||||||
#modindex_common_prefix = []
|
|
||||||
|
|
||||||
|
|
||||||
# -- Options for HTML output ---------------------------------------------------
|
|
||||||
|
|
||||||
# The theme to use for HTML and HTML Help pages. See the documentation for
|
|
||||||
# a list of builtin themes.
|
|
||||||
html_theme = 'default'
|
|
||||||
|
|
||||||
# Theme options are theme-specific and customize the look and feel of a theme
|
|
||||||
# further. For a list of options available for each theme, see the
|
|
||||||
# documentation.
|
|
||||||
#html_theme_options = {}
|
|
||||||
|
|
||||||
# Add any paths that contain custom themes here, relative to this directory.
|
|
||||||
#html_theme_path = []
|
|
||||||
|
|
||||||
# The name for this set of Sphinx documents. If None, it defaults to
|
|
||||||
# "<project> v<release> documentation".
|
|
||||||
#html_title = None
|
|
||||||
|
|
||||||
# A shorter title for the navigation bar. Default is the same as html_title.
|
|
||||||
#html_short_title = None
|
|
||||||
|
|
||||||
# The name of an image file (relative to this directory) to place at the top
|
|
||||||
# of the sidebar.
|
|
||||||
#html_logo = None
|
|
||||||
|
|
||||||
# The name of an image file (within the static path) to use as favicon of the
|
|
||||||
# docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32
|
|
||||||
# pixels large.
|
|
||||||
#html_favicon = None
|
|
||||||
|
|
||||||
# Add any paths that contain custom static files (such as style sheets) here,
|
|
||||||
# relative to this directory. They are copied after the builtin static files,
|
|
||||||
# so a file named "default.css" will overwrite the builtin "default.css".
|
|
||||||
html_static_path = ['.']
|
|
||||||
|
|
||||||
# If not '', a 'Last updated on:' timestamp is inserted at every page bottom,
|
|
||||||
# using the given strftime format.
|
|
||||||
#html_last_updated_fmt = '%b %d, %Y'
|
|
||||||
|
|
||||||
# If true, SmartyPants will be used to convert quotes and dashes to
|
|
||||||
# typographically correct entities.
|
|
||||||
#html_use_smartypants = True
|
|
||||||
|
|
||||||
# Custom sidebar templates, maps document names to template names.
|
|
||||||
#html_sidebars = {}
|
|
||||||
|
|
||||||
# Additional templates that should be rendered to pages, maps page names to
|
|
||||||
# template names.
|
|
||||||
#html_additional_pages = {}
|
|
||||||
|
|
||||||
# If false, no module index is generated.
|
|
||||||
#html_domain_indices = True
|
|
||||||
|
|
||||||
# If false, no index is generated.
|
|
||||||
#html_use_index = True
|
|
||||||
|
|
||||||
# If true, the index is split into individual pages for each letter.
|
|
||||||
#html_split_index = False
|
|
||||||
|
|
||||||
# If true, links to the reST sources are added to the pages.
|
|
||||||
html_show_sourcelink = False
|
|
||||||
|
|
||||||
# If true, "Created using Sphinx" is shown in the HTML footer. Default is True.
|
|
||||||
#html_show_sphinx = True
|
|
||||||
|
|
||||||
# If true, "(C) Copyright ..." is shown in the HTML footer. Default is True.
|
|
||||||
#html_show_copyright = True
|
|
||||||
|
|
||||||
# If true, an OpenSearch description file will be output, and all pages will
|
|
||||||
# contain a <link> tag referring to it. The value of this option must be the
|
|
||||||
# base URL from which the finished HTML is served.
|
|
||||||
#html_use_opensearch = ''
|
|
||||||
|
|
||||||
# This is the file name suffix for HTML files (e.g. ".xhtml").
|
|
||||||
#html_file_suffix = None
|
|
||||||
|
|
||||||
# Output file base name for HTML help builder.
|
|
||||||
htmlhelp_basename = 'python-systemddoc'
|
|
||||||
|
|
||||||
|
|
||||||
# -- Options for LaTeX output --------------------------------------------------
|
|
||||||
|
|
||||||
latex_elements = {
|
|
||||||
# The paper size ('letterpaper' or 'a4paper').
|
|
||||||
#'papersize': 'letterpaper',
|
|
||||||
|
|
||||||
# The font size ('10pt', '11pt' or '12pt').
|
|
||||||
#'pointsize': '10pt',
|
|
||||||
|
|
||||||
# Additional stuff for the LaTeX preamble.
|
|
||||||
#'preamble': '',
|
|
||||||
}
|
|
||||||
|
|
||||||
# Grouping the document tree into LaTeX files. List of tuples
|
|
||||||
# (source start file, target name, title, author, documentclass [howto/manual]).
|
|
||||||
latex_documents = [
|
|
||||||
('index', 'python-systemd.tex', u'python-systemd Documentation',
|
|
||||||
None, 'manual'),
|
|
||||||
]
|
|
||||||
|
|
||||||
# The name of an image file (relative to this directory) to place at the top of
|
|
||||||
# the title page.
|
|
||||||
#latex_logo = None
|
|
||||||
|
|
||||||
# For "manual" documents, if this is true, then toplevel headings are parts,
|
|
||||||
# not chapters.
|
|
||||||
#latex_use_parts = False
|
|
||||||
|
|
||||||
# If true, show page references after internal links.
|
|
||||||
#latex_show_pagerefs = False
|
|
||||||
|
|
||||||
# If true, show URL addresses after external links.
|
|
||||||
#latex_show_urls = False
|
|
||||||
|
|
||||||
# Documents to append as an appendix to all manuals.
|
|
||||||
#latex_appendices = []
|
|
||||||
|
|
||||||
# If false, no module index is generated.
|
|
||||||
#latex_domain_indices = True
|
|
||||||
|
|
||||||
|
|
||||||
# -- Options for manual page output --------------------------------------------
|
|
||||||
|
|
||||||
# One entry per manual page. List of tuples
|
|
||||||
# (source start file, name, description, authors, manual section).
|
|
||||||
man_pages = [
|
|
||||||
('index', 'python-systemd', u'python-systemd Documentation',
|
|
||||||
[], 1)
|
|
||||||
]
|
|
||||||
|
|
||||||
# If true, show URL addresses after external links.
|
|
||||||
#man_show_urls = False
|
|
||||||
|
|
||||||
|
|
||||||
# -- Options for Texinfo output ------------------------------------------------
|
|
||||||
|
|
||||||
# Grouping the document tree into Texinfo files. List of tuples
|
|
||||||
# (source start file, target name, title, author,
|
|
||||||
# dir menu entry, description, category)
|
|
||||||
texinfo_documents = [
|
|
||||||
('index', 'python-systemd', u'python-systemd Documentation',
|
|
||||||
u'David Strauss, Zbigniew Jędrzejewski-Szmek, Marti Raudsepp, Steven Hiscocks', 'python-systemd', 'One line description of project.',
|
|
||||||
'Miscellaneous'),
|
|
||||||
]
|
|
||||||
|
|
||||||
# Documents to append as an appendix to all manuals.
|
|
||||||
#texinfo_appendices = []
|
|
||||||
|
|
||||||
# If false, no module index is generated.
|
|
||||||
#texinfo_domain_indices = True
|
|
||||||
|
|
||||||
# How to display URL addresses: 'footnote', 'no', or 'inline'.
|
|
||||||
#texinfo_show_urls = 'footnote'
|
|
||||||
|
|
||||||
|
|
||||||
# -- Options for Epub output ---------------------------------------------------
|
|
||||||
|
|
||||||
# Bibliographic Dublin Core info.
|
|
||||||
epub_title = u'python-systemd'
|
|
||||||
epub_author = u'David Strauss, Zbigniew Jędrzejewski-Szmek, Marti Raudsepp, Steven Hiscocks'
|
|
||||||
epub_publisher = u'David Strauss, Zbigniew Jędrzejewski-Szmek, Marti Raudsepp, Steven Hiscocks'
|
|
||||||
epub_copyright = u'2013, David Strauss, Zbigniew Jędrzejewski-Szmek, Marti Raudsepp, Steven Hiscocks'
|
|
||||||
|
|
||||||
# The language of the text. It defaults to the language option
|
|
||||||
# or en if the language is not set.
|
|
||||||
#epub_language = ''
|
|
||||||
|
|
||||||
# The scheme of the identifier. Typical schemes are ISBN or URL.
|
|
||||||
#epub_scheme = ''
|
|
||||||
|
|
||||||
# The unique identifier of the text. This can be a ISBN number
|
|
||||||
# or the project homepage.
|
|
||||||
#epub_identifier = ''
|
|
||||||
|
|
||||||
# A unique identification for the text.
|
|
||||||
#epub_uid = ''
|
|
||||||
|
|
||||||
# A tuple containing the cover image and cover page html template filenames.
|
|
||||||
#epub_cover = ()
|
|
||||||
|
|
||||||
# HTML files that should be inserted before the pages created by sphinx.
|
|
||||||
# The format is a list of tuples containing the path and title.
|
|
||||||
#epub_pre_files = []
|
|
||||||
|
|
||||||
# HTML files shat should be inserted after the pages created by sphinx.
|
|
||||||
# The format is a list of tuples containing the path and title.
|
|
||||||
#epub_post_files = []
|
|
||||||
|
|
||||||
# A list of files that should not be packed into the epub file.
|
|
||||||
#epub_exclude_files = []
|
|
||||||
|
|
||||||
# The depth of the table of contents in toc.ncx.
|
|
||||||
#epub_tocdepth = 3
|
|
||||||
|
|
||||||
# Allow duplicate toc entries.
|
|
||||||
#epub_tocdup = True
|
|
||||||
|
|
||||||
|
|
||||||
# Example configuration for intersphinx: refer to the Python standard library.
|
|
||||||
intersphinx_mapping = {'http://docs.python.org/': None}
|
|
@ -1,18 +0,0 @@
|
|||||||
`systemd.daemon` module
|
|
||||||
=======================
|
|
||||||
|
|
||||||
.. automodule:: systemd.daemon
|
|
||||||
:members:
|
|
||||||
:undoc-members:
|
|
||||||
:inherited-members:
|
|
||||||
|
|
||||||
.. autoattribute:: systemd.daemon.LISTEN_FDS_START
|
|
||||||
|
|
||||||
.. autofunction:: _listen_fds
|
|
||||||
.. autofunction:: _is_fifo
|
|
||||||
.. autofunction:: _is_socket
|
|
||||||
.. autofunction:: _is_socket_unix
|
|
||||||
.. autofunction:: _is_socket_inet
|
|
||||||
.. autofunction:: _is_mq
|
|
||||||
.. autofunction:: notify
|
|
||||||
.. autofunction:: booted
|
|
@ -1,196 +0,0 @@
|
|||||||
@import url("basic.css");
|
|
||||||
|
|
||||||
/* -- page layout ----------------------------------------------------------- */
|
|
||||||
|
|
||||||
div.documentwrapper {
|
|
||||||
float: left;
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
div.bodywrapper {
|
|
||||||
margin: 0 0 0 230px;
|
|
||||||
}
|
|
||||||
|
|
||||||
div.body {
|
|
||||||
background-color: #ffffff;
|
|
||||||
color: #000000;
|
|
||||||
padding: 0 20px 30px 20px;
|
|
||||||
}
|
|
||||||
|
|
||||||
div.footer {
|
|
||||||
color: #ffffff;
|
|
||||||
width: 100%;
|
|
||||||
padding: 9px 0 9px 0;
|
|
||||||
text-align: center;
|
|
||||||
font-size: 75%;
|
|
||||||
}
|
|
||||||
|
|
||||||
div.footer a {
|
|
||||||
color: #ffffff;
|
|
||||||
text-decoration: underline;
|
|
||||||
}
|
|
||||||
|
|
||||||
div.related {
|
|
||||||
background-color: #133f52;
|
|
||||||
line-height: 30px;
|
|
||||||
color: #ffffff;
|
|
||||||
}
|
|
||||||
|
|
||||||
div.related a {
|
|
||||||
color: #ffffff;
|
|
||||||
}
|
|
||||||
|
|
||||||
div.sphinxsidebar {
|
|
||||||
background-color: #dddddd;
|
|
||||||
}
|
|
||||||
|
|
||||||
div.sphinxsidebar p.topless {
|
|
||||||
margin: 5px 10px 10px 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
div.sphinxsidebar ul {
|
|
||||||
margin: 10px;
|
|
||||||
padding: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
div.sphinxsidebar input {
|
|
||||||
border: 1px solid #000000;
|
|
||||||
font-family: sans-serif;
|
|
||||||
font-size: 1em;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* -- hyperlink styles ------------------------------------------------------ */
|
|
||||||
|
|
||||||
a {
|
|
||||||
text-decoration: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
a:hover {
|
|
||||||
text-decoration: underline;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* -- body styles ----------------------------------------------------------- */
|
|
||||||
|
|
||||||
div.body h1,
|
|
||||||
div.body h2,
|
|
||||||
div.body h3,
|
|
||||||
div.body h4,
|
|
||||||
div.body h5,
|
|
||||||
div.body h6 {
|
|
||||||
font-family: 'Trebuchet MS', sans-serif;
|
|
||||||
background-color: #f2f2f2;
|
|
||||||
font-weight: normal;
|
|
||||||
color: #20435c;
|
|
||||||
border-bottom: 1px solid #ccc;
|
|
||||||
margin: 20px -20px 10px -20px;
|
|
||||||
padding: 3px 0 3px 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
div.body h1 { margin-top: 0; font-size: 200%; }
|
|
||||||
div.body h2 { font-size: 160%; }
|
|
||||||
div.body h3 { font-size: 140%; }
|
|
||||||
div.body h4 { font-size: 120%; }
|
|
||||||
div.body h5 { font-size: 110%; }
|
|
||||||
div.body h6 { font-size: 100%; }
|
|
||||||
|
|
||||||
a.headerlink {
|
|
||||||
color: #c60f0f;
|
|
||||||
font-size: 0.8em;
|
|
||||||
padding: 0 4px 0 4px;
|
|
||||||
text-decoration: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
a.headerlink:hover {
|
|
||||||
background-color: #c60f0f;
|
|
||||||
color: white;
|
|
||||||
}
|
|
||||||
|
|
||||||
div.body p, div.body dd, div.body li {
|
|
||||||
text-align: justify;
|
|
||||||
line-height: 130%;
|
|
||||||
}
|
|
||||||
|
|
||||||
div.admonition p.admonition-title + p {
|
|
||||||
display: inline;
|
|
||||||
}
|
|
||||||
|
|
||||||
div.admonition p {
|
|
||||||
margin-bottom: 5px;
|
|
||||||
}
|
|
||||||
|
|
||||||
div.admonition pre {
|
|
||||||
margin-bottom: 5px;
|
|
||||||
}
|
|
||||||
|
|
||||||
div.admonition ul, div.admonition ol {
|
|
||||||
margin-bottom: 5px;
|
|
||||||
}
|
|
||||||
|
|
||||||
div.note {
|
|
||||||
background-color: #eee;
|
|
||||||
border: 1px solid #ccc;
|
|
||||||
}
|
|
||||||
|
|
||||||
div.seealso {
|
|
||||||
background-color: #ffc;
|
|
||||||
border: 1px solid #ff6;
|
|
||||||
}
|
|
||||||
|
|
||||||
div.topic {
|
|
||||||
background-color: #eee;
|
|
||||||
}
|
|
||||||
|
|
||||||
div.warning {
|
|
||||||
background-color: #ffe4e4;
|
|
||||||
border: 1px solid #f66;
|
|
||||||
}
|
|
||||||
|
|
||||||
p.admonition-title {
|
|
||||||
display: inline;
|
|
||||||
}
|
|
||||||
|
|
||||||
p.admonition-title:after {
|
|
||||||
content: ":";
|
|
||||||
}
|
|
||||||
|
|
||||||
pre {
|
|
||||||
padding: 5px;
|
|
||||||
background-color: #eeffcc;
|
|
||||||
color: #333333;
|
|
||||||
line-height: 120%;
|
|
||||||
border: 1px solid #ac9;
|
|
||||||
border-left: none;
|
|
||||||
border-right: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
tt {
|
|
||||||
background-color: #ecf0f3;
|
|
||||||
padding: 0 1px 0 1px;
|
|
||||||
font-size: 0.95em;
|
|
||||||
}
|
|
||||||
|
|
||||||
th {
|
|
||||||
background-color: #ede;
|
|
||||||
}
|
|
||||||
|
|
||||||
.warning tt {
|
|
||||||
background: #efc2c2;
|
|
||||||
}
|
|
||||||
|
|
||||||
.note tt {
|
|
||||||
background: #d6d6d6;
|
|
||||||
}
|
|
||||||
|
|
||||||
.viewcode-back {
|
|
||||||
font-family: sans-serif;
|
|
||||||
}
|
|
||||||
|
|
||||||
div.viewcode-block:target {
|
|
||||||
background-color: #f4debf;
|
|
||||||
border-top: 1px solid #ac9;
|
|
||||||
border-bottom: 1px solid #ac9;
|
|
||||||
}
|
|
@ -1,40 +0,0 @@
|
|||||||
`systemd.id128` module
|
|
||||||
======================
|
|
||||||
|
|
||||||
.. automodule:: systemd.id128
|
|
||||||
:members:
|
|
||||||
:undoc-members:
|
|
||||||
:inherited-members:
|
|
||||||
|
|
||||||
.. autoattribute:: systemd.id128.SD_MESSAGE_COREDUMP
|
|
||||||
.. autoattribute:: systemd.id128.SD_MESSAGE_FORWARD_SYSLOG_MISSED
|
|
||||||
.. autoattribute:: systemd.id128.SD_MESSAGE_HIBERNATE_KEY
|
|
||||||
.. autoattribute:: systemd.id128.SD_MESSAGE_JOURNAL_DROPPED
|
|
||||||
.. autoattribute:: systemd.id128.SD_MESSAGE_JOURNAL_MISSED
|
|
||||||
.. autoattribute:: systemd.id128.SD_MESSAGE_JOURNAL_START
|
|
||||||
.. autoattribute:: systemd.id128.SD_MESSAGE_JOURNAL_STOP
|
|
||||||
.. autoattribute:: systemd.id128.SD_MESSAGE_LID_CLOSED
|
|
||||||
.. autoattribute:: systemd.id128.SD_MESSAGE_LID_OPENED
|
|
||||||
.. autoattribute:: systemd.id128.SD_MESSAGE_OVERMOUNTING
|
|
||||||
.. autoattribute:: systemd.id128.SD_MESSAGE_POWER_KEY
|
|
||||||
.. autoattribute:: systemd.id128.SD_MESSAGE_SEAT_START
|
|
||||||
.. autoattribute:: systemd.id128.SD_MESSAGE_SEAT_STOP
|
|
||||||
.. autoattribute:: systemd.id128.SD_MESSAGE_SESSION_START
|
|
||||||
.. autoattribute:: systemd.id128.SD_MESSAGE_SESSION_STOP
|
|
||||||
.. autoattribute:: systemd.id128.SD_MESSAGE_SHUTDOWN
|
|
||||||
.. autoattribute:: systemd.id128.SD_MESSAGE_SLEEP_START
|
|
||||||
.. autoattribute:: systemd.id128.SD_MESSAGE_SLEEP_STOP
|
|
||||||
.. autoattribute:: systemd.id128.SD_MESSAGE_SPAWN_FAILED
|
|
||||||
.. autoattribute:: systemd.id128.SD_MESSAGE_STARTUP_FINISHED
|
|
||||||
.. autoattribute:: systemd.id128.SD_MESSAGE_SUSPEND_KEY
|
|
||||||
.. autoattribute:: systemd.id128.SD_MESSAGE_TIMEZONE_CHANGE
|
|
||||||
.. autoattribute:: systemd.id128.SD_MESSAGE_TIME_CHANGE
|
|
||||||
.. autoattribute:: systemd.id128.SD_MESSAGE_UNIT_FAILED
|
|
||||||
.. autoattribute:: systemd.id128.SD_MESSAGE_UNIT_RELOADED
|
|
||||||
.. autoattribute:: systemd.id128.SD_MESSAGE_UNIT_RELOADING
|
|
||||||
.. autoattribute:: systemd.id128.SD_MESSAGE_UNIT_STARTED
|
|
||||||
.. autoattribute:: systemd.id128.SD_MESSAGE_UNIT_STARTING
|
|
||||||
.. autoattribute:: systemd.id128.SD_MESSAGE_UNIT_STOPPED
|
|
||||||
.. autoattribute:: systemd.id128.SD_MESSAGE_UNIT_STOPPING
|
|
||||||
.. autoattribute:: systemd.id128.SD_MESSAGE_CONFIG_ERROR
|
|
||||||
.. autoattribute:: systemd.id128.SD_MESSAGE_BOOTCHART
|
|
@ -1,24 +0,0 @@
|
|||||||
.. python-systemd documentation master file, created by
|
|
||||||
sphinx-quickstart on Sat Feb 9 13:49:42 2013.
|
|
||||||
You can adapt this file completely to your liking, but it should at least
|
|
||||||
contain the root `toctree` directive.
|
|
||||||
|
|
||||||
Welcome to python-systemd's documentation!
|
|
||||||
==========================================
|
|
||||||
|
|
||||||
Contents:
|
|
||||||
|
|
||||||
.. toctree::
|
|
||||||
:maxdepth: 2
|
|
||||||
|
|
||||||
journal
|
|
||||||
id128
|
|
||||||
daemon
|
|
||||||
login
|
|
||||||
|
|
||||||
Indices and tables
|
|
||||||
==================
|
|
||||||
|
|
||||||
* :ref:`genindex`
|
|
||||||
* :ref:`modindex`
|
|
||||||
* :ref:`search`
|
|
@ -1,64 +0,0 @@
|
|||||||
`systemd.journal` module
|
|
||||||
========================
|
|
||||||
|
|
||||||
.. automodule:: systemd.journal
|
|
||||||
:members: send, sendv, stream, stream_fd
|
|
||||||
:undoc-members:
|
|
||||||
|
|
||||||
`JournalHandler` class
|
|
||||||
----------------------
|
|
||||||
|
|
||||||
.. autoclass:: JournalHandler
|
|
||||||
|
|
||||||
Accessing the Journal
|
|
||||||
---------------------
|
|
||||||
|
|
||||||
.. autoclass:: _Reader
|
|
||||||
:undoc-members:
|
|
||||||
:inherited-members:
|
|
||||||
|
|
||||||
.. autoclass:: Reader
|
|
||||||
:undoc-members:
|
|
||||||
:inherited-members:
|
|
||||||
|
|
||||||
.. automethod:: __init__
|
|
||||||
|
|
||||||
.. autofunction:: _get_catalog
|
|
||||||
.. autofunction:: get_catalog
|
|
||||||
|
|
||||||
.. autoclass:: Monotonic
|
|
||||||
|
|
||||||
.. autoattribute:: systemd.journal.DEFAULT_CONVERTERS
|
|
||||||
|
|
||||||
Example: polling for journal events
|
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
This example shows that journal events can be waited for (using
|
|
||||||
e.g. `poll`). This makes it easy to integrate Reader in an external
|
|
||||||
event loop:
|
|
||||||
|
|
||||||
>>> import select
|
|
||||||
>>> from systemd import journal
|
|
||||||
>>> j = journal.Reader()
|
|
||||||
>>> j.seek_tail()
|
|
||||||
>>> p = select.poll()
|
|
||||||
>>> p.register(j, j.get_events())
|
|
||||||
>>> p.poll()
|
|
||||||
[(3, 1)]
|
|
||||||
>>> j.get_next()
|
|
||||||
|
|
||||||
|
|
||||||
Journal access types
|
|
||||||
~~~~~~~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
.. autoattribute:: systemd.journal.LOCAL_ONLY
|
|
||||||
.. autoattribute:: systemd.journal.RUNTIME_ONLY
|
|
||||||
.. autoattribute:: systemd.journal.SYSTEM
|
|
||||||
.. autoattribute:: systemd.journal.CURRENT_USER
|
|
||||||
|
|
||||||
Journal event types
|
|
||||||
~~~~~~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
.. autoattribute:: systemd.journal.NOP
|
|
||||||
.. autoattribute:: systemd.journal.APPEND
|
|
||||||
.. autoattribute:: systemd.journal.INVALIDATE
|
|
@ -1,15 +0,0 @@
|
|||||||
{% extends "!layout.html" %}
|
|
||||||
|
|
||||||
{% block relbar1 %}
|
|
||||||
<a href="../man/systemd.index.html">Index </a>·
|
|
||||||
<a href="../man/systemd.directives.html">Directives </a>·
|
|
||||||
<a href="index.html">Python </a>·
|
|
||||||
<span style="float:right">systemd {{release}}</span>
|
|
||||||
<hr />
|
|
||||||
{% endblock %}
|
|
||||||
|
|
||||||
{# remove the lower relbar #}
|
|
||||||
{% block relbar2 %} {% endblock %}
|
|
||||||
|
|
||||||
{# remove the footer #}
|
|
||||||
{% block footer %} {% endblock %}
|
|
@ -1,28 +0,0 @@
|
|||||||
`systemd.login` module
|
|
||||||
=======================
|
|
||||||
|
|
||||||
.. automodule:: systemd.login
|
|
||||||
:members:
|
|
||||||
|
|
||||||
.. autoclass:: Monitor
|
|
||||||
:undoc-members:
|
|
||||||
:inherited-members:
|
|
||||||
|
|
||||||
Example: polling for events
|
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
This example shows that session/uid/seat/machine events can be waited
|
|
||||||
for (using e.g. `poll`). This makes it easy to integrate Monitor in an
|
|
||||||
external event loop:
|
|
||||||
|
|
||||||
>>> import select
|
|
||||||
>>> from systemd import login
|
|
||||||
>>> m = login.Monitor("machine")
|
|
||||||
>>> p = select.poll()
|
|
||||||
>>> p.register(m, m.get_events())
|
|
||||||
>>> login.machine_names()
|
|
||||||
[]
|
|
||||||
>>> p.poll()
|
|
||||||
[(3, 1)]
|
|
||||||
>>> login.machine_names()
|
|
||||||
['fedora-19.nspawn']
|
|
@ -1,163 +0,0 @@
|
|||||||
/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
|
|
||||||
|
|
||||||
/***
|
|
||||||
This file is part of systemd.
|
|
||||||
|
|
||||||
Copyright 2013 Zbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
|
|
||||||
|
|
||||||
systemd is free software; you can redistribute it and/or modify it
|
|
||||||
under the terms of the GNU Lesser General Public License as published by
|
|
||||||
the Free Software Foundation; either version 2.1 of the License, or
|
|
||||||
(at your option) any later version.
|
|
||||||
|
|
||||||
systemd is distributed in the hope that it will be useful, but
|
|
||||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
Lesser General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU Lesser General Public License
|
|
||||||
along with systemd; If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
***/
|
|
||||||
|
|
||||||
#include <Python.h>
|
|
||||||
|
|
||||||
#include "systemd/sd-messages.h"
|
|
||||||
|
|
||||||
#include "pyutil.h"
|
|
||||||
#include "log.h"
|
|
||||||
#include "util.h"
|
|
||||||
#include "macro.h"
|
|
||||||
|
|
||||||
PyDoc_STRVAR(module__doc__,
|
|
||||||
"Python interface to the libsystemd-id128 library.\n\n"
|
|
||||||
"Provides SD_MESSAGE_* constants and functions to query and generate\n"
|
|
||||||
"128-bit unique identifiers."
|
|
||||||
);
|
|
||||||
|
|
||||||
PyDoc_STRVAR(randomize__doc__,
|
|
||||||
"randomize() -> UUID\n\n"
|
|
||||||
"Return a new random 128-bit unique identifier.\n"
|
|
||||||
"Wraps sd_id128_randomize(3)."
|
|
||||||
);
|
|
||||||
|
|
||||||
PyDoc_STRVAR(get_machine__doc__,
|
|
||||||
"get_machine() -> UUID\n\n"
|
|
||||||
"Return a 128-bit unique identifier for this machine.\n"
|
|
||||||
"Wraps sd_id128_get_machine(3)."
|
|
||||||
);
|
|
||||||
|
|
||||||
PyDoc_STRVAR(get_boot__doc__,
|
|
||||||
"get_boot() -> UUID\n\n"
|
|
||||||
"Return a 128-bit unique identifier for this boot.\n"
|
|
||||||
"Wraps sd_id128_get_boot(3)."
|
|
||||||
);
|
|
||||||
|
|
||||||
static PyObject* make_uuid(sd_id128_t id) {
|
|
||||||
_cleanup_Py_DECREF_ PyObject
|
|
||||||
*uuid = NULL, *UUID = NULL, *bytes = NULL,
|
|
||||||
*args = NULL, *kwargs = NULL;
|
|
||||||
|
|
||||||
uuid = PyImport_ImportModule("uuid");
|
|
||||||
if (!uuid)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
UUID = PyObject_GetAttrString(uuid, "UUID");
|
|
||||||
bytes = PyBytes_FromStringAndSize((const char*) &id.bytes, sizeof(id.bytes));
|
|
||||||
args = Py_BuildValue("()");
|
|
||||||
kwargs = PyDict_New();
|
|
||||||
if (!UUID || !bytes || !args || !kwargs)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
if (PyDict_SetItemString(kwargs, "bytes", bytes) < 0)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
return PyObject_Call(UUID, args, kwargs);
|
|
||||||
}
|
|
||||||
|
|
||||||
#define helper(name) \
|
|
||||||
static PyObject *name(PyObject *self, PyObject *args) { \
|
|
||||||
sd_id128_t id; \
|
|
||||||
int r; \
|
|
||||||
\
|
|
||||||
assert(args == NULL); \
|
|
||||||
\
|
|
||||||
r = sd_id128_##name(&id); \
|
|
||||||
if (r < 0) { \
|
|
||||||
errno = -r; \
|
|
||||||
return PyErr_SetFromErrno(PyExc_IOError); \
|
|
||||||
} \
|
|
||||||
\
|
|
||||||
return make_uuid(id); \
|
|
||||||
}
|
|
||||||
|
|
||||||
helper(randomize)
|
|
||||||
helper(get_machine)
|
|
||||||
helper(get_boot)
|
|
||||||
|
|
||||||
static PyMethodDef methods[] = {
|
|
||||||
{ "randomize", randomize, METH_NOARGS, randomize__doc__},
|
|
||||||
{ "get_machine", get_machine, METH_NOARGS, get_machine__doc__},
|
|
||||||
{ "get_boot", get_boot, METH_NOARGS, get_boot__doc__},
|
|
||||||
{ NULL, NULL, 0, NULL } /* Sentinel */
|
|
||||||
};
|
|
||||||
|
|
||||||
static int add_id(PyObject *module, const char* name, sd_id128_t id) {
|
|
||||||
PyObject *obj;
|
|
||||||
|
|
||||||
obj = make_uuid(id);
|
|
||||||
if (!obj)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
return PyModule_AddObject(module, name, obj);
|
|
||||||
}
|
|
||||||
|
|
||||||
#if PY_MAJOR_VERSION < 3
|
|
||||||
|
|
||||||
DISABLE_WARNING_MISSING_PROTOTYPES;
|
|
||||||
PyMODINIT_FUNC initid128(void) {
|
|
||||||
PyObject *m;
|
|
||||||
|
|
||||||
m = Py_InitModule3("id128", methods, module__doc__);
|
|
||||||
if (m == NULL)
|
|
||||||
return;
|
|
||||||
|
|
||||||
/* a series of lines like 'add_id() ;' follow */
|
|
||||||
#define JOINER ;
|
|
||||||
#include "id128-constants.h"
|
|
||||||
#undef JOINER
|
|
||||||
PyModule_AddStringConstant(m, "__version__", PACKAGE_VERSION);
|
|
||||||
}
|
|
||||||
REENABLE_WARNING;
|
|
||||||
|
|
||||||
#else
|
|
||||||
|
|
||||||
static struct PyModuleDef module = {
|
|
||||||
PyModuleDef_HEAD_INIT,
|
|
||||||
"id128", /* name of module */
|
|
||||||
module__doc__, /* module documentation, may be NULL */
|
|
||||||
-1, /* size of per-interpreter state of the module */
|
|
||||||
methods
|
|
||||||
};
|
|
||||||
|
|
||||||
DISABLE_WARNING_MISSING_PROTOTYPES;
|
|
||||||
PyMODINIT_FUNC PyInit_id128(void) {
|
|
||||||
PyObject *m;
|
|
||||||
|
|
||||||
m = PyModule_Create(&module);
|
|
||||||
if (m == NULL)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
if ( /* a series of lines like 'add_id() ||' follow */
|
|
||||||
#define JOINER ||
|
|
||||||
#include "id128-constants.h"
|
|
||||||
#undef JOINER
|
|
||||||
PyModule_AddStringConstant(m, "__version__", PACKAGE_VERSION)) {
|
|
||||||
Py_DECREF(m);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
return m;
|
|
||||||
}
|
|
||||||
REENABLE_WARNING;
|
|
||||||
|
|
||||||
#endif
|
|
@ -1,548 +0,0 @@
|
|||||||
# -*- Mode: python; coding:utf-8; indent-tabs-mode: nil -*- */
|
|
||||||
#
|
|
||||||
# This file is part of systemd.
|
|
||||||
#
|
|
||||||
# Copyright 2012 David Strauss <david@davidstrauss.net>
|
|
||||||
# Copyright 2012 Zbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
|
|
||||||
# Copyright 2012 Marti Raudsepp <marti@juffo.org>
|
|
||||||
#
|
|
||||||
# systemd is free software; you can redistribute it and/or modify it
|
|
||||||
# under the terms of the GNU Lesser General Public License as published by
|
|
||||||
# the Free Software Foundation; either version 2.1 of the License, or
|
|
||||||
# (at your option) any later version.
|
|
||||||
#
|
|
||||||
# systemd is distributed in the hope that it will be useful, but
|
|
||||||
# WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
# Lesser General Public License for more details.
|
|
||||||
#
|
|
||||||
# You should have received a copy of the GNU Lesser General Public License
|
|
||||||
# along with systemd; If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
from __future__ import division
|
|
||||||
|
|
||||||
import sys as _sys
|
|
||||||
import datetime as _datetime
|
|
||||||
import uuid as _uuid
|
|
||||||
import traceback as _traceback
|
|
||||||
import os as _os
|
|
||||||
import logging as _logging
|
|
||||||
if _sys.version_info >= (3,3):
|
|
||||||
from collections import ChainMap as _ChainMap
|
|
||||||
from syslog import (LOG_EMERG, LOG_ALERT, LOG_CRIT, LOG_ERR,
|
|
||||||
LOG_WARNING, LOG_NOTICE, LOG_INFO, LOG_DEBUG)
|
|
||||||
from ._journal import __version__, sendv, stream_fd
|
|
||||||
from ._reader import (_Reader, NOP, APPEND, INVALIDATE,
|
|
||||||
LOCAL_ONLY, RUNTIME_ONLY,
|
|
||||||
SYSTEM, SYSTEM_ONLY, CURRENT_USER,
|
|
||||||
_get_catalog)
|
|
||||||
from . import id128 as _id128
|
|
||||||
|
|
||||||
if _sys.version_info >= (3,):
|
|
||||||
from ._reader import Monotonic
|
|
||||||
else:
|
|
||||||
Monotonic = tuple
|
|
||||||
|
|
||||||
def _convert_monotonic(m):
|
|
||||||
return Monotonic((_datetime.timedelta(microseconds=m[0]),
|
|
||||||
_uuid.UUID(bytes=m[1])))
|
|
||||||
|
|
||||||
def _convert_source_monotonic(s):
|
|
||||||
return _datetime.timedelta(microseconds=int(s))
|
|
||||||
|
|
||||||
def _convert_realtime(t):
|
|
||||||
return _datetime.datetime.fromtimestamp(t / 1000000)
|
|
||||||
|
|
||||||
def _convert_timestamp(s):
|
|
||||||
return _datetime.datetime.fromtimestamp(int(s) / 1000000)
|
|
||||||
|
|
||||||
def _convert_trivial(x):
|
|
||||||
return x
|
|
||||||
|
|
||||||
if _sys.version_info >= (3,):
|
|
||||||
def _convert_uuid(s):
|
|
||||||
return _uuid.UUID(s.decode())
|
|
||||||
else:
|
|
||||||
_convert_uuid = _uuid.UUID
|
|
||||||
|
|
||||||
DEFAULT_CONVERTERS = {
|
|
||||||
'MESSAGE_ID': _convert_uuid,
|
|
||||||
'_MACHINE_ID': _convert_uuid,
|
|
||||||
'_BOOT_ID': _convert_uuid,
|
|
||||||
'PRIORITY': int,
|
|
||||||
'LEADER': int,
|
|
||||||
'SESSION_ID': int,
|
|
||||||
'USERSPACE_USEC': int,
|
|
||||||
'INITRD_USEC': int,
|
|
||||||
'KERNEL_USEC': int,
|
|
||||||
'_UID': int,
|
|
||||||
'_GID': int,
|
|
||||||
'_PID': int,
|
|
||||||
'SYSLOG_FACILITY': int,
|
|
||||||
'SYSLOG_PID': int,
|
|
||||||
'_AUDIT_SESSION': int,
|
|
||||||
'_AUDIT_LOGINUID': int,
|
|
||||||
'_SYSTEMD_SESSION': int,
|
|
||||||
'_SYSTEMD_OWNER_UID': int,
|
|
||||||
'CODE_LINE': int,
|
|
||||||
'ERRNO': int,
|
|
||||||
'EXIT_STATUS': int,
|
|
||||||
'_SOURCE_REALTIME_TIMESTAMP': _convert_timestamp,
|
|
||||||
'__REALTIME_TIMESTAMP': _convert_realtime,
|
|
||||||
'_SOURCE_MONOTONIC_TIMESTAMP': _convert_source_monotonic,
|
|
||||||
'__MONOTONIC_TIMESTAMP': _convert_monotonic,
|
|
||||||
'__CURSOR': _convert_trivial,
|
|
||||||
'COREDUMP': bytes,
|
|
||||||
'COREDUMP_PID': int,
|
|
||||||
'COREDUMP_UID': int,
|
|
||||||
'COREDUMP_GID': int,
|
|
||||||
'COREDUMP_SESSION': int,
|
|
||||||
'COREDUMP_SIGNAL': int,
|
|
||||||
'COREDUMP_TIMESTAMP': _convert_timestamp,
|
|
||||||
}
|
|
||||||
|
|
||||||
_IDENT_LETTER = set('ABCDEFGHIJKLMNOPQRTSUVWXYZ_')
|
|
||||||
|
|
||||||
def _valid_field_name(s):
|
|
||||||
return not (set(s) - _IDENT_LETTER)
|
|
||||||
|
|
||||||
class Reader(_Reader):
|
|
||||||
"""Reader allows the access and filtering of systemd journal
|
|
||||||
entries. Note that in order to access the system journal, a
|
|
||||||
non-root user must be in the `systemd-journal` group.
|
|
||||||
|
|
||||||
Example usage to print out all informational or higher level
|
|
||||||
messages for systemd-udevd for this boot:
|
|
||||||
|
|
||||||
>>> j = journal.Reader()
|
|
||||||
>>> j.this_boot()
|
|
||||||
>>> j.log_level(journal.LOG_INFO)
|
|
||||||
>>> j.add_match(_SYSTEMD_UNIT="systemd-udevd.service")
|
|
||||||
>>> for entry in j:
|
|
||||||
... print(entry['MESSAGE'])
|
|
||||||
|
|
||||||
See systemd.journal-fields(7) for more info on typical fields
|
|
||||||
found in the journal.
|
|
||||||
"""
|
|
||||||
def __init__(self, flags=0, path=None, files=None, converters=None):
|
|
||||||
"""Create an instance of Reader, which allows filtering and
|
|
||||||
return of journal entries.
|
|
||||||
|
|
||||||
Argument `flags` sets open flags of the journal, which can be one
|
|
||||||
of, or ORed combination of constants: LOCAL_ONLY (default) opens
|
|
||||||
journal on local machine only; RUNTIME_ONLY opens only
|
|
||||||
volatile journal files; and SYSTEM_ONLY opens only
|
|
||||||
journal files of system services and the kernel.
|
|
||||||
|
|
||||||
Argument `path` is the directory of journal files. Note that
|
|
||||||
`flags` and `path` are exclusive.
|
|
||||||
|
|
||||||
Argument `converters` is a dictionary which updates the
|
|
||||||
DEFAULT_CONVERTERS to convert journal field values. Field
|
|
||||||
names are used as keys into this dictionary. The values must
|
|
||||||
be single argument functions, which take a `bytes` object and
|
|
||||||
return a converted value. When there's no entry for a field
|
|
||||||
name, then the default UTF-8 decoding will be attempted. If
|
|
||||||
the conversion fails with a ValueError, unconverted bytes
|
|
||||||
object will be returned. (Note that ValueEror is a superclass
|
|
||||||
of UnicodeDecodeError).
|
|
||||||
|
|
||||||
Reader implements the context manager protocol: the journal
|
|
||||||
will be closed when exiting the block.
|
|
||||||
"""
|
|
||||||
super(Reader, self).__init__(flags, path, files)
|
|
||||||
if _sys.version_info >= (3,3):
|
|
||||||
self.converters = _ChainMap()
|
|
||||||
if converters is not None:
|
|
||||||
self.converters.maps.append(converters)
|
|
||||||
self.converters.maps.append(DEFAULT_CONVERTERS)
|
|
||||||
else:
|
|
||||||
self.converters = DEFAULT_CONVERTERS.copy()
|
|
||||||
if converters is not None:
|
|
||||||
self.converters.update(converters)
|
|
||||||
|
|
||||||
def _convert_field(self, key, value):
|
|
||||||
"""Convert value using self.converters[key]
|
|
||||||
|
|
||||||
If `key` is not present in self.converters, a standard unicode
|
|
||||||
decoding will be attempted. If the conversion (either
|
|
||||||
key-specific or the default one) fails with a ValueError, the
|
|
||||||
original bytes object will be returned.
|
|
||||||
"""
|
|
||||||
convert = self.converters.get(key, bytes.decode)
|
|
||||||
try:
|
|
||||||
return convert(value)
|
|
||||||
except ValueError:
|
|
||||||
# Leave in default bytes
|
|
||||||
return value
|
|
||||||
|
|
||||||
def _convert_entry(self, entry):
|
|
||||||
"""Convert entire journal entry utilising _covert_field"""
|
|
||||||
result = {}
|
|
||||||
for key, value in entry.items():
|
|
||||||
if isinstance(value, list):
|
|
||||||
result[key] = [self._convert_field(key, val) for val in value]
|
|
||||||
else:
|
|
||||||
result[key] = self._convert_field(key, value)
|
|
||||||
return result
|
|
||||||
|
|
||||||
def __iter__(self):
|
|
||||||
"""Part of iterator protocol.
|
|
||||||
Returns self.
|
|
||||||
"""
|
|
||||||
return self
|
|
||||||
|
|
||||||
def __next__(self):
|
|
||||||
"""Part of iterator protocol.
|
|
||||||
Returns self.get_next() or raises StopIteration.
|
|
||||||
"""
|
|
||||||
ans = self.get_next()
|
|
||||||
if ans:
|
|
||||||
return ans
|
|
||||||
else:
|
|
||||||
raise StopIteration()
|
|
||||||
|
|
||||||
if _sys.version_info < (3,):
|
|
||||||
next = __next__
|
|
||||||
|
|
||||||
def add_match(self, *args, **kwargs):
|
|
||||||
"""Add one or more matches to the filter journal log entries.
|
|
||||||
All matches of different field are combined in a logical AND,
|
|
||||||
and matches of the same field are automatically combined in a
|
|
||||||
logical OR.
|
|
||||||
Matches can be passed as strings of form "FIELD=value", or
|
|
||||||
keyword arguments FIELD="value".
|
|
||||||
"""
|
|
||||||
args = list(args)
|
|
||||||
args.extend(_make_line(key, val) for key, val in kwargs.items())
|
|
||||||
for arg in args:
|
|
||||||
super(Reader, self).add_match(arg)
|
|
||||||
|
|
||||||
def get_next(self, skip=1):
|
|
||||||
"""Return the next log entry as a mapping type, currently
|
|
||||||
a standard dictionary of fields.
|
|
||||||
|
|
||||||
Optional skip value will return the `skip`\-th log entry.
|
|
||||||
|
|
||||||
Entries will be processed with converters specified during
|
|
||||||
Reader creation.
|
|
||||||
"""
|
|
||||||
if super(Reader, self)._next(skip):
|
|
||||||
entry = super(Reader, self)._get_all()
|
|
||||||
if entry:
|
|
||||||
entry['__REALTIME_TIMESTAMP'] = self._get_realtime()
|
|
||||||
entry['__MONOTONIC_TIMESTAMP'] = self._get_monotonic()
|
|
||||||
entry['__CURSOR'] = self._get_cursor()
|
|
||||||
return self._convert_entry(entry)
|
|
||||||
return dict()
|
|
||||||
|
|
||||||
def get_previous(self, skip=1):
|
|
||||||
"""Return the previous log entry as a mapping type,
|
|
||||||
currently a standard dictionary of fields.
|
|
||||||
|
|
||||||
Optional skip value will return the -`skip`\-th log entry.
|
|
||||||
|
|
||||||
Entries will be processed with converters specified during
|
|
||||||
Reader creation.
|
|
||||||
|
|
||||||
Equivalent to get_next(-skip).
|
|
||||||
"""
|
|
||||||
return self.get_next(-skip)
|
|
||||||
|
|
||||||
def query_unique(self, field):
|
|
||||||
"""Return unique values appearing in the journal for given `field`.
|
|
||||||
|
|
||||||
Note this does not respect any journal matches.
|
|
||||||
|
|
||||||
Entries will be processed with converters specified during
|
|
||||||
Reader creation.
|
|
||||||
"""
|
|
||||||
return set(self._convert_field(field, value)
|
|
||||||
for value in super(Reader, self).query_unique(field))
|
|
||||||
|
|
||||||
def wait(self, timeout=None):
|
|
||||||
"""Wait for a change in the journal. `timeout` is the maximum
|
|
||||||
time in seconds to wait, or None, to wait forever.
|
|
||||||
|
|
||||||
Returns one of NOP (no change), APPEND (new entries have been
|
|
||||||
added to the end of the journal), or INVALIDATE (journal files
|
|
||||||
have been added or removed).
|
|
||||||
"""
|
|
||||||
us = -1 if timeout is None else int(timeout * 1000000)
|
|
||||||
return super(Reader, self).wait(us)
|
|
||||||
|
|
||||||
def seek_realtime(self, realtime):
|
|
||||||
"""Seek to a matching journal entry nearest to `realtime` time.
|
|
||||||
|
|
||||||
Argument `realtime` must be either an integer unix timestamp
|
|
||||||
or datetime.datetime instance.
|
|
||||||
"""
|
|
||||||
if isinstance(realtime, _datetime.datetime):
|
|
||||||
realtime = float(realtime.strftime("%s.%f")) * 1000000
|
|
||||||
return super(Reader, self).seek_realtime(int(realtime))
|
|
||||||
|
|
||||||
def seek_monotonic(self, monotonic, bootid=None):
|
|
||||||
"""Seek to a matching journal entry nearest to `monotonic` time.
|
|
||||||
|
|
||||||
Argument `monotonic` is a timestamp from boot in either
|
|
||||||
seconds or a datetime.timedelta instance. Argument `bootid`
|
|
||||||
is a string or UUID representing which boot the monotonic time
|
|
||||||
is reference to. Defaults to current bootid.
|
|
||||||
"""
|
|
||||||
if isinstance(monotonic, _datetime.timedelta):
|
|
||||||
monotonic = monotonic.totalseconds()
|
|
||||||
monotonic = int(monotonic * 1000000)
|
|
||||||
if isinstance(bootid, _uuid.UUID):
|
|
||||||
bootid = bootid.hex
|
|
||||||
return super(Reader, self).seek_monotonic(monotonic, bootid)
|
|
||||||
|
|
||||||
def log_level(self, level):
|
|
||||||
"""Set maximum log `level` by setting matches for PRIORITY.
|
|
||||||
"""
|
|
||||||
if 0 <= level <= 7:
|
|
||||||
for i in range(level+1):
|
|
||||||
self.add_match(PRIORITY="%d" % i)
|
|
||||||
else:
|
|
||||||
raise ValueError("Log level must be 0 <= level <= 7")
|
|
||||||
|
|
||||||
def messageid_match(self, messageid):
|
|
||||||
"""Add match for log entries with specified `messageid`.
|
|
||||||
|
|
||||||
`messageid` can be string of hexadicimal digits or a UUID
|
|
||||||
instance. Standard message IDs can be found in systemd.id128.
|
|
||||||
|
|
||||||
Equivalent to add_match(MESSAGE_ID=`messageid`).
|
|
||||||
"""
|
|
||||||
if isinstance(messageid, _uuid.UUID):
|
|
||||||
messageid = messageid.hex
|
|
||||||
self.add_match(MESSAGE_ID=messageid)
|
|
||||||
|
|
||||||
def this_boot(self, bootid=None):
|
|
||||||
"""Add match for _BOOT_ID equal to current boot ID or the specified boot ID.
|
|
||||||
|
|
||||||
If specified, bootid should be either a UUID or a 32 digit hex number.
|
|
||||||
|
|
||||||
Equivalent to add_match(_BOOT_ID='bootid').
|
|
||||||
"""
|
|
||||||
if bootid is None:
|
|
||||||
bootid = _id128.get_boot().hex
|
|
||||||
else:
|
|
||||||
bootid = getattr(bootid, 'hex', bootid)
|
|
||||||
self.add_match(_BOOT_ID=bootid)
|
|
||||||
|
|
||||||
def this_machine(self, machineid=None):
|
|
||||||
"""Add match for _MACHINE_ID equal to the ID of this machine.
|
|
||||||
|
|
||||||
If specified, machineid should be either a UUID or a 32 digit hex number.
|
|
||||||
|
|
||||||
Equivalent to add_match(_MACHINE_ID='machineid').
|
|
||||||
"""
|
|
||||||
if machineid is None:
|
|
||||||
machineid = _id128.get_machine().hex
|
|
||||||
else:
|
|
||||||
machineid = getattr(machineid, 'hex', machineid)
|
|
||||||
self.add_match(_MACHINE_ID=machineid)
|
|
||||||
|
|
||||||
|
|
||||||
def get_catalog(mid):
|
|
||||||
if isinstance(mid, _uuid.UUID):
|
|
||||||
mid = mid.hex
|
|
||||||
return _get_catalog(mid)
|
|
||||||
|
|
||||||
def _make_line(field, value):
|
|
||||||
if isinstance(value, bytes):
|
|
||||||
return field.encode('utf-8') + b'=' + value
|
|
||||||
elif isinstance(value, int):
|
|
||||||
return field + '=' + str(value)
|
|
||||||
else:
|
|
||||||
return field + '=' + value
|
|
||||||
|
|
||||||
def send(MESSAGE, MESSAGE_ID=None,
|
|
||||||
CODE_FILE=None, CODE_LINE=None, CODE_FUNC=None,
|
|
||||||
**kwargs):
|
|
||||||
r"""Send a message to the journal.
|
|
||||||
|
|
||||||
>>> journal.send('Hello world')
|
|
||||||
>>> journal.send('Hello, again, world', FIELD2='Greetings!')
|
|
||||||
>>> journal.send('Binary message', BINARY=b'\xde\xad\xbe\xef')
|
|
||||||
|
|
||||||
Value of the MESSAGE argument will be used for the MESSAGE=
|
|
||||||
field. MESSAGE must be a string and will be sent as UTF-8 to
|
|
||||||
the journal.
|
|
||||||
|
|
||||||
MESSAGE_ID can be given to uniquely identify the type of
|
|
||||||
message. It must be a string or a uuid.UUID object.
|
|
||||||
|
|
||||||
CODE_LINE, CODE_FILE, and CODE_FUNC can be specified to
|
|
||||||
identify the caller. Unless at least on of the three is given,
|
|
||||||
values are extracted from the stack frame of the caller of
|
|
||||||
send(). CODE_FILE and CODE_FUNC must be strings, CODE_LINE
|
|
||||||
must be an integer.
|
|
||||||
|
|
||||||
Additional fields for the journal entry can only be specified
|
|
||||||
as keyword arguments. The payload can be either a string or
|
|
||||||
bytes. A string will be sent as UTF-8, and bytes will be sent
|
|
||||||
as-is to the journal.
|
|
||||||
|
|
||||||
Other useful fields include PRIORITY, SYSLOG_FACILITY,
|
|
||||||
SYSLOG_IDENTIFIER, SYSLOG_PID.
|
|
||||||
"""
|
|
||||||
|
|
||||||
args = ['MESSAGE=' + MESSAGE]
|
|
||||||
|
|
||||||
if MESSAGE_ID is not None:
|
|
||||||
id = getattr(MESSAGE_ID, 'hex', MESSAGE_ID)
|
|
||||||
args.append('MESSAGE_ID=' + id)
|
|
||||||
|
|
||||||
if CODE_LINE == CODE_FILE == CODE_FUNC == None:
|
|
||||||
CODE_FILE, CODE_LINE, CODE_FUNC = \
|
|
||||||
_traceback.extract_stack(limit=2)[0][:3]
|
|
||||||
if CODE_FILE is not None:
|
|
||||||
args.append('CODE_FILE=' + CODE_FILE)
|
|
||||||
if CODE_LINE is not None:
|
|
||||||
args.append('CODE_LINE={:d}'.format(CODE_LINE))
|
|
||||||
if CODE_FUNC is not None:
|
|
||||||
args.append('CODE_FUNC=' + CODE_FUNC)
|
|
||||||
|
|
||||||
args.extend(_make_line(key, val) for key, val in kwargs.items())
|
|
||||||
return sendv(*args)
|
|
||||||
|
|
||||||
def stream(identifier, priority=LOG_DEBUG, level_prefix=False):
|
|
||||||
r"""Return a file object wrapping a stream to journal.
|
|
||||||
|
|
||||||
Log messages written to this file as simple newline sepearted
|
|
||||||
text strings are written to the journal.
|
|
||||||
|
|
||||||
The file will be line buffered, so messages are actually sent
|
|
||||||
after a newline character is written.
|
|
||||||
|
|
||||||
>>> stream = journal.stream('myapp')
|
|
||||||
>>> stream
|
|
||||||
<open file '<fdopen>', mode 'w' at 0x...>
|
|
||||||
>>> stream.write('message...\n')
|
|
||||||
|
|
||||||
will produce the following message in the journal::
|
|
||||||
|
|
||||||
PRIORITY=7
|
|
||||||
SYSLOG_IDENTIFIER=myapp
|
|
||||||
MESSAGE=message...
|
|
||||||
|
|
||||||
Using the interface with print might be more convinient:
|
|
||||||
|
|
||||||
>>> from __future__ import print_function
|
|
||||||
>>> print('message...', file=stream)
|
|
||||||
|
|
||||||
priority is the syslog priority, one of `LOG_EMERG`,
|
|
||||||
`LOG_ALERT`, `LOG_CRIT`, `LOG_ERR`, `LOG_WARNING`,
|
|
||||||
`LOG_NOTICE`, `LOG_INFO`, `LOG_DEBUG`.
|
|
||||||
|
|
||||||
level_prefix is a boolean. If true, kernel-style log priority
|
|
||||||
level prefixes (such as '<1>') are interpreted. See
|
|
||||||
sd-daemon(3) for more information.
|
|
||||||
"""
|
|
||||||
|
|
||||||
fd = stream_fd(identifier, priority, level_prefix)
|
|
||||||
return _os.fdopen(fd, 'w', 1)
|
|
||||||
|
|
||||||
class JournalHandler(_logging.Handler):
|
|
||||||
"""Journal handler class for the Python logging framework.
|
|
||||||
|
|
||||||
Please see the Python logging module documentation for an
|
|
||||||
overview: http://docs.python.org/library/logging.html.
|
|
||||||
|
|
||||||
To create a custom logger whose messages go only to journal:
|
|
||||||
|
|
||||||
>>> log = logging.getLogger('custom_logger_name')
|
|
||||||
>>> log.propagate = False
|
|
||||||
>>> log.addHandler(journal.JournalHandler())
|
|
||||||
>>> log.warn("Some message: %s", detail)
|
|
||||||
|
|
||||||
Note that by default, message levels `INFO` and `DEBUG` are
|
|
||||||
ignored by the logging framework. To enable those log levels:
|
|
||||||
|
|
||||||
>>> log.setLevel(logging.DEBUG)
|
|
||||||
|
|
||||||
To redirect all logging messages to journal regardless of where
|
|
||||||
they come from, attach it to the root logger:
|
|
||||||
|
|
||||||
>>> logging.root.addHandler(journal.JournalHandler())
|
|
||||||
|
|
||||||
For more complex configurations when using `dictConfig` or
|
|
||||||
`fileConfig`, specify `systemd.journal.JournalHandler` as the
|
|
||||||
handler class. Only standard handler configuration options
|
|
||||||
are supported: `level`, `formatter`, `filters`.
|
|
||||||
|
|
||||||
To attach journal MESSAGE_ID, an extra field is supported:
|
|
||||||
|
|
||||||
>>> import uuid
|
|
||||||
>>> mid = uuid.UUID('0123456789ABCDEF0123456789ABCDEF')
|
|
||||||
>>> log.warn("Message with ID", extra={'MESSAGE_ID': mid})
|
|
||||||
|
|
||||||
Fields to be attached to all messages sent through this
|
|
||||||
handler can be specified as keyword arguments. This probably
|
|
||||||
makes sense only for SYSLOG_IDENTIFIER and similar fields
|
|
||||||
which are constant for the whole program:
|
|
||||||
|
|
||||||
>>> journal.JournalHandler(SYSLOG_IDENTIFIER='my-cool-app')
|
|
||||||
|
|
||||||
The following journal fields will be sent:
|
|
||||||
`MESSAGE`, `PRIORITY`, `THREAD_NAME`, `CODE_FILE`, `CODE_LINE`,
|
|
||||||
`CODE_FUNC`, `LOGGER` (name as supplied to getLogger call),
|
|
||||||
`MESSAGE_ID` (optional, see above), `SYSLOG_IDENTIFIER` (defaults
|
|
||||||
to sys.argv[0]).
|
|
||||||
"""
|
|
||||||
|
|
||||||
def __init__(self, level=_logging.NOTSET, **kwargs):
|
|
||||||
super(JournalHandler, self).__init__(level)
|
|
||||||
|
|
||||||
for name in kwargs:
|
|
||||||
if not _valid_field_name(name):
|
|
||||||
raise ValueError('Invalid field name: ' + name)
|
|
||||||
if 'SYSLOG_IDENTIFIER' not in kwargs:
|
|
||||||
kwargs['SYSLOG_IDENTIFIER'] = _sys.argv[0]
|
|
||||||
self._extra = kwargs
|
|
||||||
|
|
||||||
def emit(self, record):
|
|
||||||
"""Write record as journal event.
|
|
||||||
|
|
||||||
MESSAGE is taken from the message provided by the
|
|
||||||
user, and PRIORITY, LOGGER, THREAD_NAME,
|
|
||||||
CODE_{FILE,LINE,FUNC} fields are appended
|
|
||||||
automatically. In addition, record.MESSAGE_ID will be
|
|
||||||
used if present.
|
|
||||||
"""
|
|
||||||
try:
|
|
||||||
msg = self.format(record)
|
|
||||||
pri = self.mapPriority(record.levelno)
|
|
||||||
mid = getattr(record, 'MESSAGE_ID', None)
|
|
||||||
send(msg,
|
|
||||||
MESSAGE_ID=mid,
|
|
||||||
PRIORITY=format(pri),
|
|
||||||
LOGGER=record.name,
|
|
||||||
THREAD_NAME=record.threadName,
|
|
||||||
CODE_FILE=record.pathname,
|
|
||||||
CODE_LINE=record.lineno,
|
|
||||||
CODE_FUNC=record.funcName,
|
|
||||||
**self._extra)
|
|
||||||
except Exception:
|
|
||||||
self.handleError(record)
|
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def mapPriority(levelno):
|
|
||||||
"""Map logging levels to journald priorities.
|
|
||||||
|
|
||||||
Since Python log level numbers are "sparse", we have
|
|
||||||
to map numbers in between the standard levels too.
|
|
||||||
"""
|
|
||||||
if levelno <= _logging.DEBUG:
|
|
||||||
return LOG_DEBUG
|
|
||||||
elif levelno <= _logging.INFO:
|
|
||||||
return LOG_INFO
|
|
||||||
elif levelno <= _logging.WARNING:
|
|
||||||
return LOG_WARNING
|
|
||||||
elif levelno <= _logging.ERROR:
|
|
||||||
return LOG_ERR
|
|
||||||
elif levelno <= _logging.CRITICAL:
|
|
||||||
return LOG_CRIT
|
|
||||||
else:
|
|
||||||
return LOG_ALERT
|
|
@ -1,376 +0,0 @@
|
|||||||
/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
|
|
||||||
|
|
||||||
/***
|
|
||||||
This file is part of systemd.
|
|
||||||
|
|
||||||
Copyright 2013 Zbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
|
|
||||||
|
|
||||||
systemd is free software; you can redistribute it and/or modify it
|
|
||||||
under the terms of the GNU Lesser General Public License as published by
|
|
||||||
the Free Software Foundation; either version 2.1 of the License, or
|
|
||||||
(at your option) any later version.
|
|
||||||
|
|
||||||
systemd is distributed in the hope that it will be useful, but
|
|
||||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
Lesser General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU Lesser General Public License
|
|
||||||
along with systemd; If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
***/
|
|
||||||
|
|
||||||
#define PY_SSIZE_T_CLEAN
|
|
||||||
#pragma GCC diagnostic push
|
|
||||||
#pragma GCC diagnostic ignored "-Wredundant-decls"
|
|
||||||
#include <Python.h>
|
|
||||||
#pragma GCC diagnostic pop
|
|
||||||
|
|
||||||
#include "systemd/sd-login.h"
|
|
||||||
#include "pyutil.h"
|
|
||||||
#include "util.h"
|
|
||||||
#include "strv.h"
|
|
||||||
|
|
||||||
PyDoc_STRVAR(module__doc__,
|
|
||||||
"Python interface to the libsystemd-login library."
|
|
||||||
);
|
|
||||||
|
|
||||||
#define helper(name) \
|
|
||||||
static PyObject* name(PyObject *self, PyObject *args) { \
|
|
||||||
_cleanup_strv_free_ char **list = NULL; \
|
|
||||||
int r; \
|
|
||||||
PyObject *ans; \
|
|
||||||
\
|
|
||||||
assert(args == NULL); \
|
|
||||||
\
|
|
||||||
r = sd_get_##name(&list); \
|
|
||||||
if (r < 0) { \
|
|
||||||
errno = -r; \
|
|
||||||
return PyErr_SetFromErrno(PyExc_IOError); \
|
|
||||||
} \
|
|
||||||
\
|
|
||||||
ans = PyList_New(r); \
|
|
||||||
if (!ans) \
|
|
||||||
return NULL; \
|
|
||||||
\
|
|
||||||
for (r--; r >= 0; r--) { \
|
|
||||||
PyObject *s = unicode_FromString(list[r]); \
|
|
||||||
if (!s) { \
|
|
||||||
Py_DECREF(ans); \
|
|
||||||
return NULL; \
|
|
||||||
} \
|
|
||||||
\
|
|
||||||
PyList_SetItem(ans, r, s); \
|
|
||||||
} \
|
|
||||||
\
|
|
||||||
return ans; \
|
|
||||||
}
|
|
||||||
|
|
||||||
helper(seats)
|
|
||||||
helper(sessions)
|
|
||||||
helper(machine_names)
|
|
||||||
#undef helper
|
|
||||||
|
|
||||||
static PyObject* uids(PyObject *self, PyObject *args) {
|
|
||||||
_cleanup_free_ uid_t *list = NULL;
|
|
||||||
int r;
|
|
||||||
PyObject *ans;
|
|
||||||
|
|
||||||
assert(args == NULL);
|
|
||||||
|
|
||||||
r = sd_get_uids(&list);
|
|
||||||
if (r < 0) {
|
|
||||||
errno = -r;
|
|
||||||
return PyErr_SetFromErrno(PyExc_IOError);
|
|
||||||
}
|
|
||||||
|
|
||||||
ans = PyList_New(r);
|
|
||||||
if (!ans)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
for (r--; r >= 0; r--) {
|
|
||||||
PyObject *s = long_FromLong(list[r]);
|
|
||||||
if (!s) {
|
|
||||||
Py_DECREF(ans);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
PyList_SetItem(ans, r, s);
|
|
||||||
}
|
|
||||||
|
|
||||||
return ans;
|
|
||||||
}
|
|
||||||
|
|
||||||
PyDoc_STRVAR(seats__doc__,
|
|
||||||
"seats() -> list\n\n"
|
|
||||||
"Returns a list of currently available local seats.\n"
|
|
||||||
"Wraps sd_get_seats(3)."
|
|
||||||
);
|
|
||||||
|
|
||||||
PyDoc_STRVAR(sessions__doc__,
|
|
||||||
"sessions() -> list\n\n"
|
|
||||||
"Returns a list of current login sessions.\n"
|
|
||||||
"Wraps sd_get_sessions(3)."
|
|
||||||
);
|
|
||||||
|
|
||||||
PyDoc_STRVAR(machine_names__doc__,
|
|
||||||
"machine_names() -> list\n\n"
|
|
||||||
"Returns a list of currently running virtual machines\n"
|
|
||||||
"and containers on the system.\n"
|
|
||||||
"Wraps sd_get_machine_names(3)."
|
|
||||||
);
|
|
||||||
|
|
||||||
PyDoc_STRVAR(uids__doc__,
|
|
||||||
"uids() -> list\n\n"
|
|
||||||
"Returns a list of uids of users who currently have login sessions.\n"
|
|
||||||
"Wraps sd_get_uids(3)."
|
|
||||||
);
|
|
||||||
|
|
||||||
static PyMethodDef methods[] = {
|
|
||||||
{ "seats", seats, METH_NOARGS, seats__doc__},
|
|
||||||
{ "sessions", sessions, METH_NOARGS, sessions__doc__},
|
|
||||||
{ "machine_names", machine_names, METH_NOARGS, machine_names__doc__},
|
|
||||||
{ "uids", uids, METH_NOARGS, uids__doc__},
|
|
||||||
{} /* Sentinel */
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
PyObject_HEAD
|
|
||||||
sd_login_monitor *monitor;
|
|
||||||
} Monitor;
|
|
||||||
static PyTypeObject MonitorType;
|
|
||||||
|
|
||||||
static void Monitor_dealloc(Monitor* self) {
|
|
||||||
sd_login_monitor_unref(self->monitor);
|
|
||||||
Py_TYPE(self)->tp_free((PyObject*)self);
|
|
||||||
}
|
|
||||||
|
|
||||||
PyDoc_STRVAR(Monitor__doc__,
|
|
||||||
"Monitor([category]) -> ...\n\n"
|
|
||||||
"Monitor may be used to monitor login sessions, users, seats,\n"
|
|
||||||
"and virtual machines/containers. Monitor provides a file\n"
|
|
||||||
"descriptor which can be integrated in an external event loop.\n"
|
|
||||||
"See man:sd_login_monitor_new(3) for the details about what\n"
|
|
||||||
"can be monitored.");
|
|
||||||
static int Monitor_init(Monitor *self, PyObject *args, PyObject *keywds) {
|
|
||||||
const char *category = NULL;
|
|
||||||
int r;
|
|
||||||
|
|
||||||
static const char* const kwlist[] = {"category", NULL};
|
|
||||||
if (!PyArg_ParseTupleAndKeywords(args, keywds, "|z:__init__", (char**) kwlist,
|
|
||||||
&category))
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
Py_BEGIN_ALLOW_THREADS
|
|
||||||
r = sd_login_monitor_new(category, &self->monitor);
|
|
||||||
Py_END_ALLOW_THREADS
|
|
||||||
|
|
||||||
return set_error(r, NULL, "Invalid category");
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
PyDoc_STRVAR(Monitor_fileno__doc__,
|
|
||||||
"fileno() -> int\n\n"
|
|
||||||
"Get a file descriptor to poll for events.\n"
|
|
||||||
"This method wraps sd_login_monitor_get_fd(3).");
|
|
||||||
static PyObject* Monitor_fileno(Monitor *self, PyObject *args) {
|
|
||||||
int fd = sd_login_monitor_get_fd(self->monitor);
|
|
||||||
set_error(fd, NULL, NULL);
|
|
||||||
if (fd < 0)
|
|
||||||
return NULL;
|
|
||||||
return long_FromLong(fd);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
PyDoc_STRVAR(Monitor_get_events__doc__,
|
|
||||||
"get_events() -> int\n\n"
|
|
||||||
"Returns a mask of poll() events to wait for on the file\n"
|
|
||||||
"descriptor returned by .fileno().\n\n"
|
|
||||||
"See man:sd_login_monitor_get_events(3) for further discussion.");
|
|
||||||
static PyObject* Monitor_get_events(Monitor *self, PyObject *args) {
|
|
||||||
int r = sd_login_monitor_get_events(self->monitor);
|
|
||||||
set_error(r, NULL, NULL);
|
|
||||||
if (r < 0)
|
|
||||||
return NULL;
|
|
||||||
return long_FromLong(r);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
PyDoc_STRVAR(Monitor_get_timeout__doc__,
|
|
||||||
"get_timeout() -> int or None\n\n"
|
|
||||||
"Returns a timeout value for usage in poll(), the time since the\n"
|
|
||||||
"epoch of clock_gettime(2) in microseconds, or None if no timeout\n"
|
|
||||||
"is necessary.\n\n"
|
|
||||||
"The return value must be converted to a relative timeout in\n"
|
|
||||||
"milliseconds if it is to be used as an argument for poll().\n"
|
|
||||||
"See man:sd_login_monitor_get_timeout(3) for further discussion.");
|
|
||||||
static PyObject* Monitor_get_timeout(Monitor *self, PyObject *args) {
|
|
||||||
int r;
|
|
||||||
uint64_t t;
|
|
||||||
|
|
||||||
r = sd_login_monitor_get_timeout(self->monitor, &t);
|
|
||||||
set_error(r, NULL, NULL);
|
|
||||||
if (r < 0)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
if (t == (uint64_t) -1)
|
|
||||||
Py_RETURN_NONE;
|
|
||||||
|
|
||||||
assert_cc(sizeof(unsigned long long) == sizeof(t));
|
|
||||||
return PyLong_FromUnsignedLongLong(t);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
PyDoc_STRVAR(Monitor_get_timeout_ms__doc__,
|
|
||||||
"get_timeout_ms() -> int\n\n"
|
|
||||||
"Returns a timeout value suitable for usage in poll(), the value\n"
|
|
||||||
"returned by .get_timeout() converted to relative ms, or -1 if\n"
|
|
||||||
"no timeout is necessary.");
|
|
||||||
static PyObject* Monitor_get_timeout_ms(Monitor *self, PyObject *args) {
|
|
||||||
int r;
|
|
||||||
uint64_t t;
|
|
||||||
|
|
||||||
r = sd_login_monitor_get_timeout(self->monitor, &t);
|
|
||||||
set_error(r, NULL, NULL);
|
|
||||||
if (r < 0)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
return absolute_timeout(t);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
PyDoc_STRVAR(Monitor_close__doc__,
|
|
||||||
"close() -> None\n\n"
|
|
||||||
"Free resources allocated by this Monitor object.\n"
|
|
||||||
"This method invokes sd_login_monitor_unref().\n"
|
|
||||||
"See man:sd_login_monitor_unref(3).");
|
|
||||||
static PyObject* Monitor_close(Monitor *self, PyObject *args) {
|
|
||||||
assert(self);
|
|
||||||
assert(!args);
|
|
||||||
|
|
||||||
sd_login_monitor_unref(self->monitor);
|
|
||||||
self->monitor = NULL;
|
|
||||||
Py_RETURN_NONE;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
PyDoc_STRVAR(Monitor_flush__doc__,
|
|
||||||
"flush() -> None\n\n"
|
|
||||||
"Reset the wakeup state of the monitor object.\n"
|
|
||||||
"This method invokes sd_login_monitor_flush().\n"
|
|
||||||
"See man:sd_login_monitor_flush(3).");
|
|
||||||
static PyObject* Monitor_flush(Monitor *self, PyObject *args) {
|
|
||||||
assert(self);
|
|
||||||
assert(!args);
|
|
||||||
|
|
||||||
Py_BEGIN_ALLOW_THREADS
|
|
||||||
sd_login_monitor_flush(self->monitor);
|
|
||||||
Py_END_ALLOW_THREADS
|
|
||||||
Py_RETURN_NONE;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
PyDoc_STRVAR(Monitor___enter____doc__,
|
|
||||||
"__enter__() -> self\n\n"
|
|
||||||
"Part of the context manager protocol.\n"
|
|
||||||
"Returns self.\n");
|
|
||||||
static PyObject* Monitor___enter__(PyObject *self, PyObject *args) {
|
|
||||||
assert(self);
|
|
||||||
assert(!args);
|
|
||||||
|
|
||||||
Py_INCREF(self);
|
|
||||||
return self;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
PyDoc_STRVAR(Monitor___exit____doc__,
|
|
||||||
"__exit__(type, value, traceback) -> None\n\n"
|
|
||||||
"Part of the context manager protocol.\n"
|
|
||||||
"Closes the monitor..\n");
|
|
||||||
static PyObject* Monitor___exit__(Monitor *self, PyObject *args) {
|
|
||||||
return Monitor_close(self, args);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static PyMethodDef Monitor_methods[] = {
|
|
||||||
{"fileno", (PyCFunction) Monitor_fileno, METH_NOARGS, Monitor_fileno__doc__},
|
|
||||||
{"get_events", (PyCFunction) Monitor_get_events, METH_NOARGS, Monitor_get_events__doc__},
|
|
||||||
{"get_timeout", (PyCFunction) Monitor_get_timeout, METH_NOARGS, Monitor_get_timeout__doc__},
|
|
||||||
{"get_timeout_ms", (PyCFunction) Monitor_get_timeout_ms, METH_NOARGS, Monitor_get_timeout_ms__doc__},
|
|
||||||
{"close", (PyCFunction) Monitor_close, METH_NOARGS, Monitor_close__doc__},
|
|
||||||
{"flush", (PyCFunction) Monitor_flush, METH_NOARGS, Monitor_flush__doc__},
|
|
||||||
{"__enter__", (PyCFunction) Monitor___enter__, METH_NOARGS, Monitor___enter____doc__},
|
|
||||||
{"__exit__", (PyCFunction) Monitor___exit__, METH_VARARGS, Monitor___exit____doc__},
|
|
||||||
{} /* Sentinel */
|
|
||||||
};
|
|
||||||
|
|
||||||
static PyTypeObject MonitorType = {
|
|
||||||
PyVarObject_HEAD_INIT(NULL, 0)
|
|
||||||
.tp_name = "login.Monitor",
|
|
||||||
.tp_basicsize = sizeof(Monitor),
|
|
||||||
.tp_dealloc = (destructor) Monitor_dealloc,
|
|
||||||
.tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
|
|
||||||
.tp_doc = Monitor__doc__,
|
|
||||||
.tp_methods = Monitor_methods,
|
|
||||||
.tp_init = (initproc) Monitor_init,
|
|
||||||
.tp_new = PyType_GenericNew,
|
|
||||||
};
|
|
||||||
|
|
||||||
#if PY_MAJOR_VERSION < 3
|
|
||||||
|
|
||||||
DISABLE_WARNING_MISSING_PROTOTYPES;
|
|
||||||
PyMODINIT_FUNC initlogin(void) {
|
|
||||||
PyObject *m;
|
|
||||||
|
|
||||||
if (PyType_Ready(&MonitorType) < 0)
|
|
||||||
return;
|
|
||||||
|
|
||||||
m = Py_InitModule3("login", methods, module__doc__);
|
|
||||||
if (m == NULL)
|
|
||||||
return;
|
|
||||||
|
|
||||||
PyModule_AddStringConstant(m, "__version__", PACKAGE_VERSION);
|
|
||||||
|
|
||||||
Py_INCREF(&MonitorType);
|
|
||||||
PyModule_AddObject(m, "Monitor", (PyObject *) &MonitorType);
|
|
||||||
}
|
|
||||||
REENABLE_WARNING;
|
|
||||||
|
|
||||||
#else
|
|
||||||
|
|
||||||
static struct PyModuleDef module = {
|
|
||||||
PyModuleDef_HEAD_INIT,
|
|
||||||
"login", /* name of module */
|
|
||||||
module__doc__, /* module documentation, may be NULL */
|
|
||||||
-1, /* size of per-interpreter state of the module */
|
|
||||||
methods
|
|
||||||
};
|
|
||||||
|
|
||||||
DISABLE_WARNING_MISSING_PROTOTYPES;
|
|
||||||
PyMODINIT_FUNC PyInit_login(void) {
|
|
||||||
PyObject *m;
|
|
||||||
|
|
||||||
if (PyType_Ready(&MonitorType) < 0)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
m = PyModule_Create(&module);
|
|
||||||
if (m == NULL)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
if (PyModule_AddStringConstant(m, "__version__", PACKAGE_VERSION)) {
|
|
||||||
Py_DECREF(m);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
Py_INCREF(&MonitorType);
|
|
||||||
if (PyModule_AddObject(m, "Monitor", (PyObject *) &MonitorType)) {
|
|
||||||
Py_DECREF(&MonitorType);
|
|
||||||
Py_DECREF(m);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
return m;
|
|
||||||
}
|
|
||||||
REENABLE_WARNING;
|
|
||||||
|
|
||||||
#endif
|
|
@ -1,80 +0,0 @@
|
|||||||
/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
|
|
||||||
|
|
||||||
/***
|
|
||||||
This file is part of systemd.
|
|
||||||
|
|
||||||
Copyright 2013 Zbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
|
|
||||||
|
|
||||||
systemd is free software; you can redistribute it and/or modify it
|
|
||||||
under the terms of the GNU Lesser General Public License as published by
|
|
||||||
the Free Software Foundation; either version 2.1 of the License, or
|
|
||||||
(at your option) any later version.
|
|
||||||
|
|
||||||
systemd is distributed in the hope that it will be useful, but
|
|
||||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
Lesser General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU Lesser General Public License
|
|
||||||
along with systemd; If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
***/
|
|
||||||
|
|
||||||
#include <Python.h>
|
|
||||||
#include "pyutil.h"
|
|
||||||
|
|
||||||
void cleanup_Py_DECREFp(PyObject **p) {
|
|
||||||
if (!*p)
|
|
||||||
return;
|
|
||||||
|
|
||||||
Py_DECREF(*p);
|
|
||||||
}
|
|
||||||
|
|
||||||
PyObject* absolute_timeout(uint64_t t) {
|
|
||||||
if (t == (uint64_t) -1)
|
|
||||||
return PyLong_FromLong(-1);
|
|
||||||
else {
|
|
||||||
struct timespec ts;
|
|
||||||
uint64_t n;
|
|
||||||
int msec;
|
|
||||||
|
|
||||||
clock_gettime(CLOCK_MONOTONIC, &ts);
|
|
||||||
n = (uint64_t) ts.tv_sec * 1000000 + ts.tv_nsec / 1000;
|
|
||||||
msec = t > n ? (int) ((t - n + 999) / 1000) : 0;
|
|
||||||
|
|
||||||
return PyLong_FromLong(msec);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int set_error(int r, const char* path, const char* invalid_message) {
|
|
||||||
if (r >= 0)
|
|
||||||
return r;
|
|
||||||
if (r == -EINVAL && invalid_message)
|
|
||||||
PyErr_SetString(PyExc_ValueError, invalid_message);
|
|
||||||
else if (r == -ENOMEM)
|
|
||||||
PyErr_SetString(PyExc_MemoryError, "Not enough memory");
|
|
||||||
else {
|
|
||||||
errno = -r;
|
|
||||||
PyErr_SetFromErrnoWithFilename(PyExc_OSError, path);
|
|
||||||
}
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
#if PY_MAJOR_VERSION >=3 && PY_MINOR_VERSION >= 1
|
|
||||||
int Unicode_FSConverter(PyObject* obj, void *_result) {
|
|
||||||
PyObject **result = _result;
|
|
||||||
|
|
||||||
assert(result);
|
|
||||||
|
|
||||||
if (!obj)
|
|
||||||
/* cleanup: we don't return Py_CLEANUP_SUPPORTED, so
|
|
||||||
* we can assume that it was PyUnicode_FSConverter. */
|
|
||||||
return PyUnicode_FSConverter(obj, result);
|
|
||||||
|
|
||||||
if (obj == Py_None) {
|
|
||||||
*result = NULL;
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return PyUnicode_FSConverter(obj, result);
|
|
||||||
}
|
|
||||||
#endif
|
|
@ -1,54 +0,0 @@
|
|||||||
/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
/***
|
|
||||||
This file is part of systemd.
|
|
||||||
|
|
||||||
Copyright 2013 Zbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
|
|
||||||
|
|
||||||
systemd is free software; you can redistribute it and/or modify it
|
|
||||||
under the terms of the GNU Lesser General Public License as published by
|
|
||||||
the Free Software Foundation; either version 2.1 of the License, or
|
|
||||||
(at your option) any later version.
|
|
||||||
|
|
||||||
systemd is distributed in the hope that it will be useful, but
|
|
||||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
Lesser General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU Lesser General Public License
|
|
||||||
along with systemd; If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
***/
|
|
||||||
|
|
||||||
#ifndef Py_TYPE
|
|
||||||
/* avoid duplication warnings from errors in Python 2.7 headers */
|
|
||||||
# include <Python.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
void cleanup_Py_DECREFp(PyObject **p);
|
|
||||||
PyObject* absolute_timeout(uint64_t t);
|
|
||||||
int set_error(int r, const char* path, const char* invalid_message);
|
|
||||||
|
|
||||||
#if PY_MAJOR_VERSION >=3 && PY_MINOR_VERSION >= 1
|
|
||||||
int Unicode_FSConverter(PyObject* obj, void *_result);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define _cleanup_Py_DECREF_ __attribute__((cleanup(cleanup_Py_DECREFp)))
|
|
||||||
|
|
||||||
#if PY_MAJOR_VERSION >=3
|
|
||||||
# define unicode_FromStringAndSize PyUnicode_FromStringAndSize
|
|
||||||
# define unicode_FromString PyUnicode_FromString
|
|
||||||
# define long_FromLong PyLong_FromLong
|
|
||||||
# define long_FromSize_t PyLong_FromSize_t
|
|
||||||
# define long_Check PyLong_Check
|
|
||||||
# define long_AsLong PyLong_AsLong
|
|
||||||
#else
|
|
||||||
/* Python 3 type naming convention is used */
|
|
||||||
# define unicode_FromStringAndSize PyString_FromStringAndSize
|
|
||||||
# define unicode_FromString PyString_FromString
|
|
||||||
# define long_FromLong PyInt_FromLong
|
|
||||||
# define long_FromSize_t PyInt_FromSize_t
|
|
||||||
# define long_Check PyInt_Check
|
|
||||||
# define long_AsLong PyInt_AsLong
|
|
||||||
#endif
|
|
Loading…
Reference in New Issue
Block a user