-PyDoc_STRVAR(Journal_add_match__doc__,
-"add_match(match, ..., field=value, ...) -> None\n\n"
-"Add a match to filter journal log entries. All matches of different\n"
-"field are combined in logical AND, and matches of the same field\n"
-"are automatically combined in logical OR.\n"
-"Matches can be passed as strings \"field=value\", or keyword\n"
-"arguments field=\"value\".");
-static PyObject *
-Journal_add_match(Journal *self, PyObject *args, PyObject *keywds)
-{
- Py_ssize_t arg_match_len;
- char *arg_match;
- int i, r;
- for (i = 0; i < PySequence_Size(args); i++) {
-#if PY_MAJOR_VERSION >=3
- PyObject *arg;
- arg = PySequence_Fast_GET_ITEM(args, i);
- if (PyUnicode_Check(arg)) {
-#if PY_MINOR_VERSION >=3
- arg_match = PyUnicode_AsUTF8AndSize(arg, &arg_match_len);
-#else
- PyObject *temp;
- temp = PyUnicode_AsUTF8String(arg);
- PyBytes_AsStringAndSize(temp, &arg_match, &arg_match_len);
- Py_DECREF(temp);
-#endif
- }else if (PyBytes_Check(arg)) {
- PyBytes_AsStringAndSize(arg, &arg_match, &arg_match_len);
- }else{
- PyErr_SetString(PyExc_TypeError, "expected bytes or string");
+PyDoc_STRVAR(Reader_fileno__doc__,
+ "fileno() -> int\n\n"
+ "Get a file descriptor to poll for changes in the journal.\n"
+ "This method invokes sd_journal_get_fd().\n"
+ "See man:sd_journal_get_fd(3).");
+static PyObject* Reader_fileno(Reader *self, PyObject *args) {
+ int fd;
+
+ fd = sd_journal_get_fd(self->j);
+ set_error(fd, NULL, NULL);
+ if (fd < 0)
+ return NULL;
+ return long_FromLong(fd);
+}
+
+PyDoc_STRVAR(Reader_reliable_fd__doc__,
+ "reliable_fd() -> bool\n\n"
+ "Returns True iff the journal can be polled reliably.\n"
+ "This method invokes sd_journal_reliable_fd().\n"
+ "See man:sd_journal_reliable_fd(3).");
+static PyObject* Reader_reliable_fd(Reader *self, PyObject *args) {
+ int r;
+
+ r = sd_journal_reliable_fd(self->j);
+ if (set_error(r, NULL, NULL) < 0)
+ return NULL;
+ return PyBool_FromLong(r);
+}
+
+PyDoc_STRVAR(Reader_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_journal_get_events(3) for further discussion.");
+static PyObject* Reader_get_events(Reader *self, PyObject *args) {
+ int r;
+
+ r = sd_journal_get_events(self->j);
+ if (set_error(r, NULL, NULL) < 0)
+ return NULL;
+ return long_FromLong(r);
+}
+
+PyDoc_STRVAR(Reader_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_journal_get_timeout(3) for further discussion.");
+static PyObject* Reader_get_timeout(Reader *self, PyObject *args) {
+ int r;
+ uint64_t t;
+
+ r = sd_journal_get_timeout(self->j, &t);
+ if (set_error(r, NULL, NULL) < 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(Reader_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* Reader_get_timeout_ms(Reader *self, PyObject *args) {
+ int r;
+ uint64_t t;
+
+ r = sd_journal_get_timeout(self->j, &t);
+ if (set_error(r, NULL, NULL) < 0)
+ return NULL;
+
+ return absolute_timeout(t);
+}
+
+PyDoc_STRVAR(Reader_close__doc__,
+ "close() -> None\n\n"
+ "Free resources allocated by this Reader object.\n"
+ "This method invokes sd_journal_close().\n"
+ "See man:sd_journal_close(3).");
+static PyObject* Reader_close(Reader *self, PyObject *args) {
+ assert(self);
+ assert(!args);
+
+ sd_journal_close(self->j);
+ self->j = NULL;
+ Py_RETURN_NONE;
+}
+
+PyDoc_STRVAR(Reader_get_usage__doc__,
+ "get_usage() -> int\n\n"
+ "Returns the total disk space currently used by journal\n"
+ "files (in bytes). If `SD_JOURNAL_LOCAL_ONLY` was\n"
+ "passed when opening the journal this value will only reflect\n"
+ "the size of journal files of the local host, otherwise\n"
+ "of all hosts.\n\n"
+ "This method invokes sd_journal_get_usage().\n"
+ "See man:sd_journal_get_usage(3).");
+static PyObject* Reader_get_usage(Reader *self, PyObject *args) {
+ int r;
+ uint64_t bytes;
+
+ r = sd_journal_get_usage(self->j, &bytes);
+ if (set_error(r, NULL, NULL) < 0)
+ return NULL;
+
+ assert_cc(sizeof(unsigned long long) == sizeof(bytes));
+ return PyLong_FromUnsignedLongLong(bytes);
+}
+
+PyDoc_STRVAR(Reader___enter____doc__,
+ "__enter__() -> self\n\n"
+ "Part of the context manager protocol.\n"
+ "Returns self.\n");
+static PyObject* Reader___enter__(PyObject *self, PyObject *args) {
+ assert(self);
+ assert(!args);
+
+ Py_INCREF(self);
+ return self;
+}
+
+PyDoc_STRVAR(Reader___exit____doc__,
+ "__exit__(type, value, traceback) -> None\n\n"
+ "Part of the context manager protocol.\n"
+ "Closes the journal.\n");
+static PyObject* Reader___exit__(Reader *self, PyObject *args) {
+ return Reader_close(self, args);
+}
+
+PyDoc_STRVAR(Reader_next__doc__,
+ "next([skip]) -> bool\n\n"
+ "Go to the next log entry. Optional skip value means to go to\n"
+ "the `skip`\\-th log entry.\n"
+ "Returns False if at end of file, True otherwise.");
+static PyObject* Reader_next(Reader *self, PyObject *args) {
+ int64_t skip = 1LL;
+ int r;
+
+ if (!PyArg_ParseTuple(args, "|L:next", &skip))
+ return NULL;
+
+ if (skip == 0LL) {
+ PyErr_SetString(PyExc_ValueError, "skip must be nonzero");
+ return NULL;