Skip to content

Commit 89badf5

Browse files
committed
journal: add support for sd_journal_open_files_fd
1 parent ee9ab0b commit 89badf5

File tree

1 file changed

+81
-15
lines changed

1 file changed

+81
-15
lines changed

systemd/_reader.c

Lines changed: 81 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,57 @@ static int strv_converter(PyObject* obj, void *_result) {
161161
return 0;
162162
}
163163

164+
static int long_as_fd(PyObject *obj, int *fd) {
165+
long num = long_AsLong(obj);
166+
if (PyErr_Occurred())
167+
return -1;
168+
169+
if ((int) num != num) {
170+
PyErr_SetString(PyExc_OverflowError, "Value too large");
171+
return -1;
172+
}
173+
174+
*fd = (int) num;
175+
return 0;
176+
}
177+
178+
/**
179+
* Convert a Python sequence object into an int array.
180+
*/
181+
static int intlist_converter(PyObject* obj, int **_result, size_t *_len) {
182+
_cleanup_free_ int *result = NULL;
183+
Py_ssize_t i, len;
184+
185+
assert(_result);
186+
assert(_len);
187+
188+
if (!PySequence_Check(obj))
189+
return 0;
190+
191+
len = PySequence_Length(obj);
192+
result = new0(int, len);
193+
if (!result) {
194+
set_error(-ENOMEM, NULL, NULL);
195+
return 0;
196+
}
197+
198+
for (i = 0; i < len; i++) {
199+
PyObject *item;
200+
int fd;
201+
202+
item = PySequence_ITEM(obj, i);
203+
if (long_as_fd(item, &fd) < 0)
204+
return 0;
205+
206+
result[i] = fd;
207+
}
208+
209+
*_result = result;
210+
*_len = len;
211+
result = NULL;
212+
return 1;
213+
}
214+
164215
static void Reader_dealloc(Reader* self) {
165216
sd_journal_close(self->j);
166217
Py_TYPE(self)->tp_free((PyObject*)self);
@@ -185,36 +236,31 @@ PyDoc_STRVAR(Reader__doc__,
185236
"exiting the block.");
186237
static int Reader_init(Reader *self, PyObject *args, PyObject *keywds) {
187238
int flags = 0, r;
188-
PyObject *_path = NULL;
189-
_cleanup_strv_free_ char **files = NULL;
239+
PyObject *_path = NULL, *_files = NULL;
190240

191241
static const char* const kwlist[] = {"flags", "path", "files", NULL};
192242
if (!PyArg_ParseTupleAndKeywords(args, keywds, "|iO&O&:__init__", (char**) kwlist,
193243
&flags,
194244
null_converter, &_path,
195-
strv_converter, &files))
245+
null_converter, &_files))
196246
return -1;
197247

198-
if (!!flags + !!_path + !!files > 1) {
248+
if (!!flags + !!_path + !!_files > 1) {
199249
PyErr_SetString(PyExc_ValueError,
200250
"cannot use more than one of flags, path, and files");
201251
return -1;
202252
}
203253

204254
if (_path) {
205255
if (long_Check(_path)) {
206-
long directory_fd = long_AsLong(_path);
207-
if (PyErr_Occurred())
208-
return -1;
256+
int fd;
209257

210-
if ((int) directory_fd != directory_fd) {
211-
PyErr_SetString(PyExc_OverflowError, "Value too large");
258+
if (long_as_fd(_path, &fd) < 0)
212259
return -1;
213-
}
214260

215261
#ifdef HAVE_JOURNAL_OPEN_DIRECTORY_FD
216262
Py_BEGIN_ALLOW_THREADS
217-
r = sd_journal_open_directory_fd(&self->j, (int) directory_fd, 0);
263+
r = sd_journal_open_directory_fd(&self->j, (int) fd, 0);
218264
Py_END_ALLOW_THREADS
219265
#else
220266
r = -ENOSYS;
@@ -231,11 +277,31 @@ static int Reader_init(Reader *self, PyObject *args, PyObject *keywds) {
231277
r = sd_journal_open_directory(&self->j, path, 0);
232278
Py_END_ALLOW_THREADS
233279
}
234-
} else if (files) {
280+
} else if (_files) {
235281
#ifdef HAVE_JOURNAL_OPEN_FILES
236-
Py_BEGIN_ALLOW_THREADS
237-
r = sd_journal_open_files(&self->j, (const char**) files, 0);
238-
Py_END_ALLOW_THREADS
282+
_cleanup_Py_DECREF_ PyObject *item0 = NULL;
283+
284+
item0 = PySequence_GetItem(_files, 0);
285+
if (item0 == NULL || !PyLong_Check(item0)) {
286+
_cleanup_strv_free_ char **files = NULL;
287+
288+
if (!strv_converter(_files, &files))
289+
return -1;
290+
291+
Py_BEGIN_ALLOW_THREADS
292+
r = sd_journal_open_files(&self->j, (const char**) files, 0);
293+
Py_END_ALLOW_THREADS
294+
} else {
295+
_cleanup_free_ int *fds = NULL;
296+
size_t n_fds;
297+
298+
if (!intlist_converter(_files, &fds, &n_fds))
299+
return -1;
300+
301+
Py_BEGIN_ALLOW_THREADS
302+
r = sd_journal_open_files_fd(&self->j, fds, n_fds, 0);
303+
Py_END_ALLOW_THREADS
304+
}
239305
#else
240306
r = -ENOSYS;
241307
#endif

0 commit comments

Comments
 (0)