[systemd-devel] [RFC] exec: introduce StandardOutputFile/StandardErrorFile option
WaLyong Cho
walyong.cho at samsung.com
Mon May 18 19:44:44 PDT 2015
To redirect stdout/stderr to file add 'file' option to
StandardOutput/StandardError. And to specify the file path, add
StandardOutputFile/StandardErrorFile option.
If only set StandardOutput/StandardError to 'file' without set of
StandardOutputFile/StandardErrorFile option, then it will be
redirected to '/dev/null'.
---
src/core/execute.c | 22 ++++++++++++++++++----
src/core/execute.h | 3 +++
src/core/load-fragment-gperf.gperf.m4 | 2 ++
3 files changed, 23 insertions(+), 4 deletions(-)
diff --git a/src/core/execute.c b/src/core/execute.c
index 0cca481..a1408e0 100644
--- a/src/core/execute.c
+++ b/src/core/execute.c
@@ -197,12 +197,12 @@ static bool is_terminal_output(ExecOutput o) {
o == EXEC_OUTPUT_JOURNAL_AND_CONSOLE;
}
-static int open_null_as(int flags, int nfd) {
+static int open_file_as(int flags, const char *file, int nfd) {
int fd, r;
assert(nfd >= 0);
- fd = open("/dev/null", flags|O_NOCTTY);
+ fd = open(file ? file : "/dev/null", flags|O_NOCTTY);
if (fd < 0)
return -errno;
@@ -215,6 +215,10 @@ static int open_null_as(int flags, int nfd) {
return r;
}
+static int open_null_as(int flags, int nfd) {
+ return open_file_as(flags, "/dev/null", nfd);
+}
+
static int connect_journal_socket(int fd, uid_t uid, gid_t gid) {
union sockaddr_union sa = {
.un.sun_family = AF_UNIX,
@@ -420,7 +424,8 @@ static int setup_output(Unit *unit, const ExecContext *context, int fileno, int
return fileno;
/* Duplicate from stdout if possible */
- if (e == o || e == EXEC_OUTPUT_INHERIT)
+ if ((e == o || e == EXEC_OUTPUT_INHERIT) &&
+ e != EXEC_OUTPUT_FILE)
return dup2(STDOUT_FILENO, fileno) < 0 ? -errno : fileno;
o = e;
@@ -444,6 +449,9 @@ static int setup_output(Unit *unit, const ExecContext *context, int fileno, int
switch (o) {
+ case EXEC_OUTPUT_FILE:
+ return open_file_as(O_WRONLY|O_CREAT|O_APPEND, fileno == STDOUT_FILENO ? context->std_output_file : context->std_error_file, fileno);
+
case EXEC_OUTPUT_NULL:
return open_null_as(O_WRONLY, fileno);
@@ -1967,6 +1975,11 @@ void exec_context_done(ExecContext *c) {
free(c->root_directory);
c->root_directory = NULL;
+ free(c->std_output_file);
+ c->std_output_file = NULL;
+ free(c->std_error_file);
+ c->std_error_file = NULL;
+
free(c->tty_path);
c->tty_path = NULL;
@@ -2933,7 +2946,8 @@ static const char* const exec_output_table[_EXEC_OUTPUT_MAX] = {
[EXEC_OUTPUT_KMSG_AND_CONSOLE] = "kmsg+console",
[EXEC_OUTPUT_JOURNAL] = "journal",
[EXEC_OUTPUT_JOURNAL_AND_CONSOLE] = "journal+console",
- [EXEC_OUTPUT_SOCKET] = "socket"
+ [EXEC_OUTPUT_SOCKET] = "socket",
+ [EXEC_OUTPUT_FILE] = "file"
};
DEFINE_STRING_TABLE_LOOKUP(exec_output, ExecOutput);
diff --git a/src/core/execute.h b/src/core/execute.h
index f5d5c1d..327d711 100644
--- a/src/core/execute.h
+++ b/src/core/execute.h
@@ -59,6 +59,7 @@ typedef enum ExecOutput {
EXEC_OUTPUT_JOURNAL,
EXEC_OUTPUT_JOURNAL_AND_CONSOLE,
EXEC_OUTPUT_SOCKET,
+ EXEC_OUTPUT_FILE,
_EXEC_OUTPUT_MAX,
_EXEC_OUTPUT_INVALID = -1
} ExecOutput;
@@ -108,7 +109,9 @@ struct ExecContext {
ExecInput std_input;
ExecOutput std_output;
+ char *std_output_file;
ExecOutput std_error;
+ char *std_error_file;
nsec_t timer_slack_nsec;
diff --git a/src/core/load-fragment-gperf.gperf.m4 b/src/core/load-fragment-gperf.gperf.m4
index 66c9145..fbcaa95 100644
--- a/src/core/load-fragment-gperf.gperf.m4
+++ b/src/core/load-fragment-gperf.gperf.m4
@@ -35,7 +35,9 @@ $1.Environment, config_parse_environ, 0,
$1.EnvironmentFile, config_parse_unit_env_file, 0, offsetof($1, exec_context.environment_files)
$1.StandardInput, config_parse_input, 0, offsetof($1, exec_context.std_input)
$1.StandardOutput, config_parse_output, 0, offsetof($1, exec_context.std_output)
+$1.StandardOutputFile, config_parse_string, 0, offsetof($1, exec_context.std_output_file)
$1.StandardError, config_parse_output, 0, offsetof($1, exec_context.std_error)
+$1.StandardErrorFile, config_parse_string, 0, offsetof($1, exec_context.std_error_file)
$1.TTYPath, config_parse_unit_path_printf, 0, offsetof($1, exec_context.tty_path)
$1.TTYReset, config_parse_bool, 0, offsetof($1, exec_context.tty_reset)
$1.TTYVHangup, config_parse_bool, 0, offsetof($1, exec_context.tty_vhangup)
--
1.9.3
More information about the systemd-devel
mailing list