Bug Summary

File:build-scan/../src/journal/journald-stream.c
Warning:line 621, column 9
Value stored to 'fd' is never read

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-unknown-linux-gnu -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name journald-stream.c -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model pic -pic-level 2 -fhalf-no-semantic-interposition -mframe-pointer=all -relaxed-aliasing -menable-no-infs -menable-no-nans -menable-unsafe-fp-math -fno-signed-zeros -mreassociate -freciprocal-math -fdenormal-fp-math=preserve-sign,preserve-sign -ffp-contract=fast -fno-rounding-math -ffast-math -ffinite-math-only -mconstructor-aliases -munwind-tables -target-cpu x86-64 -tune-cpu generic -fno-split-dwarf-inlining -debugger-tuning=gdb -resource-dir /usr/lib64/clang/12.0.0 -include config.h -I libjournal-core.a.p -I . -I .. -I src/basic -I ../src/basic -I src/shared -I ../src/shared -I src/systemd -I ../src/systemd -I src/journal -I ../src/journal -I src/journal-remote -I ../src/journal-remote -I src/nspawn -I ../src/nspawn -I src/resolve -I ../src/resolve -I src/timesync -I ../src/timesync -I ../src/time-wait-sync -I src/login -I ../src/login -I src/udev -I ../src/udev -I src/libudev -I ../src/libudev -I src/core -I ../src/core -I ../src/libsystemd/sd-bus -I ../src/libsystemd/sd-device -I ../src/libsystemd/sd-hwdb -I ../src/libsystemd/sd-id128 -I ../src/libsystemd/sd-netlink -I ../src/libsystemd/sd-network -I src/libsystemd-network -I ../src/libsystemd-network -D _FILE_OFFSET_BITS=64 -internal-isystem /usr/local/include -internal-isystem /usr/lib64/clang/12.0.0/include -internal-externc-isystem /include -internal-externc-isystem /usr/include -Wwrite-strings -Wno-unused-parameter -Wno-missing-field-initializers -Wno-unused-result -Wno-format-signedness -Wno-error=nonnull -std=gnu99 -fconst-strings -fdebug-compilation-dir /home/mrc0mmand/repos/@redhat-plumbers/systemd-rhel8/build-scan -ferror-limit 19 -fvisibility hidden -stack-protector 2 -fgnuc-version=4.2.1 -fcolor-diagnostics -analyzer-output=html -faddrsig -o /tmp/scan-build-2021-07-16-221226-1465241-1 -x c ../src/journal/journald-stream.c
1/* SPDX-License-Identifier: LGPL-2.1+ */
2
3#include <stddef.h>
4#include <unistd.h>
5
6#if HAVE_SELINUX1
7#include <selinux/selinux.h>
8#endif
9
10#include "sd-daemon.h"
11#include "sd-event.h"
12
13#include "alloc-util.h"
14#include "dirent-util.h"
15#include "escape.h"
16#include "fd-util.h"
17#include "fileio.h"
18#include "io-util.h"
19#include "journald-console.h"
20#include "journald-context.h"
21#include "journald-kmsg.h"
22#include "journald-server.h"
23#include "journald-stream.h"
24#include "journald-syslog.h"
25#include "journald-wall.h"
26#include "mkdir.h"
27#include "parse-util.h"
28#include "process-util.h"
29#include "selinux-util.h"
30#include "socket-util.h"
31#include "stdio-util.h"
32#include "string-util.h"
33#include "syslog-util.h"
34#include "unit-name.h"
35
36#define STDOUT_STREAMS_MAX4096 4096
37
38typedef enum StdoutStreamState {
39 STDOUT_STREAM_IDENTIFIER,
40 STDOUT_STREAM_UNIT_ID,
41 STDOUT_STREAM_PRIORITY,
42 STDOUT_STREAM_LEVEL_PREFIX,
43 STDOUT_STREAM_FORWARD_TO_SYSLOG,
44 STDOUT_STREAM_FORWARD_TO_KMSG,
45 STDOUT_STREAM_FORWARD_TO_CONSOLE,
46 STDOUT_STREAM_RUNNING
47} StdoutStreamState;
48
49/* The different types of log record terminators: a real \n was read, a NUL character was read, the maximum line length
50 * was reached, or the end of the stream was reached */
51
52typedef enum LineBreak {
53 LINE_BREAK_NEWLINE,
54 LINE_BREAK_NUL,
55 LINE_BREAK_LINE_MAX,
56 LINE_BREAK_EOF,
57} LineBreak;
58
59struct StdoutStream {
60 Server *server;
61 StdoutStreamState state;
62
63 int fd;
64
65 struct ucred ucred;
66 char *label;
67 char *identifier;
68 char *unit_id;
69 int priority;
70 bool_Bool level_prefix:1;
71 bool_Bool forward_to_syslog:1;
72 bool_Bool forward_to_kmsg:1;
73 bool_Bool forward_to_console:1;
74
75 bool_Bool fdstore:1;
76 bool_Bool in_notify_queue:1;
77
78 char *buffer;
79 size_t length;
80 size_t allocated;
81
82 sd_event_source *event_source;
83
84 char *state_file;
85
86 ClientContext *context;
87
88 LIST_FIELDS(StdoutStream, stdout_stream)StdoutStream *stdout_stream_next, *stdout_stream_prev;
89 LIST_FIELDS(StdoutStream, stdout_stream_notify_queue)StdoutStream *stdout_stream_notify_queue_next, *stdout_stream_notify_queue_prev;
90
91 char id_field[STRLEN("_STREAM_ID=")(sizeof("""_STREAM_ID=""") - 1) + SD_ID128_STRING_MAX33];
92};
93
94void stdout_stream_free(StdoutStream *s) {
95 if (!s)
96 return;
97
98 if (s->server) {
99
100 if (s->context)
101 client_context_release(s->server, s->context);
102
103 assert(s->server->n_stdout_streams > 0)do { if ((__builtin_expect(!!(!(s->server->n_stdout_streams
> 0)),0))) log_assert_failed_realm(LOG_REALM_SYSTEMD, ("s->server->n_stdout_streams > 0"
), "../src/journal/journald-stream.c", 103, __PRETTY_FUNCTION__
); } while (0)
;
104 s->server->n_stdout_streams--;
105 LIST_REMOVE(stdout_stream, s->server->stdout_streams, s)do { typeof(*(s->server->stdout_streams)) **_head = &
(s->server->stdout_streams), *_item = (s); do { if ((__builtin_expect
(!!(!(_item)),0))) log_assert_failed_realm(LOG_REALM_SYSTEMD,
("_item"), "../src/journal/journald-stream.c", 105, __PRETTY_FUNCTION__
); } while (0); if (_item->stdout_stream_next) _item->stdout_stream_next
->stdout_stream_prev = _item->stdout_stream_prev; if (_item
->stdout_stream_prev) _item->stdout_stream_prev->stdout_stream_next
= _item->stdout_stream_next; else { do { if ((__builtin_expect
(!!(!(*_head == _item)),0))) log_assert_failed_realm(LOG_REALM_SYSTEMD
, ("*_head == _item"), "../src/journal/journald-stream.c", 105
, __PRETTY_FUNCTION__); } while (0); *_head = _item->stdout_stream_next
; } _item->stdout_stream_next = _item->stdout_stream_prev
= ((void*)0); } while (0)
;
106
107 if (s->in_notify_queue)
108 LIST_REMOVE(stdout_stream_notify_queue, s->server->stdout_streams_notify_queue, s)do { typeof(*(s->server->stdout_streams_notify_queue)) *
*_head = &(s->server->stdout_streams_notify_queue),
*_item = (s); do { if ((__builtin_expect(!!(!(_item)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("_item"), "../src/journal/journald-stream.c"
, 108, __PRETTY_FUNCTION__); } while (0); if (_item->stdout_stream_notify_queue_next
) _item->stdout_stream_notify_queue_next->stdout_stream_notify_queue_prev
= _item->stdout_stream_notify_queue_prev; if (_item->stdout_stream_notify_queue_prev
) _item->stdout_stream_notify_queue_prev->stdout_stream_notify_queue_next
= _item->stdout_stream_notify_queue_next; else { do { if (
(__builtin_expect(!!(!(*_head == _item)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("*_head == _item"), "../src/journal/journald-stream.c"
, 108, __PRETTY_FUNCTION__); } while (0); *_head = _item->
stdout_stream_notify_queue_next; } _item->stdout_stream_notify_queue_next
= _item->stdout_stream_notify_queue_prev = ((void*)0); } while
(0)
;
109 }
110
111 if (s->event_source) {
112 sd_event_source_set_enabled(s->event_source, SD_EVENT_OFF);
113 s->event_source = sd_event_source_unref(s->event_source);
114 }
115
116 safe_close(s->fd);
117 free(s->label);
118 free(s->identifier);
119 free(s->unit_id);
120 free(s->state_file);
121 free(s->buffer);
122
123 free(s);
124}
125
126DEFINE_TRIVIAL_CLEANUP_FUNC(StdoutStream*, stdout_stream_free)static inline void stdout_stream_freep(StdoutStream* *p) { if
(*p) stdout_stream_free(*p); }
;
127
128void stdout_stream_destroy(StdoutStream *s) {
129 if (!s)
130 return;
131
132 if (s->state_file)
133 (void) unlink(s->state_file);
134
135 stdout_stream_free(s);
136}
137
138static int stdout_stream_save(StdoutStream *s) {
139 _cleanup_free___attribute__((cleanup(freep))) char *temp_path = NULL((void*)0);
140 _cleanup_fclose___attribute__((cleanup(fclosep))) FILE *f = NULL((void*)0);
141 int r;
142
143 assert(s)do { if ((__builtin_expect(!!(!(s)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("s"), "../src/journal/journald-stream.c"
, 143, __PRETTY_FUNCTION__); } while (0)
;
144
145 if (s->state != STDOUT_STREAM_RUNNING)
146 return 0;
147
148 if (!s->state_file) {
149 struct stat st;
150
151 r = fstat(s->fd, &st);
152 if (r < 0)
153 return log_warning_errno(errno, "Failed to stat connected stream: %m")({ int _level = ((4)), _e = (((*__errno_location ()))), _realm
= (LOG_REALM_SYSTEMD); (log_get_max_level_realm(_realm) >=
((_level) & 0x07)) ? log_internal_realm(((_realm) <<
10 | (_level)), _e, "../src/journal/journald-stream.c", 153,
__func__, "Failed to stat connected stream: %m") : -abs(_e);
})
;
154
155 /* We use device and inode numbers as identifier for the stream */
156 if (asprintf(&s->state_file, "/run/systemd/journal/streams/%lu:%lu", (unsigned long) st.st_dev, (unsigned long) st.st_ino) < 0)
157 return log_oom()log_oom_internal(LOG_REALM_SYSTEMD, "../src/journal/journald-stream.c"
, 157, __func__)
;
158 }
159
160 mkdir_p("/run/systemd/journal/streams", 0755);
161
162 r = fopen_temporary(s->state_file, &f, &temp_path);
163 if (r < 0)
164 goto fail;
165
166 fprintf(f,
167 "# This is private data. Do not parse\n"
168 "PRIORITY=%i\n"
169 "LEVEL_PREFIX=%i\n"
170 "FORWARD_TO_SYSLOG=%i\n"
171 "FORWARD_TO_KMSG=%i\n"
172 "FORWARD_TO_CONSOLE=%i\n"
173 "STREAM_ID=%s\n",
174 s->priority,
175 s->level_prefix,
176 s->forward_to_syslog,
177 s->forward_to_kmsg,
178 s->forward_to_console,
179 s->id_field + STRLEN("_STREAM_ID=")(sizeof("""_STREAM_ID=""") - 1));
180
181 if (!isempty(s->identifier)) {
182 _cleanup_free___attribute__((cleanup(freep))) char *escaped;
183
184 escaped = cescape(s->identifier);
185 if (!escaped) {
186 r = -ENOMEM12;
187 goto fail;
188 }
189
190 fprintf(f, "IDENTIFIER=%s\n", escaped);
191 }
192
193 if (!isempty(s->unit_id)) {
194 _cleanup_free___attribute__((cleanup(freep))) char *escaped;
195
196 escaped = cescape(s->unit_id);
197 if (!escaped) {
198 r = -ENOMEM12;
199 goto fail;
200 }
201
202 fprintf(f, "UNIT=%s\n", escaped);
203 }
204
205 r = fflush_and_check(f);
206 if (r < 0)
207 goto fail;
208
209 if (rename(temp_path, s->state_file) < 0) {
210 r = -errno(*__errno_location ());
211 goto fail;
212 }
213
214 if (!s->fdstore && !s->in_notify_queue) {
215 LIST_PREPEND(stdout_stream_notify_queue, s->server->stdout_streams_notify_queue, s)do { typeof(*(s->server->stdout_streams_notify_queue)) *
*_head = &(s->server->stdout_streams_notify_queue),
*_item = (s); do { if ((__builtin_expect(!!(!(_item)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("_item"), "../src/journal/journald-stream.c"
, 215, __PRETTY_FUNCTION__); } while (0); if ((_item->stdout_stream_notify_queue_next
= *_head)) _item->stdout_stream_notify_queue_next->stdout_stream_notify_queue_prev
= _item; _item->stdout_stream_notify_queue_prev = ((void*
)0); *_head = _item; } while (0)
;
216 s->in_notify_queue = true1;
217
218 if (s->server->notify_event_source) {
219 r = sd_event_source_set_enabled(s->server->notify_event_source, SD_EVENT_ON);
220 if (r < 0)
221 log_warning_errno(r, "Failed to enable notify event source: %m")({ int _level = ((4)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/journal/journald-stream.c", 221, __func__, "Failed to enable notify event source: %m"
) : -abs(_e); })
;
222 }
223 }
224
225 return 0;
226
227fail:
228 (void) unlink(s->state_file);
229
230 if (temp_path)
231 (void) unlink(temp_path);
232
233 return log_error_errno(r, "Failed to save stream data %s: %m", s->state_file)({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/journal/journald-stream.c", 233, __func__, "Failed to save stream data %s: %m"
, s->state_file) : -abs(_e); })
;
234}
235
236static int stdout_stream_log(StdoutStream *s, const char *p, LineBreak line_break) {
237 struct iovec *iovec;
238 int priority;
239 char syslog_priority[] = "PRIORITY=\0";
240 char syslog_facility[STRLEN("SYSLOG_FACILITY=")(sizeof("""SYSLOG_FACILITY=""") - 1) + DECIMAL_STR_MAX(int)(2+(sizeof(int) <= 1 ? 3 : sizeof(int) <= 2 ? 5 : sizeof
(int) <= 4 ? 10 : sizeof(int) <= 8 ? 20 : sizeof(int[-2
*(sizeof(int) > 8)])))
+ 1];
241 _cleanup_free___attribute__((cleanup(freep))) char *message = NULL((void*)0), *syslog_identifier = NULL((void*)0);
242 size_t n = 0, m;
243 int r;
244
245 assert(s)do { if ((__builtin_expect(!!(!(s)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("s"), "../src/journal/journald-stream.c"
, 245, __PRETTY_FUNCTION__); } while (0)
;
246 assert(p)do { if ((__builtin_expect(!!(!(p)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("p"), "../src/journal/journald-stream.c"
, 246, __PRETTY_FUNCTION__); } while (0)
;
247
248 if (s->context)
249 (void) client_context_maybe_refresh(s->server, s->context, NULL((void*)0), NULL((void*)0), 0, NULL((void*)0), USEC_INFINITY((usec_t) -1));
250 else if (pid_is_valid(s->ucred.pid)) {
251 r = client_context_acquire(s->server, s->ucred.pid, &s->ucred, s->label, strlen_ptr(s->label), s->unit_id, &s->context);
252 if (r < 0)
253 log_warning_errno(r, "Failed to acquire client context, ignoring: %m")({ int _level = ((4)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/journal/journald-stream.c", 253, __func__, "Failed to acquire client context, ignoring: %m"
) : -abs(_e); })
;
254 }
255
256 priority = s->priority;
257
258 if (s->level_prefix)
259 syslog_parse_priority(&p, &priority, false0);
260
261 if (!client_context_test_priority(s->context, priority))
262 return 0;
263
264 if (isempty(p))
265 return 0;
266
267 if (s->forward_to_syslog || s->server->forward_to_syslog)
268 server_forward_syslog(s->server, syslog_fixup_facility(priority), s->identifier, p, &s->ucred, NULL((void*)0));
269
270 if (s->forward_to_kmsg || s->server->forward_to_kmsg)
271 server_forward_kmsg(s->server, priority, s->identifier, p, &s->ucred);
272
273 if (s->forward_to_console || s->server->forward_to_console)
274 server_forward_console(s->server, priority, s->identifier, p, &s->ucred);
275
276 if (s->server->forward_to_wall)
277 server_forward_wall(s->server, priority, s->identifier, p, &s->ucred);
278
279 m = N_IOVEC_META_FIELDS22 + 7 + client_context_extra_fields_n_iovec(s->context);
280 iovec = newa(struct iovec, m)({ do { if ((__builtin_expect(!!(!(!size_multiply_overflow(sizeof
(struct iovec), m))),0))) log_assert_failed_realm(LOG_REALM_SYSTEMD
, ("!size_multiply_overflow(sizeof(struct iovec), m)"), "../src/journal/journald-stream.c"
, 280, __PRETTY_FUNCTION__); } while (0); (struct iovec*) __builtin_alloca
(sizeof(struct iovec)*(m)); })
;
281
282 iovec[n++] = IOVEC_MAKE_STRING("_TRANSPORT=stdout")(struct iovec) { .iov_base = ((char*) "_TRANSPORT=stdout"), .
iov_len = (strlen("_TRANSPORT=stdout")) }
;
283 iovec[n++] = IOVEC_MAKE_STRING(s->id_field)(struct iovec) { .iov_base = ((char*) s->id_field), .iov_len
= (strlen(s->id_field)) }
;
284
285 syslog_priority[STRLEN("PRIORITY=")(sizeof("""PRIORITY=""") - 1)] = '0' + LOG_PRI(priority)((priority) & 0x07);
286 iovec[n++] = IOVEC_MAKE_STRING(syslog_priority)(struct iovec) { .iov_base = ((char*) syslog_priority), .iov_len
= (strlen(syslog_priority)) }
;
287
288 if (priority & LOG_FACMASK0x03f8) {
289 xsprintf(syslog_facility, "SYSLOG_FACILITY=%i", LOG_FAC(priority))do { if ((__builtin_expect(!!(!(((size_t) snprintf(syslog_facility
, __extension__ (__builtin_choose_expr( !__builtin_types_compatible_p
(typeof(syslog_facility), typeof(&*(syslog_facility))), sizeof
(syslog_facility)/sizeof((syslog_facility)[0]), ((void)0))), "SYSLOG_FACILITY=%i"
, (((priority) & 0x03f8) >> 3)) < (__extension__
(__builtin_choose_expr( !__builtin_types_compatible_p(typeof
(syslog_facility), typeof(&*(syslog_facility))), sizeof(syslog_facility
)/sizeof((syslog_facility)[0]), ((void)0))))))),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("xsprintf: " "syslog_facility" "[] must be big enough"
), "../src/journal/journald-stream.c", 289, __PRETTY_FUNCTION__
); } while (0)
;
290 iovec[n++] = IOVEC_MAKE_STRING(syslog_facility)(struct iovec) { .iov_base = ((char*) syslog_facility), .iov_len
= (strlen(syslog_facility)) }
;
291 }
292
293 if (s->identifier) {
294 syslog_identifier = strappend("SYSLOG_IDENTIFIER=", s->identifier);
295 if (syslog_identifier)
296 iovec[n++] = IOVEC_MAKE_STRING(syslog_identifier)(struct iovec) { .iov_base = ((char*) syslog_identifier), .iov_len
= (strlen(syslog_identifier)) }
;
297 }
298
299 if (line_break != LINE_BREAK_NEWLINE) {
300 const char *c;
301
302 /* If this log message was generated due to an uncommon line break then mention this in the log
303 * entry */
304
305 c = line_break == LINE_BREAK_NUL ? "_LINE_BREAK=nul" :
306 line_break == LINE_BREAK_LINE_MAX ? "_LINE_BREAK=line-max" :
307 "_LINE_BREAK=eof";
308 iovec[n++] = IOVEC_MAKE_STRING(c)(struct iovec) { .iov_base = ((char*) c), .iov_len = (strlen(
c)) }
;
309 }
310
311 message = strappend("MESSAGE=", p);
312 if (message)
313 iovec[n++] = IOVEC_MAKE_STRING(message)(struct iovec) { .iov_base = ((char*) message), .iov_len = (strlen
(message)) }
;
314
315 server_dispatch_message(s->server, iovec, n, m, s->context, NULL((void*)0), priority, 0);
316 return 0;
317}
318
319static int stdout_stream_line(StdoutStream *s, char *p, LineBreak line_break) {
320 int r;
321 char *orig;
322
323 assert(s)do { if ((__builtin_expect(!!(!(s)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("s"), "../src/journal/journald-stream.c"
, 323, __PRETTY_FUNCTION__); } while (0)
;
324 assert(p)do { if ((__builtin_expect(!!(!(p)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("p"), "../src/journal/journald-stream.c"
, 324, __PRETTY_FUNCTION__); } while (0)
;
325
326 orig = p;
327 p = strstrip(p);
328
329 /* line breaks by NUL, line max length or EOF are not permissible during the negotiation part of the protocol */
330 if (line_break != LINE_BREAK_NEWLINE && s->state != STDOUT_STREAM_RUNNING) {
331 log_warning("Control protocol line not properly terminated.")({ int _level = (((4))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/journal/journald-stream.c", 331, __func__, "Control protocol line not properly terminated."
) : -abs(_e); })
;
332 return -EINVAL22;
333 }
334
335 switch (s->state) {
336
337 case STDOUT_STREAM_IDENTIFIER:
338 if (!isempty(p)) {
339 s->identifier = strdup(p);
340 if (!s->identifier)
341 return log_oom()log_oom_internal(LOG_REALM_SYSTEMD, "../src/journal/journald-stream.c"
, 341, __func__)
;
342 }
343
344 s->state = STDOUT_STREAM_UNIT_ID;
345 return 0;
346
347 case STDOUT_STREAM_UNIT_ID:
348 if (s->ucred.uid == 0 &&
349 unit_name_is_valid(p, UNIT_NAME_PLAIN|UNIT_NAME_INSTANCE)) {
350
351 s->unit_id = strdup(p);
352 if (!s->unit_id)
353 return log_oom()log_oom_internal(LOG_REALM_SYSTEMD, "../src/journal/journald-stream.c"
, 353, __func__)
;
354 }
355
356 s->state = STDOUT_STREAM_PRIORITY;
357 return 0;
358
359 case STDOUT_STREAM_PRIORITY:
360 r = safe_atoi(p, &s->priority);
361 if (r < 0 || s->priority < 0 || s->priority > 999) {
362 log_warning("Failed to parse log priority line.")({ int _level = (((4))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/journal/journald-stream.c", 362, __func__, "Failed to parse log priority line."
) : -abs(_e); })
;
363 return -EINVAL22;
364 }
365
366 s->state = STDOUT_STREAM_LEVEL_PREFIX;
367 return 0;
368
369 case STDOUT_STREAM_LEVEL_PREFIX:
370 r = parse_boolean(p);
371 if (r < 0) {
372 log_warning("Failed to parse level prefix line.")({ int _level = (((4))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/journal/journald-stream.c", 372, __func__, "Failed to parse level prefix line."
) : -abs(_e); })
;
373 return -EINVAL22;
374 }
375
376 s->level_prefix = r;
377 s->state = STDOUT_STREAM_FORWARD_TO_SYSLOG;
378 return 0;
379
380 case STDOUT_STREAM_FORWARD_TO_SYSLOG:
381 r = parse_boolean(p);
382 if (r < 0) {
383 log_warning("Failed to parse forward to syslog line.")({ int _level = (((4))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/journal/journald-stream.c", 383, __func__, "Failed to parse forward to syslog line."
) : -abs(_e); })
;
384 return -EINVAL22;
385 }
386
387 s->forward_to_syslog = r;
388 s->state = STDOUT_STREAM_FORWARD_TO_KMSG;
389 return 0;
390
391 case STDOUT_STREAM_FORWARD_TO_KMSG:
392 r = parse_boolean(p);
393 if (r < 0) {
394 log_warning("Failed to parse copy to kmsg line.")({ int _level = (((4))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/journal/journald-stream.c", 394, __func__, "Failed to parse copy to kmsg line."
) : -abs(_e); })
;
395 return -EINVAL22;
396 }
397
398 s->forward_to_kmsg = r;
399 s->state = STDOUT_STREAM_FORWARD_TO_CONSOLE;
400 return 0;
401
402 case STDOUT_STREAM_FORWARD_TO_CONSOLE:
403 r = parse_boolean(p);
404 if (r < 0) {
405 log_warning("Failed to parse copy to console line.")({ int _level = (((4))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/journal/journald-stream.c", 405, __func__, "Failed to parse copy to console line."
) : -abs(_e); })
;
406 return -EINVAL22;
407 }
408
409 s->forward_to_console = r;
410 s->state = STDOUT_STREAM_RUNNING;
411
412 /* Try to save the stream, so that journald can be restarted and we can recover */
413 (void) stdout_stream_save(s);
414 return 0;
415
416 case STDOUT_STREAM_RUNNING:
417 return stdout_stream_log(s, orig, line_break);
418 }
419
420 assert_not_reached("Unknown stream state")do { log_assert_failed_unreachable_realm(LOG_REALM_SYSTEMD, (
"Unknown stream state"), "../src/journal/journald-stream.c", 420
, __PRETTY_FUNCTION__); } while (0)
;
421}
422
423static int stdout_stream_scan(StdoutStream *s, bool_Bool force_flush) {
424 char *p;
425 size_t remaining;
426 int r;
427
428 assert(s)do { if ((__builtin_expect(!!(!(s)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("s"), "../src/journal/journald-stream.c"
, 428, __PRETTY_FUNCTION__); } while (0)
;
429
430 p = s->buffer;
431 remaining = s->length;
432
433 /* XXX: This function does nothing if (s->length == 0) */
434
435 for (;;) {
436 LineBreak line_break;
437 size_t skip;
438 char *end1, *end2;
439
440 end1 = memchr(p, '\n', remaining);
441 end2 = memchr(p, 0, end1 ? (size_t) (end1 - p) : remaining);
442
443 if (end2) {
444 /* We found a NUL terminator */
445 skip = end2 - p + 1;
446 line_break = LINE_BREAK_NUL;
447 } else if (end1) {
448 /* We found a \n terminator */
449 *end1 = 0;
450 skip = end1 - p + 1;
451 line_break = LINE_BREAK_NEWLINE;
452 } else if (remaining >= s->server->line_max) {
453 /* Force a line break after the maximum line length */
454 *(p + s->server->line_max) = 0;
455 skip = remaining;
456 line_break = LINE_BREAK_LINE_MAX;
457 } else
458 break;
459
460 r = stdout_stream_line(s, p, line_break);
461 if (r < 0)
462 return r;
463
464 remaining -= skip;
465 p += skip;
466 }
467
468 if (force_flush && remaining > 0) {
469 p[remaining] = 0;
470 r = stdout_stream_line(s, p, LINE_BREAK_EOF);
471 if (r < 0)
472 return r;
473
474 p += remaining;
475 remaining = 0;
476 }
477
478 if (p > s->buffer) {
479 memmove(s->buffer, p, remaining);
480 s->length = remaining;
481 }
482
483 return 0;
484}
485
486static int stdout_stream_process(sd_event_source *es, int fd, uint32_t revents, void *userdata) {
487 StdoutStream *s = userdata;
488 size_t limit;
489 ssize_t l;
490 int r;
491
492 assert(s)do { if ((__builtin_expect(!!(!(s)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("s"), "../src/journal/journald-stream.c"
, 492, __PRETTY_FUNCTION__); } while (0)
;
493
494 if ((revents|EPOLLINEPOLLIN|EPOLLHUPEPOLLHUP) != (EPOLLINEPOLLIN|EPOLLHUPEPOLLHUP)) {
495 log_error("Got invalid event from epoll for stdout stream: %"PRIx32, revents)({ int _level = (((3))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/journal/journald-stream.c", 495, __func__, "Got invalid event from epoll for stdout stream: %"
"x", revents) : -abs(_e); })
;
496 goto terminate;
497 }
498
499 /* If the buffer is full already (discounting the extra NUL we need), add room for another 1K */
500 if (s->length + 1 >= s->allocated) {
501 if (!GREEDY_REALLOC(s->buffer, s->allocated, s->length + 1 + 1024)greedy_realloc((void**) &(s->buffer), &(s->allocated
), (s->length + 1 + 1024), sizeof((s->buffer)[0]))
) {
502 log_oom()log_oom_internal(LOG_REALM_SYSTEMD, "../src/journal/journald-stream.c"
, 502, __func__)
;
503 goto terminate;
504 }
505 }
506
507 /* Try to make use of the allocated buffer in full, but never read more than the configured line size. Also,
508 * always leave room for a terminating NUL we might need to add. */
509 limit = MIN(s->allocated - 1, s->server->line_max)__extension__ ({ const typeof((s->allocated - 1)) __unique_prefix_A13
= ((s->allocated - 1)); const typeof((s->server->line_max
)) __unique_prefix_B14 = ((s->server->line_max)); __unique_prefix_A13
< __unique_prefix_B14 ? __unique_prefix_A13 : __unique_prefix_B14
; })
;
510
511 l = read(s->fd, s->buffer + s->length, limit - s->length);
512 if (l < 0) {
513 if (errno(*__errno_location ()) == EAGAIN11)
514 return 0;
515
516 log_warning_errno(errno, "Failed to read from stream: %m")({ int _level = ((4)), _e = (((*__errno_location ()))), _realm
= (LOG_REALM_SYSTEMD); (log_get_max_level_realm(_realm) >=
((_level) & 0x07)) ? log_internal_realm(((_realm) <<
10 | (_level)), _e, "../src/journal/journald-stream.c", 516,
__func__, "Failed to read from stream: %m") : -abs(_e); })
;
517 goto terminate;
518 }
519
520 if (l == 0) {
521 stdout_stream_scan(s, true1);
522 goto terminate;
523 }
524
525 s->length += l;
526 r = stdout_stream_scan(s, false0);
527 if (r < 0)
528 goto terminate;
529
530 return 1;
531
532terminate:
533 stdout_stream_destroy(s);
534 return 0;
535}
536
537int stdout_stream_install(Server *s, int fd, StdoutStream **ret) {
538 _cleanup_(stdout_stream_freep)__attribute__((cleanup(stdout_stream_freep))) StdoutStream *stream = NULL((void*)0);
539 sd_id128_t id;
540 int r;
541
542 assert(s)do { if ((__builtin_expect(!!(!(s)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("s"), "../src/journal/journald-stream.c"
, 542, __PRETTY_FUNCTION__); } while (0)
;
543 assert(fd >= 0)do { if ((__builtin_expect(!!(!(fd >= 0)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("fd >= 0"), "../src/journal/journald-stream.c"
, 543, __PRETTY_FUNCTION__); } while (0)
;
544
545 r = sd_id128_randomize(&id);
546 if (r < 0)
547 return log_error_errno(r, "Failed to generate stream ID: %m")({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/journal/journald-stream.c", 547, __func__, "Failed to generate stream ID: %m"
) : -abs(_e); })
;
548
549 stream = new0(StdoutStream, 1)((StdoutStream*) calloc((1), sizeof(StdoutStream)));
550 if (!stream)
551 return log_oom()log_oom_internal(LOG_REALM_SYSTEMD, "../src/journal/journald-stream.c"
, 551, __func__)
;
552
553 stream->fd = -1;
554 stream->priority = LOG_INFO6;
555
556 xsprintf(stream->id_field, "_STREAM_ID=" SD_ID128_FORMAT_STR, SD_ID128_FORMAT_VAL(id))do { if ((__builtin_expect(!!(!(((size_t) snprintf(stream->
id_field, __extension__ (__builtin_choose_expr( !__builtin_types_compatible_p
(typeof(stream->id_field), typeof(&*(stream->id_field
))), sizeof(stream->id_field)/sizeof((stream->id_field)
[0]), ((void)0))), "_STREAM_ID=" "%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x"
, (id).bytes[0], (id).bytes[1], (id).bytes[2], (id).bytes[3],
(id).bytes[4], (id).bytes[5], (id).bytes[6], (id).bytes[7], (
id).bytes[8], (id).bytes[9], (id).bytes[10], (id).bytes[11], (
id).bytes[12], (id).bytes[13], (id).bytes[14], (id).bytes[15]
) < (__extension__ (__builtin_choose_expr( !__builtin_types_compatible_p
(typeof(stream->id_field), typeof(&*(stream->id_field
))), sizeof(stream->id_field)/sizeof((stream->id_field)
[0]), ((void)0))))))),0))) log_assert_failed_realm(LOG_REALM_SYSTEMD
, ("xsprintf: " "stream->id_field" "[] must be big enough"
), "../src/journal/journald-stream.c", 556, __PRETTY_FUNCTION__
); } while (0)
;
557
558 r = getpeercred(fd, &stream->ucred);
559 if (r < 0)
560 return log_error_errno(r, "Failed to determine peer credentials: %m")({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/journal/journald-stream.c", 560, __func__, "Failed to determine peer credentials: %m"
) : -abs(_e); })
;
561
562 if (mac_selinux_use()) {
563 r = getpeersec(fd, &stream->label);
564 if (r < 0 && r != -EOPNOTSUPP95)
565 (void) log_warning_errno(r, "Failed to determine peer security context: %m")({ int _level = ((4)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/journal/journald-stream.c", 565, __func__, "Failed to determine peer security context: %m"
) : -abs(_e); })
;
566 }
567
568 (void) shutdown(fd, SHUT_WRSHUT_WR);
569
570 r = sd_event_add_io(s->event, &stream->event_source, fd, EPOLLINEPOLLIN, stdout_stream_process, stream);
571 if (r < 0)
572 return log_error_errno(r, "Failed to add stream to event loop: %m")({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/journal/journald-stream.c", 572, __func__, "Failed to add stream to event loop: %m"
) : -abs(_e); })
;
573
574 r = sd_event_source_set_priority(stream->event_source, SD_EVENT_PRIORITY_NORMAL+5);
575 if (r < 0)
576 return log_error_errno(r, "Failed to adjust stdout event source priority: %m")({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/journal/journald-stream.c", 576, __func__, "Failed to adjust stdout event source priority: %m"
) : -abs(_e); })
;
577
578 stream->fd = fd;
579
580 stream->server = s;
581 LIST_PREPEND(stdout_stream, s->stdout_streams, stream)do { typeof(*(s->stdout_streams)) **_head = &(s->stdout_streams
), *_item = (stream); do { if ((__builtin_expect(!!(!(_item))
,0))) log_assert_failed_realm(LOG_REALM_SYSTEMD, ("_item"), "../src/journal/journald-stream.c"
, 581, __PRETTY_FUNCTION__); } while (0); if ((_item->stdout_stream_next
= *_head)) _item->stdout_stream_next->stdout_stream_prev
= _item; _item->stdout_stream_prev = ((void*)0); *_head =
_item; } while (0)
;
582 s->n_stdout_streams++;
583
584 if (ret)
585 *ret = stream;
586
587 stream = NULL((void*)0);
588
589 return 0;
590}
591
592static int stdout_stream_new(sd_event_source *es, int listen_fd, uint32_t revents, void *userdata) {
593 _cleanup_close___attribute__((cleanup(closep))) int fd = -1;
594 Server *s = userdata;
595 int r;
596
597 assert(s)do { if ((__builtin_expect(!!(!(s)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("s"), "../src/journal/journald-stream.c"
, 597, __PRETTY_FUNCTION__); } while (0)
;
598
599 if (revents != EPOLLINEPOLLIN) {
600 log_error("Got invalid event from epoll for stdout server fd: %"PRIx32, revents)({ int _level = (((3))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/journal/journald-stream.c", 600, __func__, "Got invalid event from epoll for stdout server fd: %"
"x", revents) : -abs(_e); })
;
601 return -EIO5;
602 }
603
604 fd = accept4(s->stdout_fd, NULL((void*)0), NULL((void*)0), SOCK_NONBLOCKSOCK_NONBLOCK|SOCK_CLOEXECSOCK_CLOEXEC);
605 if (fd < 0) {
606 if (errno(*__errno_location ()) == EAGAIN11)
607 return 0;
608
609 return log_error_errno(errno, "Failed to accept stdout connection: %m")({ int _level = ((3)), _e = (((*__errno_location ()))), _realm
= (LOG_REALM_SYSTEMD); (log_get_max_level_realm(_realm) >=
((_level) & 0x07)) ? log_internal_realm(((_realm) <<
10 | (_level)), _e, "../src/journal/journald-stream.c", 609,
__func__, "Failed to accept stdout connection: %m") : -abs(_e
); })
;
610 }
611
612 if (s->n_stdout_streams >= STDOUT_STREAMS_MAX4096) {
613 log_warning("Too many stdout streams, refusing connection.")({ int _level = (((4))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/journal/journald-stream.c", 613, __func__, "Too many stdout streams, refusing connection."
) : -abs(_e); })
;
614 return 0;
615 }
616
617 r = stdout_stream_install(s, fd, NULL((void*)0));
618 if (r < 0)
619 return r;
620
621 fd = -1;
Value stored to 'fd' is never read
622 return 0;
623}
624
625static int stdout_stream_load(StdoutStream *stream, const char *fname) {
626 _cleanup_free___attribute__((cleanup(freep))) char
627 *priority = NULL((void*)0),
628 *level_prefix = NULL((void*)0),
629 *forward_to_syslog = NULL((void*)0),
630 *forward_to_kmsg = NULL((void*)0),
631 *forward_to_console = NULL((void*)0),
632 *stream_id = NULL((void*)0);
633 int r;
634
635 assert(stream)do { if ((__builtin_expect(!!(!(stream)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("stream"), "../src/journal/journald-stream.c"
, 635, __PRETTY_FUNCTION__); } while (0)
;
636 assert(fname)do { if ((__builtin_expect(!!(!(fname)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("fname"), "../src/journal/journald-stream.c"
, 636, __PRETTY_FUNCTION__); } while (0)
;
637
638 if (!stream->state_file) {
639 stream->state_file = strappend("/run/systemd/journal/streams/", fname);
640 if (!stream->state_file)
641 return log_oom()log_oom_internal(LOG_REALM_SYSTEMD, "../src/journal/journald-stream.c"
, 641, __func__)
;
642 }
643
644 r = parse_env_file(NULL((void*)0), stream->state_file, NEWLINE"\n\r",
645 "PRIORITY", &priority,
646 "LEVEL_PREFIX", &level_prefix,
647 "FORWARD_TO_SYSLOG", &forward_to_syslog,
648 "FORWARD_TO_KMSG", &forward_to_kmsg,
649 "FORWARD_TO_CONSOLE", &forward_to_console,
650 "IDENTIFIER", &stream->identifier,
651 "UNIT", &stream->unit_id,
652 "STREAM_ID", &stream_id,
653 NULL((void*)0));
654 if (r < 0)
655 return log_error_errno(r, "Failed to read: %s", stream->state_file)({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/journal/journald-stream.c", 655, __func__, "Failed to read: %s"
, stream->state_file) : -abs(_e); })
;
656
657 if (priority) {
658 int p;
659
660 p = log_level_from_string(priority);
661 if (p >= 0)
662 stream->priority = p;
663 }
664
665 if (level_prefix) {
666 r = parse_boolean(level_prefix);
667 if (r >= 0)
668 stream->level_prefix = r;
669 }
670
671 if (forward_to_syslog) {
672 r = parse_boolean(forward_to_syslog);
673 if (r >= 0)
674 stream->forward_to_syslog = r;
675 }
676
677 if (forward_to_kmsg) {
678 r = parse_boolean(forward_to_kmsg);
679 if (r >= 0)
680 stream->forward_to_kmsg = r;
681 }
682
683 if (forward_to_console) {
684 r = parse_boolean(forward_to_console);
685 if (r >= 0)
686 stream->forward_to_console = r;
687 }
688
689 if (stream_id) {
690 sd_id128_t id;
691
692 r = sd_id128_from_string(stream_id, &id);
693 if (r >= 0)
694 xsprintf(stream->id_field, "_STREAM_ID=" SD_ID128_FORMAT_STR, SD_ID128_FORMAT_VAL(id))do { if ((__builtin_expect(!!(!(((size_t) snprintf(stream->
id_field, __extension__ (__builtin_choose_expr( !__builtin_types_compatible_p
(typeof(stream->id_field), typeof(&*(stream->id_field
))), sizeof(stream->id_field)/sizeof((stream->id_field)
[0]), ((void)0))), "_STREAM_ID=" "%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x"
, (id).bytes[0], (id).bytes[1], (id).bytes[2], (id).bytes[3],
(id).bytes[4], (id).bytes[5], (id).bytes[6], (id).bytes[7], (
id).bytes[8], (id).bytes[9], (id).bytes[10], (id).bytes[11], (
id).bytes[12], (id).bytes[13], (id).bytes[14], (id).bytes[15]
) < (__extension__ (__builtin_choose_expr( !__builtin_types_compatible_p
(typeof(stream->id_field), typeof(&*(stream->id_field
))), sizeof(stream->id_field)/sizeof((stream->id_field)
[0]), ((void)0))))))),0))) log_assert_failed_realm(LOG_REALM_SYSTEMD
, ("xsprintf: " "stream->id_field" "[] must be big enough"
), "../src/journal/journald-stream.c", 694, __PRETTY_FUNCTION__
); } while (0)
;
695 }
696
697 return 0;
698}
699
700static int stdout_stream_restore(Server *s, const char *fname, int fd) {
701 StdoutStream *stream;
702 int r;
703
704 assert(s)do { if ((__builtin_expect(!!(!(s)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("s"), "../src/journal/journald-stream.c"
, 704, __PRETTY_FUNCTION__); } while (0)
;
705 assert(fname)do { if ((__builtin_expect(!!(!(fname)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("fname"), "../src/journal/journald-stream.c"
, 705, __PRETTY_FUNCTION__); } while (0)
;
706 assert(fd >= 0)do { if ((__builtin_expect(!!(!(fd >= 0)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("fd >= 0"), "../src/journal/journald-stream.c"
, 706, __PRETTY_FUNCTION__); } while (0)
;
707
708 if (s->n_stdout_streams >= STDOUT_STREAMS_MAX4096) {
709 log_warning("Too many stdout streams, refusing restoring of stream.")({ int _level = (((4))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/journal/journald-stream.c", 709, __func__, "Too many stdout streams, refusing restoring of stream."
) : -abs(_e); })
;
710 return -ENOBUFS105;
711 }
712
713 r = stdout_stream_install(s, fd, &stream);
714 if (r < 0)
715 return r;
716
717 stream->state = STDOUT_STREAM_RUNNING;
718 stream->fdstore = true1;
719
720 /* Ignore all parsing errors */
721 (void) stdout_stream_load(stream, fname);
722
723 return 0;
724}
725
726int server_restore_streams(Server *s, FDSet *fds) {
727 _cleanup_closedir___attribute__((cleanup(closedirp))) DIR *d = NULL((void*)0);
728 struct dirent *de;
729 int r;
730
731 d = opendir("/run/systemd/journal/streams");
732 if (!d) {
733 if (errno(*__errno_location ()) == ENOENT2)
734 return 0;
735
736 return log_warning_errno(errno, "Failed to enumerate /run/systemd/journal/streams: %m")({ int _level = ((4)), _e = (((*__errno_location ()))), _realm
= (LOG_REALM_SYSTEMD); (log_get_max_level_realm(_realm) >=
((_level) & 0x07)) ? log_internal_realm(((_realm) <<
10 | (_level)), _e, "../src/journal/journald-stream.c", 736,
__func__, "Failed to enumerate /run/systemd/journal/streams: %m"
) : -abs(_e); })
;
737 }
738
739 FOREACH_DIRENT(de, d, goto fail)for ((*__errno_location ()) = 0, de = readdir(d);; (*__errno_location
()) = 0, de = readdir(d)) if (!de) { if ((*__errno_location (
)) > 0) { goto fail; } break; } else if (hidden_or_backup_file
((de)->d_name)) continue; else
{
740 unsigned long st_dev, st_ino;
741 bool_Bool found = false0;
742 Iterator i;
743 int fd;
744
745 if (sscanf(de->d_name, "%lu:%lu", &st_dev, &st_ino) != 2)
746 continue;
747
748 FDSET_FOREACH(fd, fds, i)for ((i) = ((Iterator) { .idx = ((2147483647 *2U +1U) - 1), .
next_key = ((void*)0) }), (fd) = fdset_iterate((fds), &(i
)); (fd) >= 0; (fd) = fdset_iterate((fds), &(i)))
{
749 struct stat st;
750
751 if (fstat(fd, &st) < 0)
752 return log_error_errno(errno, "Failed to stat %s: %m", de->d_name)({ int _level = ((3)), _e = (((*__errno_location ()))), _realm
= (LOG_REALM_SYSTEMD); (log_get_max_level_realm(_realm) >=
((_level) & 0x07)) ? log_internal_realm(((_realm) <<
10 | (_level)), _e, "../src/journal/journald-stream.c", 752,
__func__, "Failed to stat %s: %m", de->d_name) : -abs(_e)
; })
;
753
754 if (S_ISSOCK(st.st_mode)((((st.st_mode)) & 0170000) == (0140000)) && st.st_dev == st_dev && st.st_ino == st_ino) {
755 found = true1;
756 break;
757 }
758 }
759
760 if (!found) {
761 /* No file descriptor? Then let's delete the state file */
762 log_debug("Cannot restore stream file %s", de->d_name)({ int _level = (((7))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/journal/journald-stream.c", 762, __func__, "Cannot restore stream file %s"
, de->d_name) : -abs(_e); })
;
763 if (unlinkat(dirfd(d), de->d_name, 0) < 0)
764 log_warning_errno(errno, "Failed to remove /run/systemd/journal/streams/%s: %m",({ int _level = ((4)), _e = (((*__errno_location ()))), _realm
= (LOG_REALM_SYSTEMD); (log_get_max_level_realm(_realm) >=
((_level) & 0x07)) ? log_internal_realm(((_realm) <<
10 | (_level)), _e, "../src/journal/journald-stream.c", 765,
__func__, "Failed to remove /run/systemd/journal/streams/%s: %m"
, de->d_name) : -abs(_e); })
765 de->d_name)({ int _level = ((4)), _e = (((*__errno_location ()))), _realm
= (LOG_REALM_SYSTEMD); (log_get_max_level_realm(_realm) >=
((_level) & 0x07)) ? log_internal_realm(((_realm) <<
10 | (_level)), _e, "../src/journal/journald-stream.c", 765,
__func__, "Failed to remove /run/systemd/journal/streams/%s: %m"
, de->d_name) : -abs(_e); })
;
766 continue;
767 }
768
769 fdset_remove(fds, fd);
770
771 r = stdout_stream_restore(s, de->d_name, fd);
772 if (r < 0)
773 safe_close(fd);
774 }
775
776 return 0;
777
778fail:
779 return log_error_errno(errno, "Failed to read streams directory: %m")({ int _level = ((3)), _e = (((*__errno_location ()))), _realm
= (LOG_REALM_SYSTEMD); (log_get_max_level_realm(_realm) >=
((_level) & 0x07)) ? log_internal_realm(((_realm) <<
10 | (_level)), _e, "../src/journal/journald-stream.c", 779,
__func__, "Failed to read streams directory: %m") : -abs(_e)
; })
;
780}
781
782int server_open_stdout_socket(Server *s) {
783 static const union sockaddr_union sa = {
784 .un.sun_family = AF_UNIX1,
785 .un.sun_path = "/run/systemd/journal/stdout",
786 };
787 int r;
788
789 assert(s)do { if ((__builtin_expect(!!(!(s)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("s"), "../src/journal/journald-stream.c"
, 789, __PRETTY_FUNCTION__); } while (0)
;
790
791 if (s->stdout_fd < 0) {
792 s->stdout_fd = socket(AF_UNIX1, SOCK_STREAMSOCK_STREAM|SOCK_CLOEXECSOCK_CLOEXEC|SOCK_NONBLOCKSOCK_NONBLOCK, 0);
793 if (s->stdout_fd < 0)
794 return log_error_errno(errno, "socket() failed: %m")({ int _level = ((3)), _e = (((*__errno_location ()))), _realm
= (LOG_REALM_SYSTEMD); (log_get_max_level_realm(_realm) >=
((_level) & 0x07)) ? log_internal_realm(((_realm) <<
10 | (_level)), _e, "../src/journal/journald-stream.c", 794,
__func__, "socket() failed: %m") : -abs(_e); })
;
795
796 (void) unlink(sa.un.sun_path);
797
798 r = bind(s->stdout_fd, &sa.sa, SOCKADDR_UN_LEN(sa.un)({ const struct sockaddr_un *_sa = &(sa.un); do { if ((__builtin_expect
(!!(!(_sa->sun_family == 1)),0))) log_assert_failed_realm(
LOG_REALM_SYSTEMD, ("_sa->sun_family == AF_UNIX"), "../src/journal/journald-stream.c"
, 798, __PRETTY_FUNCTION__); } while (0); __builtin_offsetof(
struct sockaddr_un, sun_path) + (_sa->sun_path[0] == 0 ? 1
+ strnlen(_sa->sun_path+1, sizeof(_sa->sun_path)-1) : strnlen
(_sa->sun_path, sizeof(_sa->sun_path))); })
);
799 if (r < 0)
800 return log_error_errno(errno, "bind(%s) failed: %m", sa.un.sun_path)({ int _level = ((3)), _e = (((*__errno_location ()))), _realm
= (LOG_REALM_SYSTEMD); (log_get_max_level_realm(_realm) >=
((_level) & 0x07)) ? log_internal_realm(((_realm) <<
10 | (_level)), _e, "../src/journal/journald-stream.c", 800,
__func__, "bind(%s) failed: %m", sa.un.sun_path) : -abs(_e);
})
;
801
802 (void) chmod(sa.un.sun_path, 0666);
803
804 if (listen(s->stdout_fd, SOMAXCONN4096) < 0)
805 return log_error_errno(errno, "listen(%s) failed: %m", sa.un.sun_path)({ int _level = ((3)), _e = (((*__errno_location ()))), _realm
= (LOG_REALM_SYSTEMD); (log_get_max_level_realm(_realm) >=
((_level) & 0x07)) ? log_internal_realm(((_realm) <<
10 | (_level)), _e, "../src/journal/journald-stream.c", 805,
__func__, "listen(%s) failed: %m", sa.un.sun_path) : -abs(_e
); })
;
806 } else
807 fd_nonblock(s->stdout_fd, 1);
808
809 r = sd_event_add_io(s->event, &s->stdout_event_source, s->stdout_fd, EPOLLINEPOLLIN, stdout_stream_new, s);
810 if (r < 0)
811 return log_error_errno(r, "Failed to add stdout server fd to event source: %m")({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/journal/journald-stream.c", 811, __func__, "Failed to add stdout server fd to event source: %m"
) : -abs(_e); })
;
812
813 r = sd_event_source_set_priority(s->stdout_event_source, SD_EVENT_PRIORITY_NORMAL+5);
814 if (r < 0)
815 return log_error_errno(r, "Failed to adjust priority of stdout server event source: %m")({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/journal/journald-stream.c", 815, __func__, "Failed to adjust priority of stdout server event source: %m"
) : -abs(_e); })
;
816
817 return 0;
818}
819
820void stdout_stream_send_notify(StdoutStream *s) {
821 struct iovec iovec = {
822 .iov_base = (char*) "FDSTORE=1",
823 .iov_len = STRLEN("FDSTORE=1")(sizeof("""FDSTORE=1""") - 1),
824 };
825 struct msghdr msghdr = {
826 .msg_iov = &iovec,
827 .msg_iovlen = 1,
828 };
829 struct cmsghdr *cmsg;
830 ssize_t l;
831
832 assert(s)do { if ((__builtin_expect(!!(!(s)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("s"), "../src/journal/journald-stream.c"
, 832, __PRETTY_FUNCTION__); } while (0)
;
833 assert(!s->fdstore)do { if ((__builtin_expect(!!(!(!s->fdstore)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("!s->fdstore"), "../src/journal/journald-stream.c"
, 833, __PRETTY_FUNCTION__); } while (0)
;
834 assert(s->in_notify_queue)do { if ((__builtin_expect(!!(!(s->in_notify_queue)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("s->in_notify_queue"), "../src/journal/journald-stream.c"
, 834, __PRETTY_FUNCTION__); } while (0)
;
835 assert(s->server)do { if ((__builtin_expect(!!(!(s->server)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("s->server"), "../src/journal/journald-stream.c"
, 835, __PRETTY_FUNCTION__); } while (0)
;
836 assert(s->server->notify_fd >= 0)do { if ((__builtin_expect(!!(!(s->server->notify_fd >=
0)),0))) log_assert_failed_realm(LOG_REALM_SYSTEMD, ("s->server->notify_fd >= 0"
), "../src/journal/journald-stream.c", 836, __PRETTY_FUNCTION__
); } while (0)
;
837
838 /* Store the connection fd in PID 1, so that we get it passed
839 * in again on next start */
840
841 msghdr.msg_controllen = CMSG_SPACE(sizeof(int))((((sizeof(int)) + sizeof (size_t) - 1) & (size_t) ~(sizeof
(size_t) - 1)) + (((sizeof (struct cmsghdr)) + sizeof (size_t
) - 1) & (size_t) ~(sizeof (size_t) - 1)))
;
842 msghdr.msg_control = alloca0(msghdr.msg_controllen)({ char *_new_; size_t _len_ = msghdr.msg_controllen; _new_ =
__builtin_alloca (_len_); (void *) memset(_new_, 0, _len_); }
)
;
843
844 cmsg = CMSG_FIRSTHDR(&msghdr)((size_t) (&msghdr)->msg_controllen >= sizeof (struct
cmsghdr) ? (struct cmsghdr *) (&msghdr)->msg_control :
(struct cmsghdr *) 0)
;
845 cmsg->cmsg_level = SOL_SOCKET1;
846 cmsg->cmsg_type = SCM_RIGHTSSCM_RIGHTS;
847 cmsg->cmsg_len = CMSG_LEN(sizeof(int))((((sizeof (struct cmsghdr)) + sizeof (size_t) - 1) & (size_t
) ~(sizeof (size_t) - 1)) + (sizeof(int)))
;
848
849 memcpy(CMSG_DATA(cmsg)((cmsg)->__cmsg_data), &s->fd, sizeof(int));
850
851 l = sendmsg(s->server->notify_fd, &msghdr, MSG_DONTWAITMSG_DONTWAIT|MSG_NOSIGNALMSG_NOSIGNAL);
852 if (l < 0) {
853 if (errno(*__errno_location ()) == EAGAIN11)
854 return;
855
856 log_error_errno(errno, "Failed to send stream file descriptor to service manager: %m")({ int _level = ((3)), _e = (((*__errno_location ()))), _realm
= (LOG_REALM_SYSTEMD); (log_get_max_level_realm(_realm) >=
((_level) & 0x07)) ? log_internal_realm(((_realm) <<
10 | (_level)), _e, "../src/journal/journald-stream.c", 856,
__func__, "Failed to send stream file descriptor to service manager: %m"
) : -abs(_e); })
;
857 } else {
858 log_debug("Successfully sent stream file descriptor to service manager.")({ int _level = (((7))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/journal/journald-stream.c", 858, __func__, "Successfully sent stream file descriptor to service manager."
) : -abs(_e); })
;
859 s->fdstore = 1;
860 }
861
862 LIST_REMOVE(stdout_stream_notify_queue, s->server->stdout_streams_notify_queue, s)do { typeof(*(s->server->stdout_streams_notify_queue)) *
*_head = &(s->server->stdout_streams_notify_queue),
*_item = (s); do { if ((__builtin_expect(!!(!(_item)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("_item"), "../src/journal/journald-stream.c"
, 862, __PRETTY_FUNCTION__); } while (0); if (_item->stdout_stream_notify_queue_next
) _item->stdout_stream_notify_queue_next->stdout_stream_notify_queue_prev
= _item->stdout_stream_notify_queue_prev; if (_item->stdout_stream_notify_queue_prev
) _item->stdout_stream_notify_queue_prev->stdout_stream_notify_queue_next
= _item->stdout_stream_notify_queue_next; else { do { if (
(__builtin_expect(!!(!(*_head == _item)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("*_head == _item"), "../src/journal/journald-stream.c"
, 862, __PRETTY_FUNCTION__); } while (0); *_head = _item->
stdout_stream_notify_queue_next; } _item->stdout_stream_notify_queue_next
= _item->stdout_stream_notify_queue_prev = ((void*)0); } while
(0)
;
863 s->in_notify_queue = false0;
864
865}