2 This file is part of systemd.
4 Copyright 2012 Lennart Poettering
6 systemd is free software; you can redistribute it and/or modify it
7 under the terms of the GNU Lesser General Public License as published by
8 the Free Software Foundation; either version 2.1 of the License, or
9 (at your option) any later version.
11 systemd is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 Lesser General Public License for more details.
16 You should have received a copy of the GNU Lesser General Public License
17 along with systemd; If not, see <http://www.gnu.org/licenses/>.
27 #include "sd-journal.h"
30 #include "parse-util.h"
31 #include "string-util.h"
32 #include "syslog-util.h"
35 static const char *arg_identifier
= NULL
;
36 static int arg_priority
= LOG_INFO
;
37 static bool arg_level_prefix
= true;
39 static void help(void) {
40 printf("%s [OPTIONS...] {COMMAND} ...\n\n"
41 "Execute process with stdout/stderr connected to the journal.\n\n"
42 " -h --help Show this help\n"
43 " --version Show package version\n"
44 " -t --identifier=STRING Set syslog identifier\n"
45 " -p --priority=PRIORITY Set priority value (0..7)\n"
46 " --level-prefix=BOOL Control whether level prefix shall be parsed\n"
47 , program_invocation_short_name
);
50 static int parse_argv(int argc
, char *argv
[]) {
57 static const struct option options
[] = {
58 { "help", no_argument
, NULL
, 'h' },
59 { "version", no_argument
, NULL
, ARG_VERSION
},
60 { "identifier", required_argument
, NULL
, 't' },
61 { "priority", required_argument
, NULL
, 'p' },
62 { "level-prefix", required_argument
, NULL
, ARG_LEVEL_PREFIX
},
71 while ((c
= getopt_long(argc
, argv
, "+ht:p:", options
, NULL
)) >= 0)
84 arg_identifier
= NULL
;
86 arg_identifier
= optarg
;
90 arg_priority
= log_level_from_string(optarg
);
91 if (arg_priority
< 0) {
92 log_error("Failed to parse priority value.");
97 case ARG_LEVEL_PREFIX
: {
100 k
= parse_boolean(optarg
);
102 return log_error_errno(k
, "Failed to parse level prefix value.");
104 arg_level_prefix
= k
;
112 assert_not_reached("Unhandled option");
118 int main(int argc
, char *argv
[]) {
119 _cleanup_close_
int fd
= -1, saved_stderr
= -1;
122 log_parse_environment();
125 r
= parse_argv(argc
, argv
);
129 fd
= sd_journal_stream_fd(arg_identifier
, arg_priority
, arg_level_prefix
);
131 r
= log_error_errno(fd
, "Failed to create stream fd: %m");
135 saved_stderr
= fcntl(STDERR_FILENO
, F_DUPFD_CLOEXEC
, 3);
137 if (dup3(fd
, STDOUT_FILENO
, 0) < 0 ||
138 dup3(fd
, STDERR_FILENO
, 0) < 0) {
139 r
= log_error_errno(errno
, "Failed to duplicate fd: %m");
148 (void) execl("/bin/cat", "/bin/cat", NULL
);
150 (void) execvp(argv
[optind
], argv
+ optind
);
153 /* Let's try to restore a working stderr, so we can print the error message */
154 if (saved_stderr
>= 0)
155 (void) dup3(saved_stderr
, STDERR_FILENO
, 0);
157 log_error_errno(r
, "Failed to execute process: %m");
160 return r
< 0 ? EXIT_FAILURE
: EXIT_SUCCESS
;