diff options
Diffstat (limited to 'systemd/_daemon.c')
-rw-r--r-- | systemd/_daemon.c | 70 |
1 files changed, 63 insertions, 7 deletions
diff --git a/systemd/_daemon.c b/systemd/_daemon.c index a041b1b..90cf205 100644 --- a/systemd/_daemon.c +++ b/systemd/_daemon.c @@ -2,7 +2,7 @@ /*** - Copyright 2013 Zbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl> + Copyright 2013-2016 Zbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl> python-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 @@ -31,12 +31,18 @@ #include "systemd/sd-daemon.h" #include "pyutil.h" #include "macro.h" +#include "util.h" #if LIBSYSTEMD_VERSION >= 214 # define HAVE_PID_NOTIFY -# if LIBSYSTEMD_VERSION >= 219 -# define HAVE_PID_NOTIFY_WITH_FDS -# endif +#endif + +#if LIBSYSTEMD_VERSION >= 219 +# define HAVE_PID_NOTIFY_WITH_FDS +#endif + +#if LIBSYSTEMD_VERSION >= 233 +# define HAVE_IS_SOCKET_SOCKADDR #endif PyDoc_STRVAR(module__doc__, @@ -145,14 +151,14 @@ static PyObject* notify(PyObject *self, PyObject *args, PyObject *keywds) { #ifdef HAVE_PID_NOTIFY r = sd_pid_notify(pid, unset, msg); #else - PyErr_SetString(PyExc_NotImplementedError, "Compiled without support for sd_pid_notify"); + set_error(-ENOSYS, NULL, "Compiled without support for sd_pid_notify"); return NULL; #endif } else { #ifdef HAVE_PID_NOTIFY_WITH_FDS r = sd_pid_notify_with_fds(pid, unset, msg, arr, n_fds); #else - PyErr_SetString(PyExc_NotImplementedError, "Compiled without support for sd_pid_notify_with_fds"); + set_error(-ENOSYS, NULL, "Compiled without support for sd_pid_notify_with_fds"); return NULL; #endif } @@ -311,6 +317,53 @@ static PyObject* is_socket_inet(PyObject *self, PyObject *args) { return PyBool_FromLong(r); } +#ifdef HAVE_IS_SOCKET_SOCKADDR +PyDoc_STRVAR(is_socket_sockaddr__doc__, + "_is_socket_sockaddr(fd, address, type=0, flowinfo=0, listening=-1) -> bool\n\n" + "Wraps sd_is_socket_inet_sockaddr(3).\n" + "`address` is a systemd-style numerical IPv4 or IPv6 address as used in\n" + "ListenStream=. A port may be included after a colon (\":\"). See\n" + "systemd.socket(5) for details.\n\n" + "Constants for `family` are defined in the socket module." +); + +static PyObject* is_socket_sockaddr(PyObject *self, PyObject *args) { + int r; + int fd, type = 0, flowinfo = 0, listening = -1; + const char *address; + union sockaddr_union addr = {}; + unsigned addr_len; + + if (!PyArg_ParseTuple(args, "is|iii:_is_socket_sockaddr", + &fd, + &address, + &type, + &flowinfo, + &listening)) + return NULL; + + r = parse_sockaddr(address, &addr, &addr_len); + if (r < 0) { + set_error(r, NULL, "Cannot parse address"); + return NULL; + } + + if (flowinfo != 0) { + if (addr.sa.sa_family != AF_INET6) { + set_error(-EINVAL, NULL, "flowinfo is only applicable to IPv6 addresses"); + return NULL; + } + + addr.in6.sin6_flowinfo = flowinfo; + } + + r = sd_is_socket_sockaddr(fd, type, &addr.sa, addr_len, listening); + if (set_error(r, NULL, NULL) < 0) + return NULL; + + return PyBool_FromLong(r); +} +#endif PyDoc_STRVAR(is_socket_unix__doc__, "_is_socket_unix(fd, type, listening, path) -> bool\n\n" @@ -355,8 +408,11 @@ static PyMethodDef methods[] = { { "_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__}, +#ifdef HAVE_IS_SOCKET_SOCKADDR + { "_is_socket_sockaddr", is_socket_sockaddr, METH_VARARGS, is_socket_sockaddr__doc__}, +#endif { "_is_socket_unix", is_socket_unix, METH_VARARGS, is_socket_unix__doc__}, - { NULL, NULL, 0, NULL } /* Sentinel */ + {} /* Sentinel */ }; #if PY_MAJOR_VERSION < 3 |