X-Git-Url: http://git.ipfire.org/?a=blobdiff_plain;f=src%2Fjournal%2Fcat.c;h=d8d72690d7278f5fed66ccef04a63c727556b45f;hb=5238e9575906297608ff802a27e2ff9effa3b338;hp=b2f9ed50108a9f0f52f7e48a62104bfa3032e89b;hpb=4ff183d419f9ec271ae311dae0bc01b4bb204b50;p=thirdparty%2Fsystemd.git diff --git a/src/journal/cat.c b/src/journal/cat.c index b2f9ed50108..d8d72690d72 100644 --- a/src/journal/cat.c +++ b/src/journal/cat.c @@ -1,22 +1,4 @@ /* SPDX-License-Identifier: LGPL-2.1+ */ -/*** - This file is part of systemd. - - Copyright 2012 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 . -***/ #include #include @@ -27,40 +9,59 @@ #include "sd-journal.h" +#include "alloc-util.h" #include "fd-util.h" +#include "main-func.h" #include "parse-util.h" +#include "pretty-print.h" #include "string-util.h" #include "syslog-util.h" #include "util.h" static const char *arg_identifier = NULL; static int arg_priority = LOG_INFO; +static int arg_stderr_priority = -1; static bool arg_level_prefix = true; -static void help(void) { +static int help(void) { + _cleanup_free_ char *link = NULL; + int r; + + r = terminal_urlify_man("systemd-cat", "1", &link); + if (r < 0) + return log_oom(); + printf("%s [OPTIONS...] {COMMAND} ...\n\n" "Execute process with stdout/stderr connected to the journal.\n\n" - " -h --help Show this help\n" - " --version Show package version\n" - " -t --identifier=STRING Set syslog identifier\n" - " -p --priority=PRIORITY Set priority value (0..7)\n" - " --level-prefix=BOOL Control whether level prefix shall be parsed\n" - , program_invocation_short_name); + " -h --help Show this help\n" + " --version Show package version\n" + " -t --identifier=STRING Set syslog identifier\n" + " -p --priority=PRIORITY Set priority value (0..7)\n" + " --stderr-priority=PRIORITY Set priority value (0..7) used for stderr\n" + " --level-prefix=BOOL Control whether level prefix shall be parsed\n" + "\nSee the %s for details.\n" + , program_invocation_short_name + , link + ); + + return 0; } static int parse_argv(int argc, char *argv[]) { enum { ARG_VERSION = 0x100, + ARG_STDERR_PRIORITY, ARG_LEVEL_PREFIX }; static const struct option options[] = { - { "help", no_argument, NULL, 'h' }, - { "version", no_argument, NULL, ARG_VERSION }, - { "identifier", required_argument, NULL, 't' }, - { "priority", required_argument, NULL, 'p' }, - { "level-prefix", required_argument, NULL, ARG_LEVEL_PREFIX }, + { "help", no_argument, NULL, 'h' }, + { "version", no_argument, NULL, ARG_VERSION }, + { "identifier", required_argument, NULL, 't' }, + { "priority", required_argument, NULL, 'p' }, + { "stderr-priority", required_argument, NULL, ARG_STDERR_PRIORITY }, + { "level-prefix", required_argument, NULL, ARG_LEVEL_PREFIX }, {} }; @@ -89,10 +90,16 @@ static int parse_argv(int argc, char *argv[]) { case 'p': arg_priority = log_level_from_string(optarg); - if (arg_priority < 0) { - log_error("Failed to parse priority value."); - return -EINVAL; - } + if (arg_priority < 0) + return log_error_errno(SYNTHETIC_ERRNO(EINVAL), + "Failed to parse priority value."); + break; + + case ARG_STDERR_PRIORITY: + arg_stderr_priority = log_level_from_string(optarg); + if (arg_stderr_priority < 0) + return log_error_errno(SYNTHETIC_ERRNO(EINVAL), + "Failed to parse stderr priority value."); break; case ARG_LEVEL_PREFIX: { @@ -116,8 +123,8 @@ static int parse_argv(int argc, char *argv[]) { return 1; } -int main(int argc, char *argv[]) { - _cleanup_close_ int fd = -1, saved_stderr = -1; +static int run(int argc, char *argv[]) { + _cleanup_close_ int outfd = -1, errfd = -1, saved_stderr = -1; int r; log_parse_environment(); @@ -125,25 +132,25 @@ int main(int argc, char *argv[]) { r = parse_argv(argc, argv); if (r <= 0) - goto finish; + return r; - fd = sd_journal_stream_fd(arg_identifier, arg_priority, arg_level_prefix); - if (fd < 0) { - r = log_error_errno(fd, "Failed to create stream fd: %m"); - goto finish; + outfd = sd_journal_stream_fd(arg_identifier, arg_priority, arg_level_prefix); + if (outfd < 0) + return log_error_errno(outfd, "Failed to create stream fd: %m"); + + if (arg_stderr_priority >= 0 && arg_stderr_priority != arg_priority) { + errfd = sd_journal_stream_fd(arg_identifier, arg_stderr_priority, arg_level_prefix); + if (errfd < 0) + return log_error_errno(errfd, "Failed to create stream fd: %m"); } saved_stderr = fcntl(STDERR_FILENO, F_DUPFD_CLOEXEC, 3); - if (dup3(fd, STDOUT_FILENO, 0) < 0 || - dup3(fd, STDERR_FILENO, 0) < 0) { - r = log_error_errno(errno, "Failed to duplicate fd: %m"); - goto finish; - } - - if (fd >= 3) - safe_close(fd); - fd = -1; + r = rearrange_stdio(STDIN_FILENO, outfd, errfd < 0 ? outfd : errfd); /* Invalidates fd on success + error! */ + TAKE_FD(outfd); + TAKE_FD(errfd); + if (r < 0) + return log_error_errno(r, "Failed to rearrange stdout/stderr: %m"); if (argc <= optind) (void) execl("/bin/cat", "/bin/cat", NULL); @@ -155,8 +162,7 @@ int main(int argc, char *argv[]) { if (saved_stderr >= 0) (void) dup3(saved_stderr, STDERR_FILENO, 0); - log_error_errno(r, "Failed to execute process: %m"); - -finish: - return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS; + return log_error_errno(r, "Failed to execute process: %m"); } + +DEFINE_MAIN_FUNCTION(run);