/*-*- 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> #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 = alloca(argc * sizeof(PyObject*)); memset(encoded, 0, 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 */ }; #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wmissing-prototypes" #if PY_MAJOR_VERSION < 3 PyMODINIT_FUNC init_journal(void) { PyObject *m; m = Py_InitModule("_journal", methods); if (m == NULL) return; PyModule_AddStringConstant(m, "__version__", PACKAGE_VERSION); } #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 }; 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; } #endif #pragma GCC diagnostic pop