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