]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/journal/journald-console.c
Add a snprinf wrapper which checks that the buffer was big enough
[thirdparty/systemd.git] / src / journal / journald-console.c
CommitLineData
3b7124a8
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
ad79565d 22#include <time.h>
3b7124a8
LP
23#include <fcntl.h>
24#include <unistd.h>
4871690d 25#include <sys/socket.h>
3b7124a8 26
ad79565d 27#include "fileio.h"
d025f1e4 28#include "journald-server.h"
3b7124a8
LP
29#include "journald-console.h"
30
ad79565d
UTL
31static bool prefix_timestamp(void) {
32
33 static int cached_printk_time = -1;
34
35 if (_unlikely_(cached_printk_time < 0)) {
36 _cleanup_free_ char *p = NULL;
37
38 cached_printk_time =
39 read_one_line_file("/sys/module/printk/parameters/time", &p) >= 0
40 && parse_boolean(p) > 0;
41 }
42
43 return cached_printk_time;
44}
45
3b7124a8
LP
46void server_forward_console(
47 Server *s,
48 int priority,
49 const char *identifier,
50 const char *message,
3b3154df 51 const struct ucred *ucred) {
3b7124a8 52
ad79565d 53 struct iovec iovec[5];
ad79565d 54 struct timespec ts;
5ffa8c81
ZJS
55 char tbuf[sizeof("[] ")-1 + DECIMAL_STR_MAX(ts.tv_sec) + DECIMAL_STR_MAX(ts.tv_nsec)-3 + 1];
56 char header_pid[sizeof("[]: ")-1 + DECIMAL_STR_MAX(pid_t)];
3b7124a8 57 int n = 0, fd;
fb472900 58 _cleanup_free_ char *ident_buf = NULL;
3b7124a8
LP
59 const char *tty;
60
61 assert(s);
62 assert(message);
63
64 if (LOG_PRI(priority) > s->max_level_console)
65 return;
66
ad79565d
UTL
67 /* First: timestamp */
68 if (prefix_timestamp()) {
69 assert_se(clock_gettime(CLOCK_MONOTONIC, &ts) == 0);
5ffa8c81 70 xsprintf(tbuf, "[%5"PRI_TIME".%06ld] ",
de0671ee
ZJS
71 ts.tv_sec,
72 ts.tv_nsec / 1000);
ad79565d
UTL
73 IOVEC_SET_STRING(iovec[n++], tbuf);
74 }
75
76 /* Second: identifier and PID */
3b7124a8
LP
77 if (ucred) {
78 if (!identifier) {
79 get_process_comm(ucred->pid, &ident_buf);
80 identifier = ident_buf;
81 }
82
5ffa8c81 83 xsprintf(header_pid, "["PID_FMT"]: ", ucred->pid);
3b7124a8
LP
84
85 if (identifier)
86 IOVEC_SET_STRING(iovec[n++], identifier);
87
88 IOVEC_SET_STRING(iovec[n++], header_pid);
89 } else if (identifier) {
90 IOVEC_SET_STRING(iovec[n++], identifier);
91 IOVEC_SET_STRING(iovec[n++], ": ");
92 }
93
ad79565d 94 /* Fourth: message */
3b7124a8
LP
95 IOVEC_SET_STRING(iovec[n++], message);
96 IOVEC_SET_STRING(iovec[n++], "\n");
97
98 tty = s->tty_path ? s->tty_path : "/dev/console";
99
100 fd = open_terminal(tty, O_WRONLY|O_NOCTTY|O_CLOEXEC);
101 if (fd < 0) {
56f64d95 102 log_debug_errno(errno, "Failed to open %s for logging: %m", tty);
fb472900 103 return;
3b7124a8
LP
104 }
105
106 if (writev(fd, iovec, n) < 0)
56f64d95 107 log_debug_errno(errno, "Failed to write to %s for logging: %m", tty);
3b7124a8 108
03e334a1 109 safe_close(fd);
3b7124a8 110}