journald-console.c revision 709f6e46a35ec492b70eb92943d82a8d838ce918
3731acf1acfb4a6eb68374a5b137f3b368f63381Lennart Poettering/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
3731acf1acfb4a6eb68374a5b137f3b368f63381Lennart Poettering
3731acf1acfb4a6eb68374a5b137f3b368f63381Lennart Poettering/***
3731acf1acfb4a6eb68374a5b137f3b368f63381Lennart Poettering This file is part of systemd.
3731acf1acfb4a6eb68374a5b137f3b368f63381Lennart Poettering
3731acf1acfb4a6eb68374a5b137f3b368f63381Lennart Poettering Copyright 2011 Lennart Poettering
3731acf1acfb4a6eb68374a5b137f3b368f63381Lennart Poettering
3731acf1acfb4a6eb68374a5b137f3b368f63381Lennart Poettering systemd is free software; you can redistribute it and/or modify it
3731acf1acfb4a6eb68374a5b137f3b368f63381Lennart Poettering under the terms of the GNU Lesser General Public License as published by
3731acf1acfb4a6eb68374a5b137f3b368f63381Lennart Poettering the Free Software Foundation; either version 2.1 of the License, or
3731acf1acfb4a6eb68374a5b137f3b368f63381Lennart Poettering (at your option) any later version.
3731acf1acfb4a6eb68374a5b137f3b368f63381Lennart Poettering
3731acf1acfb4a6eb68374a5b137f3b368f63381Lennart Poettering systemd is distributed in the hope that it will be useful, but
3731acf1acfb4a6eb68374a5b137f3b368f63381Lennart Poettering WITHOUT ANY WARRANTY; without even the implied warranty of
3731acf1acfb4a6eb68374a5b137f3b368f63381Lennart Poettering MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
3731acf1acfb4a6eb68374a5b137f3b368f63381Lennart Poettering Lesser General Public License for more details.
3731acf1acfb4a6eb68374a5b137f3b368f63381Lennart Poettering
3731acf1acfb4a6eb68374a5b137f3b368f63381Lennart Poettering You should have received a copy of the GNU Lesser General Public License
3731acf1acfb4a6eb68374a5b137f3b368f63381Lennart Poettering along with systemd; If not, see <http://www.gnu.org/licenses/>.
3731acf1acfb4a6eb68374a5b137f3b368f63381Lennart Poettering***/
3731acf1acfb4a6eb68374a5b137f3b368f63381Lennart Poettering
3731acf1acfb4a6eb68374a5b137f3b368f63381Lennart Poettering#include <time.h>
3731acf1acfb4a6eb68374a5b137f3b368f63381Lennart Poettering#include <fcntl.h>
3731acf1acfb4a6eb68374a5b137f3b368f63381Lennart Poettering#include <sys/socket.h>
1ca208fb4f93e5869704af1812cbff7130a2fc03Zbigniew Jędrzejewski-Szmek
1ca208fb4f93e5869704af1812cbff7130a2fc03Zbigniew Jędrzejewski-Szmek#include "alloc-util.h"
938d2699d2e818bd996614e89ea3d668200ad2a8Zbigniew Jędrzejewski-Szmek#include "fd-util.h"
3731acf1acfb4a6eb68374a5b137f3b368f63381Lennart Poettering#include "fileio.h"
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering#include "formats-util.h"
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering#include "io-util.h"
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering#include "journald-console.h"
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering#include "journald-server.h"
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering#include "parse-util.h"
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering#include "process-util.h"
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering#include "stdio-util.h"
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering#include "terminal-util.h"
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poetteringstatic bool prefix_timestamp(void) {
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering static int cached_printk_time = -1;
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering if (_unlikely_(cached_printk_time < 0)) {
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering _cleanup_free_ char *p = NULL;
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering cached_printk_time =
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering read_one_line_file("/sys/module/printk/parameters/time", &p) >= 0
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering && parse_boolean(p) > 0;
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering }
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering return cached_printk_time;
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering}
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poetteringvoid server_forward_console(
938d2699d2e818bd996614e89ea3d668200ad2a8Zbigniew Jędrzejewski-Szmek Server *s,
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering int priority,
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering const char *identifier,
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering const char *message,
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering const struct ucred *ucred) {
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering struct iovec iovec[5];
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering struct timespec ts;
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering char tbuf[sizeof("[] ")-1 + DECIMAL_STR_MAX(ts.tv_sec) + DECIMAL_STR_MAX(ts.tv_nsec)-3 + 1];
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering char header_pid[sizeof("[]: ")-1 + DECIMAL_STR_MAX(pid_t)];
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering int n = 0, fd;
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering _cleanup_free_ char *ident_buf = NULL;
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering const char *tty;
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering
39883f622f392d8579f4428fc5a789a102efbb10Lennart Poettering assert(s);
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering assert(message);
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering
938d2699d2e818bd996614e89ea3d668200ad2a8Zbigniew Jędrzejewski-Szmek if (LOG_PRI(priority) > s->max_level_console)
938d2699d2e818bd996614e89ea3d668200ad2a8Zbigniew Jędrzejewski-Szmek return;
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering /* First: timestamp */
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering if (prefix_timestamp()) {
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering assert_se(clock_gettime(CLOCK_MONOTONIC, &ts) == 0);
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering xsprintf(tbuf, "[%5"PRI_TIME".%06ld] ",
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering ts.tv_sec,
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering ts.tv_nsec / 1000);
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering IOVEC_SET_STRING(iovec[n++], tbuf);
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering }
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering /* Second: identifier and PID */
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering if (ucred) {
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering if (!identifier) {
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering get_process_comm(ucred->pid, &ident_buf);
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering identifier = ident_buf;
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering }
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering xsprintf(header_pid, "["PID_FMT"]: ", ucred->pid);
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering if (identifier)
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering IOVEC_SET_STRING(iovec[n++], identifier);
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering IOVEC_SET_STRING(iovec[n++], header_pid);
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering } else if (identifier) {
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering IOVEC_SET_STRING(iovec[n++], identifier);
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering IOVEC_SET_STRING(iovec[n++], ": ");
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering }
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering /* Fourth: message */
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering IOVEC_SET_STRING(iovec[n++], message);
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering IOVEC_SET_STRING(iovec[n++], "\n");
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering tty = s->tty_path ? s->tty_path : "/dev/console";
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering fd = open_terminal(tty, O_WRONLY|O_NOCTTY|O_CLOEXEC);
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering if (fd < 0) {
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering log_debug_errno(fd, "Failed to open %s for logging: %m", tty);
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering return;
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering }
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering if (writev(fd, iovec, n) < 0)
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering log_debug_errno(errno, "Failed to write to %s for logging: %m", tty);
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering safe_close(fd);
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering}
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering