Skip to content

Commit 6baa4b4

Browse files
committed
daemon: wrap sd_pid_notify[_with_pids]
Closes #8.
1 parent 035700c commit 6baa4b4

File tree

2 files changed

+79
-10
lines changed

2 files changed

+79
-10
lines changed

systemd/_daemon.c

Lines changed: 78 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,13 @@
3232
#include "pyutil.h"
3333
#include "macro.h"
3434

35+
#if LIBSYSTEMD_VERSION >= 214
36+
# define HAVE_PID_NOTIFY
37+
# if LIBSYSTEMD_VERSION >= 219
38+
# define HAVE_PID_NOTIFY_WITH_FDS
39+
# endif
40+
#endif
41+
3542
PyDoc_STRVAR(module__doc__,
3643
"Python interface to the libsystemd-daemon library.\n\n"
3744
"Provides _listen_fds, notify, booted, and is_* functions\n"
@@ -57,37 +64,99 @@ static PyObject* booted(PyObject *self, PyObject *args) {
5764
return PyBool_FromLong(r);
5865
}
5966

67+
static inline void PyMem_Free_intp(int **p) {
68+
PyMem_Free(*p);
69+
}
70+
6071
PyDoc_STRVAR(notify__doc__,
61-
"notify(status, unset_environment=False) -> bool\n\n"
72+
"notify(status, unset_environment=False, pid=0, fds=None) -> bool\n\n"
6273
"Send a message to the init system about a status change.\n"
6374
"Wraps sd_notify(3).");
6475

6576
static PyObject* notify(PyObject *self, PyObject *args, PyObject *keywds) {
6677
int r;
6778
const char* msg;
68-
int unset = false;
79+
int unset = false, n_fds;
80+
int _pid = 0;
81+
pid_t pid;
82+
PyObject *fds = NULL;
83+
_cleanup_(PyMem_Free_intp) int *arr = NULL;
6984

7085
static const char* const kwlist[] = {
7186
"status",
7287
"unset_environment",
88+
"pid",
89+
"fds",
7390
NULL,
7491
};
7592
#if PY_MAJOR_VERSION >=3 && PY_MINOR_VERSION >= 3
76-
if (!PyArg_ParseTupleAndKeywords(args, keywds, "s|p:notify",
77-
(char**) kwlist, &msg, &unset))
93+
if (!PyArg_ParseTupleAndKeywords(args, keywds, "s|piO:notify",
94+
(char**) kwlist, &msg, &unset, &_pid, &fds))
7895
return NULL;
7996
#else
8097
PyObject *obj = NULL;
81-
if (!PyArg_ParseTupleAndKeywords(args, keywds, "s|O:notify",
82-
(char**) kwlist, &msg, &obj))
98+
if (!PyArg_ParseTupleAndKeywords(args, keywds, "s|OiO:notify",
99+
(char**) kwlist, &msg, &obj, &_pid, &fds))
83100
return NULL;
84101
if (obj != NULL)
85102
unset = PyObject_IsTrue(obj);
86103
if (unset < 0)
87104
return NULL;
88105
#endif
106+
pid = _pid;
107+
if (pid < 0 || pid != _pid) {
108+
PyErr_SetString(PyExc_OverflowError, "Bad pid_t");
109+
return NULL;
110+
}
111+
112+
if (fds != NULL) {
113+
Py_ssize_t i, len;
114+
115+
len = PySequence_Length(fds);
116+
if (len < 0)
117+
return NULL;
118+
119+
arr = PyMem_NEW(int, len);
120+
if (!fds)
121+
return NULL;
122+
123+
for (i = 0; i < len; i++) {
124+
PyObject *item = PySequence_GetItem(fds, i);
125+
if (!item)
126+
return NULL;
127+
128+
long value = PyLong_AsLong(item);
129+
if (PyErr_Occurred())
130+
return NULL;
131+
132+
arr[i] = value;
133+
if (arr[i] != value) {
134+
PyErr_SetString(PyExc_OverflowError, "Value to large for an integer");
135+
return NULL;
136+
}
137+
}
138+
139+
n_fds = len;
140+
}
141+
142+
if (pid == 0 && fds == NULL)
143+
r = sd_notify(unset, msg);
144+
else if (fds == NULL) {
145+
#ifdef HAVE_PID_NOTIFY
146+
r = sd_pid_notify(pid, unset, msg);
147+
#else
148+
PyErr_SetString(PyExc_NotImplementedError, "Compiled without support for sd_pid_notify");
149+
return NULL;
150+
#endif
151+
} else {
152+
#ifdef HAVE_PID_NOTIFY_WITH_FDS
153+
r = sd_pid_notify_with_fds(pid, unset, msg, arr, n_fds);
154+
#else
155+
PyErr_SetString(PyExc_NotImplementedError, "Compiled without support for sd_pid_notify_with_fds");
156+
return NULL;
157+
#endif
158+
}
89159

90-
r = sd_notify(unset, msg);
91160
if (set_error(r, NULL, NULL) < 0)
92161
return NULL;
93162

@@ -177,8 +246,8 @@ static PyObject* is_mq(PyObject *self, PyObject *args) {
177246
if (!PyArg_ParseTuple(args, "i|O&:_is_mq",
178247
&fd, Unicode_FSConverter, &_path))
179248
return NULL;
180-
if (_path)
181-
path = PyBytes_AsString(_path);
249+
if (_path)
250+
path = PyBytes_AsString(_path);
182251
#else
183252
if (!PyArg_ParseTuple(args, "i|z:_is_mq", &fd, &path))
184253
return NULL;

systemd/pyutil.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ int set_error(int r, const char* path, const char* invalid_message);
3333
int Unicode_FSConverter(PyObject* obj, void *_result);
3434
#endif
3535

36-
#define _cleanup_Py_DECREF_ __attribute__((cleanup(cleanup_Py_DECREFp)))
36+
#define _cleanup_Py_DECREF_ _cleanup_(cleanup_Py_DECREFp)
3737

3838
#if PY_MAJOR_VERSION >=3
3939
# define unicode_FromStringAndSize PyUnicode_FromStringAndSize

0 commit comments

Comments
 (0)