File: Read.xs

package info (click to toggle)
liblinux-systemd-perl 1.201600-4
  • links: PTS, VCS
  • area: main
  • in suites: bookworm, forky, sid, trixie
  • size: 284 kB
  • sloc: perl: 640; makefile: 7
file content (154 lines) | stat: -rw-r--r-- 3,771 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
#include "EXTERN.h"
#include "perl.h"
#include "XSUB.h"

#include <systemd/sd-journal.h>

sd_journal *j;

void split_data_to_svs(const char *msg, SV **k_sv, SV **v_sv) {
    char *data_copy = strdup(msg);
    char *k = strtok(data_copy, "=");
    char *v = strtok(NULL, "=");

    (*k_sv) = newSVpv(k, strlen(k));
    (*v_sv) = newSVpv(v, strlen(v));
}

MODULE = Linux::Systemd::Journal::Read PACKAGE = Linux::Systemd::Journal::Read

PROTOTYPES: ENABLE

NO_OUTPUT void
__open()
    CODE:
        int r = sd_journal_open(&j, SD_JOURNAL_LOCAL_ONLY);
        if (r < 0)
            croak("Failed to open journal: %s\n", strerror(r));
//
// NO_OUTPUT void
// __open_files(path)
//     CODE:
//         int r = sd_journal_open_files(&j, path, SD_JOURNAL_LOCAL_ONLY);
//         if (r < 0)
//             croak("Failed to open journal: %s\n", strerror(r));

uint64_t
get_usage(self)
    CODE:
        int r = sd_journal_get_usage(j, &RETVAL);
        if (r < 0)
            croak("Failed to open journal: %s\n", strerror(-r));
    OUTPUT: RETVAL

int
next(self, uint64_t skip=0)
    CODE:
        if (skip > 0)
            RETVAL = sd_journal_next_skip(j, skip);
        else
            RETVAL = sd_journal_next(j);
    POSTCALL:
        if (RETVAL < 0)
            croak("Failed to move to next record: %s\n", strerror(-RETVAL));
    OUTPUT: RETVAL

int
previous(self, uint64_t skip=0)
    CODE:
        if (skip > 0)
            RETVAL = sd_journal_previous_skip(j, skip);
        else
            RETVAL = sd_journal_previous(j);
    POSTCALL:
        if (RETVAL < 0)
            croak("Failed to move to previous record: %s\n", strerror(-RETVAL));
    OUTPUT: RETVAL

NO_OUTPUT void
seek_head(self)
    CODE:
        int r = sd_journal_seek_head(j);
        if (r < 0)
            croak("Failed to seek to journal head: %s\n", strerror(-r));

NO_OUTPUT void
seek_tail(self)
    CODE:
        int r = sd_journal_seek_tail(j);
        if (r < 0)
            croak("Failed to seek to journal tail: %s\n", strerror(-r));

NO_OUTPUT void
wait(self)
    CODE:
        int r = sd_journal_wait(j, (uint64_t) -1);
        if (r < 0)
            croak("Failed to wait for changes: %s\n", strerror(-r));


SV *
get_data(self, const char *field)
    CODE:
        SV     *key_sv;
        char   *data;
        size_t l;
        int r = sd_journal_get_data(j, field, (const void**) &data, &l);
        if (r < 0)
            croak("Failed to read message field '%s': %s\n", field, strerror(-r));

        split_data_to_svs(data, &key_sv, &RETVAL);
    OUTPUT: RETVAL

HV *
get_entry(self)
    PREINIT:
        const void *data;
        size_t l;
        SV   *key_sv, *val_sv;
        int r;
    CODE:
        RETVAL = newHV();
        sd_journal_restart_data(j);
        while ((r = sd_journal_enumerate_data(j, &data, &l)) > 0) {
            split_data_to_svs(data, &key_sv, &val_sv);
            hv_store_ent(RETVAL, key_sv, val_sv, 0);
        }

        if (r < 0)
            croak("Failed to get entry data: %s\n", strerror(-r));

    OUTPUT: RETVAL

# TODO should take binary data as well
NO_OUTPUT void
__add_match(const char *data)
    CODE:
        int r = sd_journal_add_match(j, data, 0);
        if (r < 0)
            croak("Failed to add a match: %s\n", strerror(-r));

NO_OUTPUT void
__match_and()
    CODE:
        int r = sd_journal_add_conjunction(j);
        if (r < 0)
            croak("Failed to set conjunction: %s\n", strerror(-r));

NO_OUTPUT void
__match_or()
    CODE:
        int r = sd_journal_add_disjunction(j);
        if (r < 0)
            croak("Failed to set disjunction: %s\n", strerror(-r));

NO_OUTPUT void
flush_matches(self)
    CODE:
        sd_journal_flush_matches(j);


NO_OUTPUT void
DESTROY(self)
    CODE:
        sd_journal_close(j);