[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