]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/journal/journald-stream.c
util-lib: split string parsing related calls from util.[ch] into parse-util.[ch]
[thirdparty/systemd.git] / src / journal / journald-stream.c
CommitLineData
a45b9fca
LP
1/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
2
3/***
4 This file is part of systemd.
5
6 Copyright 2011 Lennart Poettering
7
8 systemd is free software; you can redistribute it and/or modify it
9 under the terms of the GNU Lesser General Public License as published by
10 the Free Software Foundation; either version 2.1 of the License, or
11 (at your option) any later version.
12
13 systemd is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 Lesser General Public License for more details.
17
18 You should have received a copy of the GNU Lesser General Public License
19 along with systemd; If not, see <http://www.gnu.org/licenses/>.
20***/
21
4871690d 22#include <stddef.h>
07630cea 23#include <unistd.h>
a45b9fca
LP
24
25#ifdef HAVE_SELINUX
26#include <selinux/selinux.h>
27#endif
28
13790add 29#include "sd-daemon.h"
4f5dd394
LP
30#include "sd-event.h"
31
32#include "escape.h"
3ffd4af2 33#include "fd-util.h"
13790add 34#include "fileio.h"
4f5dd394
LP
35#include "journald-console.h"
36#include "journald-kmsg.h"
d025f1e4 37#include "journald-server.h"
3ffd4af2 38#include "journald-stream.h"
a45b9fca 39#include "journald-syslog.h"
40b71e89 40#include "journald-wall.h"
4f5dd394 41#include "mkdir.h"
6bedfcbb 42#include "parse-util.h"
4f5dd394
LP
43#include "selinux-util.h"
44#include "socket-util.h"
07630cea 45#include "string-util.h"
a45b9fca
LP
46
47#define STDOUT_STREAMS_MAX 4096
48
49typedef enum StdoutStreamState {
50 STDOUT_STREAM_IDENTIFIER,
51 STDOUT_STREAM_UNIT_ID,
52 STDOUT_STREAM_PRIORITY,
53 STDOUT_STREAM_LEVEL_PREFIX,
54 STDOUT_STREAM_FORWARD_TO_SYSLOG,
55 STDOUT_STREAM_FORWARD_TO_KMSG,
56 STDOUT_STREAM_FORWARD_TO_CONSOLE,
57 STDOUT_STREAM_RUNNING
58} StdoutStreamState;
59
60struct StdoutStream {
61 Server *server;
62 StdoutStreamState state;
63
64 int fd;
65
66 struct ucred ucred;
2de56f70 67 char *label;
a45b9fca
LP
68 char *identifier;
69 char *unit_id;
70 int priority;
71 bool level_prefix:1;
72 bool forward_to_syslog:1;
73 bool forward_to_kmsg:1;
74 bool forward_to_console:1;
75
13790add
LP
76 bool fdstore:1;
77
a45b9fca
LP
78 char buffer[LINE_MAX+1];
79 size_t length;
80
f9a810be
LP
81 sd_event_source *event_source;
82
13790add
LP
83 char *state_file;
84
a45b9fca
LP
85 LIST_FIELDS(StdoutStream, stdout_stream);
86};
87
13790add
LP
88void stdout_stream_free(StdoutStream *s) {
89 if (!s)
90 return;
91
92 if (s->server) {
93 assert(s->server->n_stdout_streams > 0);
94 s->server->n_stdout_streams --;
95 LIST_REMOVE(stdout_stream, s->server->stdout_streams, s);
96 }
97
98 if (s->event_source) {
99 sd_event_source_set_enabled(s->event_source, SD_EVENT_OFF);
100 s->event_source = sd_event_source_unref(s->event_source);
101 }
102
103 safe_close(s->fd);
2de56f70 104 free(s->label);
13790add
LP
105 free(s->identifier);
106 free(s->unit_id);
107 free(s->state_file);
108
109 free(s);
110}
111
112DEFINE_TRIVIAL_CLEANUP_FUNC(StdoutStream*, stdout_stream_free);
113
114static void stdout_stream_destroy(StdoutStream *s) {
115 if (!s)
116 return;
117
118 if (s->state_file)
119 unlink(s->state_file);
120
121 stdout_stream_free(s);
122}
123
124static int stdout_stream_save(StdoutStream *s) {
125 _cleanup_free_ char *temp_path = NULL;
126 _cleanup_fclose_ FILE *f = NULL;
127 int r;
128
129 assert(s);
130
131 if (s->state != STDOUT_STREAM_RUNNING)
132 return 0;
133
134 if (!s->state_file) {
135 struct stat st;
136
137 r = fstat(s->fd, &st);
138 if (r < 0)
139 return log_warning_errno(errno, "Failed to stat connected stream: %m");
140
141 /* We use device and inode numbers as identifier for the stream */
142 if (asprintf(&s->state_file, "/run/systemd/journal/streams/%lu:%lu", (unsigned long) st.st_dev, (unsigned long) st.st_ino) < 0)
143 return log_oom();
144 }
145
146 mkdir_p("/run/systemd/journal/streams", 0755);
147
148 r = fopen_temporary(s->state_file, &f, &temp_path);
149 if (r < 0)
dacd6cee 150 goto fail;
13790add
LP
151
152 fprintf(f,
153 "# This is private data. Do not parse\n"
154 "PRIORITY=%i\n"
155 "LEVEL_PREFIX=%i\n"
156 "FORWARD_TO_SYSLOG=%i\n"
157 "FORWARD_TO_KMSG=%i\n"
158 "FORWARD_TO_CONSOLE=%i\n",
159 s->priority,
160 s->level_prefix,
161 s->forward_to_syslog,
162 s->forward_to_kmsg,
163 s->forward_to_console);
164
165 if (!isempty(s->identifier)) {
166 _cleanup_free_ char *escaped;
167
168 escaped = cescape(s->identifier);
169 if (!escaped) {
170 r = -ENOMEM;
dacd6cee 171 goto fail;
13790add
LP
172 }
173
174 fprintf(f, "IDENTIFIER=%s\n", escaped);
175 }
176
177 if (!isempty(s->unit_id)) {
178 _cleanup_free_ char *escaped;
179
180 escaped = cescape(s->unit_id);
181 if (!escaped) {
182 r = -ENOMEM;
dacd6cee 183 goto fail;
13790add
LP
184 }
185
186 fprintf(f, "UNIT=%s\n", escaped);
187 }
188
189 r = fflush_and_check(f);
190 if (r < 0)
dacd6cee 191 goto fail;
13790add
LP
192
193 if (rename(temp_path, s->state_file) < 0) {
194 r = -errno;
dacd6cee 195 goto fail;
13790add
LP
196 }
197
13790add
LP
198 /* Store the connection fd in PID 1, so that we get it passed
199 * in again on next start */
200 if (!s->fdstore) {
201 sd_pid_notify_with_fds(0, false, "FDSTORE=1", &s->fd, 1);
202 s->fdstore = true;
203 }
204
dacd6cee 205 return 0;
13790add 206
dacd6cee
LP
207fail:
208 (void) unlink(s->state_file);
209
210 if (temp_path)
211 (void) unlink(temp_path);
13790add 212
dacd6cee 213 return log_error_errno(r, "Failed to save stream data %s: %m", s->state_file);
13790add
LP
214}
215
a45b9fca
LP
216static int stdout_stream_log(StdoutStream *s, const char *p) {
217 struct iovec iovec[N_IOVEC_META_FIELDS + 5];
a45b9fca 218 int priority;
e3bfb7be 219 char syslog_priority[] = "PRIORITY=\0";
5ffa8c81 220 char syslog_facility[sizeof("SYSLOG_FACILITY=")-1 + DECIMAL_STR_MAX(int) + 1];
e3bfb7be
ZJS
221 _cleanup_free_ char *message = NULL, *syslog_identifier = NULL;
222 unsigned n = 0;
2de56f70 223 size_t label_len;
a45b9fca
LP
224
225 assert(s);
226 assert(p);
227
228 if (isempty(p))
229 return 0;
230
231 priority = s->priority;
232
233 if (s->level_prefix)
e3bfb7be 234 syslog_parse_priority(&p, &priority, false);
a45b9fca
LP
235
236 if (s->forward_to_syslog || s->server->forward_to_syslog)
237 server_forward_syslog(s->server, syslog_fixup_facility(priority), s->identifier, p, &s->ucred, NULL);
238
239 if (s->forward_to_kmsg || s->server->forward_to_kmsg)
240 server_forward_kmsg(s->server, priority, s->identifier, p, &s->ucred);
241
242 if (s->forward_to_console || s->server->forward_to_console)
243 server_forward_console(s->server, priority, s->identifier, p, &s->ucred);
244
40b71e89
ST
245 if (s->server->forward_to_wall)
246 server_forward_wall(s->server, priority, s->identifier, p, &s->ucred);
247
a45b9fca
LP
248 IOVEC_SET_STRING(iovec[n++], "_TRANSPORT=stdout");
249
e3bfb7be
ZJS
250 syslog_priority[strlen("PRIORITY=")] = '0' + LOG_PRI(priority);
251 IOVEC_SET_STRING(iovec[n++], syslog_priority);
a45b9fca 252
e3bfb7be 253 if (priority & LOG_FACMASK) {
5ffa8c81 254 xsprintf(syslog_facility, "SYSLOG_FACILITY=%i", LOG_FAC(priority));
e3bfb7be
ZJS
255 IOVEC_SET_STRING(iovec[n++], syslog_facility);
256 }
a45b9fca
LP
257
258 if (s->identifier) {
259 syslog_identifier = strappend("SYSLOG_IDENTIFIER=", s->identifier);
260 if (syslog_identifier)
261 IOVEC_SET_STRING(iovec[n++], syslog_identifier);
262 }
263
264 message = strappend("MESSAGE=", p);
265 if (message)
266 IOVEC_SET_STRING(iovec[n++], message);
267
2de56f70
ZJS
268 label_len = s->label ? strlen(s->label) : 0;
269 server_dispatch_message(s->server, iovec, n, ELEMENTSOF(iovec), &s->ucred, NULL, s->label, label_len, s->unit_id, priority, 0);
a45b9fca
LP
270 return 0;
271}
272
273static int stdout_stream_line(StdoutStream *s, char *p) {
274 int r;
275
276 assert(s);
277 assert(p);
278
279 p = strstrip(p);
280
281 switch (s->state) {
282
283 case STDOUT_STREAM_IDENTIFIER:
284 if (isempty(p))
285 s->identifier = NULL;
286 else {
287 s->identifier = strdup(p);
288 if (!s->identifier)
289 return log_oom();
290 }
291
292 s->state = STDOUT_STREAM_UNIT_ID;
293 return 0;
294
295 case STDOUT_STREAM_UNIT_ID:
296 if (s->ucred.uid == 0) {
297 if (isempty(p))
298 s->unit_id = NULL;
299 else {
300 s->unit_id = strdup(p);
301 if (!s->unit_id)
302 return log_oom();
303 }
304 }
305
306 s->state = STDOUT_STREAM_PRIORITY;
307 return 0;
308
309 case STDOUT_STREAM_PRIORITY:
310 r = safe_atoi(p, &s->priority);
41891700 311 if (r < 0 || s->priority < 0 || s->priority > 999) {
a45b9fca
LP
312 log_warning("Failed to parse log priority line.");
313 return -EINVAL;
314 }
315
316 s->state = STDOUT_STREAM_LEVEL_PREFIX;
317 return 0;
318
319 case STDOUT_STREAM_LEVEL_PREFIX:
320 r = parse_boolean(p);
321 if (r < 0) {
322 log_warning("Failed to parse level prefix line.");
323 return -EINVAL;
324 }
325
326 s->level_prefix = !!r;
327 s->state = STDOUT_STREAM_FORWARD_TO_SYSLOG;
328 return 0;
329
330 case STDOUT_STREAM_FORWARD_TO_SYSLOG:
331 r = parse_boolean(p);
332 if (r < 0) {
333 log_warning("Failed to parse forward to syslog line.");
334 return -EINVAL;
335 }
336
337 s->forward_to_syslog = !!r;
338 s->state = STDOUT_STREAM_FORWARD_TO_KMSG;
339 return 0;
340
341 case STDOUT_STREAM_FORWARD_TO_KMSG:
342 r = parse_boolean(p);
343 if (r < 0) {
344 log_warning("Failed to parse copy to kmsg line.");
345 return -EINVAL;
346 }
347
348 s->forward_to_kmsg = !!r;
349 s->state = STDOUT_STREAM_FORWARD_TO_CONSOLE;
350 return 0;
351
352 case STDOUT_STREAM_FORWARD_TO_CONSOLE:
353 r = parse_boolean(p);
354 if (r < 0) {
355 log_warning("Failed to parse copy to console line.");
356 return -EINVAL;
357 }
358
359 s->forward_to_console = !!r;
360 s->state = STDOUT_STREAM_RUNNING;
13790add
LP
361
362 /* Try to save the stream, so that journald can be restarted and we can recover */
363 (void) stdout_stream_save(s);
a45b9fca
LP
364 return 0;
365
366 case STDOUT_STREAM_RUNNING:
367 return stdout_stream_log(s, p);
368 }
369
370 assert_not_reached("Unknown stream state");
371}
372
373static int stdout_stream_scan(StdoutStream *s, bool force_flush) {
374 char *p;
375 size_t remaining;
376 int r;
377
378 assert(s);
379
380 p = s->buffer;
381 remaining = s->length;
382 for (;;) {
383 char *end;
384 size_t skip;
385
386 end = memchr(p, '\n', remaining);
387 if (end)
388 skip = end - p + 1;
389 else if (remaining >= sizeof(s->buffer) - 1) {
390 end = p + sizeof(s->buffer) - 1;
391 skip = remaining;
392 } else
393 break;
394
395 *end = 0;
396
397 r = stdout_stream_line(s, p);
398 if (r < 0)
399 return r;
400
401 remaining -= skip;
402 p += skip;
403 }
404
405 if (force_flush && remaining > 0) {
406 p[remaining] = 0;
407 r = stdout_stream_line(s, p);
408 if (r < 0)
409 return r;
410
411 p += remaining;
412 remaining = 0;
413 }
414
415 if (p > s->buffer) {
416 memmove(s->buffer, p, remaining);
417 s->length = remaining;
418 }
419
420 return 0;
421}
422
f9a810be
LP
423static int stdout_stream_process(sd_event_source *es, int fd, uint32_t revents, void *userdata) {
424 StdoutStream *s = userdata;
a45b9fca
LP
425 ssize_t l;
426 int r;
427
428 assert(s);
429
f9a810be
LP
430 if ((revents|EPOLLIN|EPOLLHUP) != (EPOLLIN|EPOLLHUP)) {
431 log_error("Got invalid event from epoll for stdout stream: %"PRIx32, revents);
91bf3b3e 432 goto terminate;
f9a810be
LP
433 }
434
a45b9fca
LP
435 l = read(s->fd, s->buffer+s->length, sizeof(s->buffer)-1-s->length);
436 if (l < 0) {
437
438 if (errno == EAGAIN)
439 return 0;
440
56f64d95 441 log_warning_errno(errno, "Failed to read from stream: %m");
91bf3b3e 442 goto terminate;
a45b9fca
LP
443 }
444
445 if (l == 0) {
7b77ed8c 446 stdout_stream_scan(s, true);
91bf3b3e 447 goto terminate;
a45b9fca
LP
448 }
449
450 s->length += l;
451 r = stdout_stream_scan(s, false);
452 if (r < 0)
91bf3b3e 453 goto terminate;
a45b9fca
LP
454
455 return 1;
456
91bf3b3e 457terminate:
13790add 458 stdout_stream_destroy(s);
f9a810be 459 return 0;
a45b9fca
LP
460}
461
13790add
LP
462static int stdout_stream_install(Server *s, int fd, StdoutStream **ret) {
463 _cleanup_(stdout_stream_freep) StdoutStream *stream = NULL;
464 int r;
465
a45b9fca 466 assert(s);
13790add 467 assert(fd >= 0);
a45b9fca 468
13790add
LP
469 stream = new0(StdoutStream, 1);
470 if (!stream)
471 return log_oom();
a45b9fca 472
13790add
LP
473 stream->fd = -1;
474 stream->priority = LOG_INFO;
a45b9fca 475
13790add
LP
476 r = getpeercred(fd, &stream->ucred);
477 if (r < 0)
478 return log_error_errno(r, "Failed to determine peer credentials: %m");
a45b9fca 479
13790add 480 if (mac_selinux_use()) {
2de56f70
ZJS
481 r = getpeersec(fd, &stream->label);
482 if (r < 0 && r != -EOPNOTSUPP)
483 (void) log_warning_errno(r, "Failed to determine peer security context: %m");
13790add 484 }
a45b9fca 485
13790add
LP
486 (void) shutdown(fd, SHUT_WR);
487
488 r = sd_event_add_io(s->event, &stream->event_source, fd, EPOLLIN, stdout_stream_process, stream);
489 if (r < 0)
490 return log_error_errno(r, "Failed to add stream to event loop: %m");
491
492 r = sd_event_source_set_priority(stream->event_source, SD_EVENT_PRIORITY_NORMAL+5);
493 if (r < 0)
494 return log_error_errno(r, "Failed to adjust stdout event source priority: %m");
495
496 stream->fd = fd;
497
498 stream->server = s;
499 LIST_PREPEND(stdout_stream, s->stdout_streams, stream);
500 s->n_stdout_streams ++;
501
502 if (ret)
503 *ret = stream;
504
505 stream = NULL;
506
507 return 0;
a45b9fca
LP
508}
509
f9a810be 510static int stdout_stream_new(sd_event_source *es, int listen_fd, uint32_t revents, void *userdata) {
13790add 511 _cleanup_close_ int fd = -1;
f9a810be 512 Server *s = userdata;
13790add 513 int r;
a45b9fca
LP
514
515 assert(s);
516
f9a810be
LP
517 if (revents != EPOLLIN) {
518 log_error("Got invalid event from epoll for stdout server fd: %"PRIx32, revents);
519 return -EIO;
520 }
521
a45b9fca
LP
522 fd = accept4(s->stdout_fd, NULL, NULL, SOCK_NONBLOCK|SOCK_CLOEXEC);
523 if (fd < 0) {
524 if (errno == EAGAIN)
525 return 0;
526
56f64d95 527 log_error_errno(errno, "Failed to accept stdout connection: %m");
a45b9fca
LP
528 return -errno;
529 }
530
531 if (s->n_stdout_streams >= STDOUT_STREAMS_MAX) {
532 log_warning("Too many stdout streams, refusing connection.");
a45b9fca
LP
533 return 0;
534 }
535
13790add
LP
536 r = stdout_stream_install(s, fd, NULL);
537 if (r < 0)
538 return r;
539
540 fd = -1;
541 return 0;
542}
543
544static int stdout_stream_load(StdoutStream *stream, const char *fname) {
545 _cleanup_free_ char
546 *priority = NULL,
547 *level_prefix = NULL,
548 *forward_to_syslog = NULL,
549 *forward_to_kmsg = NULL,
550 *forward_to_console = NULL;
551 int r;
552
553 assert(stream);
554 assert(fname);
555
556 if (!stream->state_file) {
557 stream->state_file = strappend("/run/systemd/journal/streams/", fname);
558 if (!stream->state_file)
559 return log_oom();
a45b9fca
LP
560 }
561
13790add
LP
562 r = parse_env_file(stream->state_file, NEWLINE,
563 "PRIORITY", &priority,
564 "LEVEL_PREFIX", &level_prefix,
565 "FORWARD_TO_SYSLOG", &forward_to_syslog,
566 "FORWARD_TO_KMSG", &forward_to_kmsg,
567 "FORWARD_TO_CONSOLE", &forward_to_console,
568 "IDENTIFIER", &stream->identifier,
569 "UNIT", &stream->unit_id,
570 NULL);
571 if (r < 0)
572 return log_error_errno(r, "Failed to read: %s", stream->state_file);
a45b9fca 573
13790add
LP
574 if (priority) {
575 int p;
576
577 p = log_level_from_string(priority);
578 if (p >= 0)
579 stream->priority = p;
a45b9fca
LP
580 }
581
13790add
LP
582 if (level_prefix) {
583 r = parse_boolean(level_prefix);
584 if (r >= 0)
585 stream->level_prefix = r;
d682b3a7 586 }
a45b9fca 587
13790add
LP
588 if (forward_to_syslog) {
589 r = parse_boolean(forward_to_syslog);
590 if (r >= 0)
591 stream->forward_to_syslog = r;
a45b9fca
LP
592 }
593
13790add
LP
594 if (forward_to_kmsg) {
595 r = parse_boolean(forward_to_kmsg);
596 if (r >= 0)
597 stream->forward_to_kmsg = r;
f9a810be
LP
598 }
599
13790add
LP
600 if (forward_to_console) {
601 r = parse_boolean(forward_to_console);
602 if (r >= 0)
603 stream->forward_to_console = r;
a45b9fca
LP
604 }
605
13790add
LP
606 return 0;
607}
608
609static int stdout_stream_restore(Server *s, const char *fname, int fd) {
610 StdoutStream *stream;
611 int r;
612
613 assert(s);
614 assert(fname);
615 assert(fd >= 0);
616
617 if (s->n_stdout_streams >= STDOUT_STREAMS_MAX) {
618 log_warning("Too many stdout streams, refusing restoring of stream.");
619 return -ENOBUFS;
620 }
621
622 r = stdout_stream_install(s, fd, &stream);
623 if (r < 0)
624 return r;
625
626 stream->state = STDOUT_STREAM_RUNNING;
627 stream->fdstore = true;
628
629 /* Ignore all parsing errors */
630 (void) stdout_stream_load(stream, fname);
a45b9fca
LP
631
632 return 0;
13790add
LP
633}
634
15d91bff 635int server_restore_streams(Server *s, FDSet *fds) {
13790add
LP
636 _cleanup_closedir_ DIR *d = NULL;
637 struct dirent *de;
638 int r;
639
640 d = opendir("/run/systemd/journal/streams");
641 if (!d) {
642 if (errno == ENOENT)
643 return 0;
644
645 return log_warning_errno(errno, "Failed to enumerate /run/systemd/journal/streams: %m");
646 }
647
648 FOREACH_DIRENT(de, d, goto fail) {
649 unsigned long st_dev, st_ino;
650 bool found = false;
651 Iterator i;
652 int fd;
653
654 if (sscanf(de->d_name, "%lu:%lu", &st_dev, &st_ino) != 2)
655 continue;
656
657 FDSET_FOREACH(fd, fds, i) {
658 struct stat st;
659
660 if (fstat(fd, &st) < 0)
661 return log_error_errno(errno, "Failed to stat %s: %m", de->d_name);
662
663 if (S_ISSOCK(st.st_mode) && st.st_dev == st_dev && st.st_ino == st_ino) {
664 found = true;
665 break;
666 }
667 }
668
669 if (!found) {
670 /* No file descriptor? Then let's delete the state file */
671 log_debug("Cannot restore stream file %s", de->d_name);
672 unlinkat(dirfd(d), de->d_name, 0);
673 continue;
674 }
675
676 fdset_remove(fds, fd);
677
678 r = stdout_stream_restore(s, de->d_name, fd);
679 if (r < 0)
680 safe_close(fd);
681 }
a45b9fca 682
7b77ed8c 683 return 0;
13790add
LP
684
685fail:
686 return log_error_errno(errno, "Failed to read streams directory: %m");
a45b9fca
LP
687}
688
15d91bff 689int server_open_stdout_socket(Server *s) {
a45b9fca 690 int r;
a45b9fca
LP
691
692 assert(s);
693
694 if (s->stdout_fd < 0) {
b92bea5d
ZJS
695 union sockaddr_union sa = {
696 .un.sun_family = AF_UNIX,
697 .un.sun_path = "/run/systemd/journal/stdout",
698 };
a45b9fca
LP
699
700 s->stdout_fd = socket(AF_UNIX, SOCK_STREAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0);
4a62c710
MS
701 if (s->stdout_fd < 0)
702 return log_error_errno(errno, "socket() failed: %m");
a45b9fca 703
a45b9fca
LP
704 unlink(sa.un.sun_path);
705
706 r = bind(s->stdout_fd, &sa.sa, offsetof(union sockaddr_union, un.sun_path) + strlen(sa.un.sun_path));
4a62c710
MS
707 if (r < 0)
708 return log_error_errno(errno, "bind(%s) failed: %m", sa.un.sun_path);
a45b9fca 709
4a61c3e5 710 (void) chmod(sa.un.sun_path, 0666);
a45b9fca 711
4a62c710
MS
712 if (listen(s->stdout_fd, SOMAXCONN) < 0)
713 return log_error_errno(errno, "listen(%s) failed: %m", sa.un.sun_path);
a45b9fca
LP
714 } else
715 fd_nonblock(s->stdout_fd, 1);
716
151b9b96 717 r = sd_event_add_io(s->event, &s->stdout_event_source, s->stdout_fd, EPOLLIN, stdout_stream_new, s);
23bbb0de
MS
718 if (r < 0)
719 return log_error_errno(r, "Failed to add stdout server fd to event source: %m");
f9a810be
LP
720
721 r = sd_event_source_set_priority(s->stdout_event_source, SD_EVENT_PRIORITY_NORMAL+10);
23bbb0de
MS
722 if (r < 0)
723 return log_error_errno(r, "Failed to adjust priority of stdout server event source: %m");
a45b9fca
LP
724
725 return 0;
726}