2012-08-22 05:36:29 +04:00
/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
/***
This file is part of systemd .
Copyright 2011 Lennart Poettering
systemd is free software ; you can redistribute it and / or modify it
under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation ; either version 2.1 of the License , or
( at your option ) any later version .
systemd is distributed in the hope that it will be useful , but
WITHOUT ANY WARRANTY ; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the GNU
Lesser General Public License for more details .
You should have received a copy of the GNU Lesser General Public License
along with systemd ; If not , see < http : //www.gnu.org/licenses/>.
* * */
2013-11-13 18:27:19 +04:00
# include <time.h>
2012-08-22 05:36:29 +04:00
# include <fcntl.h>
2012-08-24 03:46:38 +04:00
# include <sys/socket.h>
2012-08-22 05:36:29 +04:00
2013-11-13 18:27:19 +04:00
# include "fileio.h"
2012-11-12 20:29:07 +04:00
# include "journald-server.h"
2012-08-22 05:36:29 +04:00
# include "journald-console.h"
2015-04-10 21:43:52 +03:00
# include "formats-util.h"
2015-04-10 20:10:00 +03:00
# include "process-util.h"
2015-04-11 00:15:59 +03:00
# include "terminal-util.h"
2012-08-22 05:36:29 +04:00
2013-11-13 18:27:19 +04:00
static bool prefix_timestamp ( void ) {
static int cached_printk_time = - 1 ;
if ( _unlikely_ ( cached_printk_time < 0 ) ) {
_cleanup_free_ char * p = NULL ;
cached_printk_time =
read_one_line_file ( " /sys/module/printk/parameters/time " , & p ) > = 0
& & parse_boolean ( p ) > 0 ;
}
return cached_printk_time ;
}
2012-08-22 05:36:29 +04:00
void server_forward_console (
Server * s ,
int priority ,
const char * identifier ,
const char * message ,
2014-11-02 23:46:42 +03:00
const struct ucred * ucred ) {
2012-08-22 05:36:29 +04:00
2013-11-13 18:27:19 +04:00
struct iovec iovec [ 5 ] ;
struct timespec ts ;
2015-01-27 16:00:11 +03:00
char tbuf [ sizeof ( " [] " ) - 1 + DECIMAL_STR_MAX ( ts . tv_sec ) + DECIMAL_STR_MAX ( ts . tv_nsec ) - 3 + 1 ] ;
char header_pid [ sizeof ( " []: " ) - 1 + DECIMAL_STR_MAX ( pid_t ) ] ;
2012-08-22 05:36:29 +04:00
int n = 0 , fd ;
2014-02-16 03:10:36 +04:00
_cleanup_free_ char * ident_buf = NULL ;
2012-08-22 05:36:29 +04:00
const char * tty ;
assert ( s ) ;
assert ( message ) ;
if ( LOG_PRI ( priority ) > s - > max_level_console )
return ;
2013-11-13 18:27:19 +04:00
/* First: timestamp */
if ( prefix_timestamp ( ) ) {
assert_se ( clock_gettime ( CLOCK_MONOTONIC , & ts ) = = 0 ) ;
2015-01-27 16:00:11 +03:00
xsprintf ( tbuf , " [%5 " PRI_TIME " .%06ld] " ,
2014-04-25 15:45:15 +04:00
ts . tv_sec ,
ts . tv_nsec / 1000 ) ;
2013-11-13 18:27:19 +04:00
IOVEC_SET_STRING ( iovec [ n + + ] , tbuf ) ;
}
/* Second: identifier and PID */
2012-08-22 05:36:29 +04:00
if ( ucred ) {
if ( ! identifier ) {
get_process_comm ( ucred - > pid , & ident_buf ) ;
identifier = ident_buf ;
}
2015-01-27 16:00:11 +03:00
xsprintf ( header_pid , " [ " PID_FMT " ]: " , ucred - > pid ) ;
2012-08-22 05:36:29 +04:00
if ( identifier )
IOVEC_SET_STRING ( iovec [ n + + ] , identifier ) ;
IOVEC_SET_STRING ( iovec [ n + + ] , header_pid ) ;
} else if ( identifier ) {
IOVEC_SET_STRING ( iovec [ n + + ] , identifier ) ;
IOVEC_SET_STRING ( iovec [ n + + ] , " : " ) ;
}
2013-11-13 18:27:19 +04:00
/* Fourth: message */
2012-08-22 05:36:29 +04:00
IOVEC_SET_STRING ( iovec [ n + + ] , message ) ;
IOVEC_SET_STRING ( iovec [ n + + ] , " \n " ) ;
tty = s - > tty_path ? s - > tty_path : " /dev/console " ;
fd = open_terminal ( tty , O_WRONLY | O_NOCTTY | O_CLOEXEC ) ;
if ( fd < 0 ) {
2014-11-28 21:29:59 +03:00
log_debug_errno ( errno , " Failed to open %s for logging: %m " , tty ) ;
2014-02-16 03:10:36 +04:00
return ;
2012-08-22 05:36:29 +04:00
}
if ( writev ( fd , iovec , n ) < 0 )
2014-11-28 21:29:59 +03:00
log_debug_errno ( errno , " Failed to write to %s for logging: %m " , tty ) ;
2012-08-22 05:36:29 +04:00
2014-03-18 22:22:43 +04:00
safe_close ( fd ) ;
2012-08-22 05:36:29 +04:00
}