diff options
author | Lennart Poettering <lennart@poettering.net> | 2011-02-15 01:27:53 +0100 |
---|---|---|
committer | Lennart Poettering <lennart@poettering.net> | 2011-02-15 01:27:53 +0100 |
commit | 28dbc1e80b0db09313f11e44f218138aefd646c8 (patch) | |
tree | 897f4bbc275cc773d20929deabeb8c16a51f2910 /src | |
parent | 7b4bf06ba7f31ea8069fc8927729d70ab98b9b64 (diff) |
execute: optionally forward program output to /dev/console in addition to syslog/kmsg
Diffstat (limited to 'src')
-rw-r--r-- | src/execute.c | 15 | ||||
-rw-r--r-- | src/execute.h | 2 | ||||
-rw-r--r-- | src/logger.c | 25 | ||||
-rw-r--r-- | src/unit.c | 6 |
4 files changed, 42 insertions, 6 deletions
diff --git a/src/execute.c b/src/execute.c index 10ce951c59..e01cbde974 100644 --- a/src/execute.c +++ b/src/execute.c @@ -198,7 +198,10 @@ static int connect_logger_as(const ExecContext *context, ExecOutput output, cons "%i\n" "%s\n" "%i\n", - output == EXEC_OUTPUT_KMSG ? "kmsg" : "syslog", + output == EXEC_OUTPUT_KMSG ? "kmsg" : + output == EXEC_OUTPUT_KMSG_AND_CONSOLE ? "kmsg+console" : + output == EXEC_OUTPUT_SYSLOG ? "syslog" : + "syslog+console", context->syslog_priority, context->syslog_identifier ? context->syslog_identifier : ident, context->syslog_level_prefix); @@ -338,7 +341,9 @@ static int setup_output(const ExecContext *context, int socket_fd, const char *i return open_terminal_as(tty_path(context), O_WRONLY, STDOUT_FILENO); case EXEC_OUTPUT_SYSLOG: + case EXEC_OUTPUT_SYSLOG_AND_CONSOLE: case EXEC_OUTPUT_KMSG: + case EXEC_OUTPUT_KMSG_AND_CONSOLE: return connect_logger_as(context, o, ident, STDOUT_FILENO); case EXEC_OUTPUT_SOCKET: @@ -389,7 +394,9 @@ static int setup_error(const ExecContext *context, int socket_fd, const char *id return open_terminal_as(tty_path(context), O_WRONLY, STDERR_FILENO); case EXEC_OUTPUT_SYSLOG: + case EXEC_OUTPUT_SYSLOG_AND_CONSOLE: case EXEC_OUTPUT_KMSG: + case EXEC_OUTPUT_KMSG_AND_CONSOLE: return connect_logger_as(context, e, ident, STDERR_FILENO); case EXEC_OUTPUT_SOCKET: @@ -1543,7 +1550,9 @@ void exec_context_dump(ExecContext *c, FILE* f, const char *prefix) { prefix, c->tty_path); if (c->std_output == EXEC_OUTPUT_SYSLOG || c->std_output == EXEC_OUTPUT_KMSG || - c->std_error == EXEC_OUTPUT_SYSLOG || c->std_error == EXEC_OUTPUT_KMSG) + c->std_output == EXEC_OUTPUT_SYSLOG_AND_CONSOLE || c->std_output == EXEC_OUTPUT_KMSG_AND_CONSOLE || + c->std_error == EXEC_OUTPUT_SYSLOG || c->std_error == EXEC_OUTPUT_KMSG || + c->std_error == EXEC_OUTPUT_SYSLOG_AND_CONSOLE || c->std_error == EXEC_OUTPUT_KMSG_AND_CONSOLE) fprintf(f, "%sSyslogFacility: %s\n" "%sSyslogLevel: %s\n", @@ -1820,7 +1829,9 @@ static const char* const exec_output_table[_EXEC_OUTPUT_MAX] = { [EXEC_OUTPUT_NULL] = "null", [EXEC_OUTPUT_TTY] = "tty", [EXEC_OUTPUT_SYSLOG] = "syslog", + [EXEC_OUTPUT_SYSLOG_AND_CONSOLE] = "syslog+console", [EXEC_OUTPUT_KMSG] = "kmsg", + [EXEC_OUTPUT_KMSG_AND_CONSOLE] = "kmsg+console", [EXEC_OUTPUT_SOCKET] = "socket" }; diff --git a/src/execute.h b/src/execute.h index a6766f9e99..3cdd2ad284 100644 --- a/src/execute.h +++ b/src/execute.h @@ -78,7 +78,9 @@ typedef enum ExecOutput { EXEC_OUTPUT_NULL, EXEC_OUTPUT_TTY, EXEC_OUTPUT_SYSLOG, + EXEC_OUTPUT_SYSLOG_AND_CONSOLE, EXEC_OUTPUT_KMSG, + EXEC_OUTPUT_KMSG_AND_CONSOLE, EXEC_OUTPUT_SOCKET, _EXEC_OUTPUT_MAX, _EXEC_OUTPUT_INVALID = -1 diff --git a/src/logger.c b/src/logger.c index 482ec41244..342c307899 100644 --- a/src/logger.c +++ b/src/logger.c @@ -84,7 +84,8 @@ struct Stream { uid_t uid; gid_t gid; - bool prefix; + bool prefix:1; + bool tee_console:1; char buffer[LINE_MAX]; size_t length; @@ -228,6 +229,20 @@ static int stream_log(Stream *s, char *p, usec_t ts) { } else assert_not_reached("Unknown log target"); + if (s->tee_console) { + int console; + + if ((console = open_terminal("/dev/console", O_WRONLY|O_NOCTTY|O_CLOEXEC)) >= 0) { + IOVEC_SET_STRING(iovec[0], s->process); + IOVEC_SET_STRING(iovec[1], header_pid); + IOVEC_SET_STRING(iovec[2], p); + IOVEC_SET_STRING(iovec[3], (char*) "\n"); + + writev(console, iovec, 4); + } + + } + return 0; } @@ -242,9 +257,9 @@ static int stream_line(Stream *s, char *p, usec_t ts) { switch (s->state) { case STREAM_TARGET: - if (streq(p, "syslog")) + if (streq(p, "syslog") || streq(p, "syslog+console")) s->target = STREAM_SYSLOG; - else if (streq(p, "kmsg")) { + else if (streq(p, "kmsg") || streq(p, "kmsg+console")) { if (s->server->kmsg_fd >= 0 && s->uid == 0) s->target = STREAM_KMSG; @@ -256,6 +271,10 @@ static int stream_line(Stream *s, char *p, usec_t ts) { log_warning("Failed to parse log target line."); return -EBADMSG; } + + if (endswith(p, "+console")) + s->tee_console = true; + s->state = STREAM_PRIORITY; return 0; diff --git a/src/unit.c b/src/unit.c index a7e6714c45..0d5312376c 100644 --- a/src/unit.c +++ b/src/unit.c @@ -556,8 +556,12 @@ int unit_add_exec_dependencies(Unit *u, ExecContext *c) { if (c->std_output != EXEC_OUTPUT_KMSG && c->std_output != EXEC_OUTPUT_SYSLOG && + c->std_output != EXEC_OUTPUT_KMSG_AND_CONSOLE && + c->std_output != EXEC_OUTPUT_SYSLOG_AND_CONSOLE && c->std_error != EXEC_OUTPUT_KMSG && - c->std_error != EXEC_OUTPUT_SYSLOG) + c->std_error != EXEC_OUTPUT_SYSLOG_AND_CONSOLE && + c->std_error != EXEC_OUTPUT_KMSG && + c->std_error != EXEC_OUTPUT_SYSLOG_AND_CONSOLE) return 0; /* If syslog or kernel logging is requested, make sure our own |