diff options
author | Zsolt Dollenstein <zsol.zsol@gmail.com> | 2018-07-03 12:22:29 -0700 |
---|---|---|
committer | The Plumber <50238977+systemd-rhel-bot@users.noreply.github.com> | 2020-05-19 13:36:25 +0200 |
commit | 2808e53f785e9ca7fdab286678e784b661b4c185 (patch) | |
tree | c718e3eec51fac57672cc9687b52bd5dca89fb33 /src | |
parent | b8af9fd65b697e9bb77a32d1a6a70367814aaed5 (diff) | |
download | systemd-2808e53f785e9ca7fdab286678e784b661b4c185.tar.gz |
Add support for opening files for appending
Addresses part of #8983
(cherry picked from commit 566b7d23eb747e9c5a74e5647693077b52395fc5)
Resolves: #1809175
Diffstat (limited to 'src')
-rw-r--r-- | src/core/dbus-execute.c | 30 | ||||
-rw-r--r-- | src/core/execute.c | 20 | ||||
-rw-r--r-- | src/core/execute.h | 1 | ||||
-rw-r--r-- | src/core/load-fragment.c | 11 | ||||
-rw-r--r-- | src/core/main.c | 4 | ||||
-rw-r--r-- | src/test/test-execute.c | 10 |
6 files changed, 62 insertions, 14 deletions
diff --git a/src/core/dbus-execute.c b/src/core/dbus-execute.c index e7c0b893d1..f9527e56b2 100644 --- a/src/core/dbus-execute.c +++ b/src/core/dbus-execute.c @@ -1772,7 +1772,10 @@ int bus_exec_context_set_transient_property( return 1; - } else if (STR_IN_SET(name, "StandardInputFile", "StandardOutputFile", "StandardErrorFile")) { + } else if (STR_IN_SET(name, + "StandardInputFile", + "StandardOutputFile", "StandardOutputFileToCreate", "StandardOutputFileToAppend", + "StandardErrorFile", "StandardErrorFileToCreate", "StandardErrorFileToAppend")) { const char *s; r = sd_bus_message_read(message, "s", &s); @@ -1796,23 +1799,34 @@ int bus_exec_context_set_transient_property( c->std_input = EXEC_INPUT_FILE; unit_write_settingf(u, flags|UNIT_ESCAPE_SPECIFIERS, name, "StandardInput=file:%s", s); - } else if (streq(name, "StandardOutputFile")) { + } else if (STR_IN_SET(name, "StandardOutputFile", "StandardOutputFileToAppend")) { r = free_and_strdup(&c->stdio_file[STDOUT_FILENO], empty_to_null(s)); if (r < 0) return r; - c->std_output = EXEC_OUTPUT_FILE; - unit_write_settingf(u, flags|UNIT_ESCAPE_SPECIFIERS, name, "StandardOutput=file:%s", s); - + if (streq(name, "StandardOutputFile")) { + c->std_output = EXEC_OUTPUT_FILE; + unit_write_settingf(u, flags|UNIT_ESCAPE_SPECIFIERS, name, "StandardOutput=file:%s", s); + } else { + assert(streq(name, "StandardOutputFileToAppend")); + c->std_output = EXEC_OUTPUT_FILE_APPEND; + unit_write_settingf(u, flags|UNIT_ESCAPE_SPECIFIERS, name, "StandardOutput=append:%s", s); + } } else { - assert(streq(name, "StandardErrorFile")); + assert(STR_IN_SET(name, "StandardErrorFile", "StandardErrorFileToAppend")); r = free_and_strdup(&c->stdio_file[STDERR_FILENO], empty_to_null(s)); if (r < 0) return r; - c->std_error = EXEC_OUTPUT_FILE; - unit_write_settingf(u, flags|UNIT_ESCAPE_SPECIFIERS, name, "StandardError=file:%s", s); + if (streq(name, "StandardErrorFile")) { + c->std_error = EXEC_OUTPUT_FILE; + unit_write_settingf(u, flags|UNIT_ESCAPE_SPECIFIERS, name, "StandardOutput=file:%s", s); + } else { + assert(streq(name, "StandardErrorFileToAppend")); + c->std_error = EXEC_OUTPUT_FILE_APPEND; + unit_write_settingf(u, flags|UNIT_ESCAPE_SPECIFIERS, name, "StandardOutput=append:%s", s); + } } } diff --git a/src/core/execute.c b/src/core/execute.c index f012023224..3c54ac1110 100644 --- a/src/core/execute.c +++ b/src/core/execute.c @@ -89,6 +89,7 @@ #include "strv.h" #include "syslog-util.h" #include "terminal-util.h" +#include "umask-util.h" #include "unit.h" #include "user-util.h" #include "util.h" @@ -675,9 +676,10 @@ static int setup_output( (void) fd_nonblock(named_iofds[fileno], false); return dup2(named_iofds[fileno], fileno) < 0 ? -errno : fileno; - case EXEC_OUTPUT_FILE: { + case EXEC_OUTPUT_FILE: + case EXEC_OUTPUT_FILE_APPEND: { bool rw; - int fd; + int fd, flags; assert(context->stdio_file[fileno]); @@ -687,11 +689,16 @@ static int setup_output( if (rw) return dup2(STDIN_FILENO, fileno) < 0 ? -errno : fileno; - fd = acquire_path(context->stdio_file[fileno], O_WRONLY, 0666 & ~context->umask); + flags = O_WRONLY; + if (o == EXEC_OUTPUT_FILE_APPEND) + flags |= O_APPEND; + + fd = acquire_path(context->stdio_file[fileno], flags, 0666 & ~context->umask); + if (fd < 0) return fd; - return move_fd(fd, fileno, false); + return move_fd(fd, fileno, 0); } default: @@ -4168,8 +4175,12 @@ void exec_context_dump(const ExecContext *c, FILE* f, const char *prefix) { fprintf(f, "%sStandardInputFile: %s\n", prefix, c->stdio_file[STDIN_FILENO]); if (c->std_output == EXEC_OUTPUT_FILE) fprintf(f, "%sStandardOutputFile: %s\n", prefix, c->stdio_file[STDOUT_FILENO]); + if (c->std_output == EXEC_OUTPUT_FILE_APPEND) + fprintf(f, "%sStandardOutputFileToAppend: %s\n", prefix, c->stdio_file[STDOUT_FILENO]); if (c->std_error == EXEC_OUTPUT_FILE) fprintf(f, "%sStandardErrorFile: %s\n", prefix, c->stdio_file[STDERR_FILENO]); + if (c->std_error == EXEC_OUTPUT_FILE_APPEND) + fprintf(f, "%sStandardErrorFileToAppend: %s\n", prefix, c->stdio_file[STDERR_FILENO]); if (c->tty_path) fprintf(f, @@ -5111,6 +5122,7 @@ static const char* const exec_output_table[_EXEC_OUTPUT_MAX] = { [EXEC_OUTPUT_SOCKET] = "socket", [EXEC_OUTPUT_NAMED_FD] = "fd", [EXEC_OUTPUT_FILE] = "file", + [EXEC_OUTPUT_FILE_APPEND] = "append", }; DEFINE_STRING_TABLE_LOOKUP(exec_output, ExecOutput); diff --git a/src/core/execute.h b/src/core/execute.h index 2266355962..86c1cee84c 100644 --- a/src/core/execute.h +++ b/src/core/execute.h @@ -57,6 +57,7 @@ typedef enum ExecOutput { EXEC_OUTPUT_SOCKET, EXEC_OUTPUT_NAMED_FD, EXEC_OUTPUT_FILE, + EXEC_OUTPUT_FILE_APPEND, _EXEC_OUTPUT_MAX, _EXEC_OUTPUT_INVALID = -1 } ExecOutput; diff --git a/src/core/load-fragment.c b/src/core/load-fragment.c index 2082166afb..9b2724307d 100644 --- a/src/core/load-fragment.c +++ b/src/core/load-fragment.c @@ -1016,6 +1016,17 @@ int config_parse_exec_output( eo = EXEC_OUTPUT_FILE; + } else if ((n = startswith(rvalue, "append:"))) { + + r = unit_full_printf(u, n, &resolved); + if (r < 0) + return log_syntax(unit, LOG_ERR, filename, line, r, "Failed to resolve unit specifiers in %s: %m", n); + + r = path_simplify_and_warn(resolved, PATH_CHECK_ABSOLUTE | PATH_CHECK_FATAL, unit, filename, line, lvalue); + if (r < 0) + return -ENOEXEC; + + eo = EXEC_OUTPUT_FILE_APPEND; } else { eo = exec_output_from_string(rvalue); if (eo < 0) { diff --git a/src/core/main.c b/src/core/main.c index 9f238a8430..25536054b3 100644 --- a/src/core/main.c +++ b/src/core/main.c @@ -620,8 +620,8 @@ static int config_parse_output_restricted( return 0; } - if (IN_SET(t, EXEC_OUTPUT_SOCKET, EXEC_OUTPUT_NAMED_FD, EXEC_OUTPUT_FILE)) { - log_syntax(unit, LOG_ERR, filename, line, 0, "Standard output types socket, fd:, file: are not supported as defaults, ignoring: %s", rvalue); + if (IN_SET(t, EXEC_OUTPUT_SOCKET, EXEC_OUTPUT_NAMED_FD, EXEC_OUTPUT_FILE, EXEC_OUTPUT_FILE_APPEND)) { + log_syntax(unit, LOG_ERR, filename, line, 0, "Standard output types socket, fd:, file:, append: are not supported as defaults, ignoring: %s", rvalue); return 0; } diff --git a/src/test/test-execute.c b/src/test/test-execute.c index 637ffe96bb..0f8dc883b1 100644 --- a/src/test/test-execute.c +++ b/src/test/test-execute.c @@ -651,6 +651,14 @@ static void test_exec_standardinput(Manager *m) { test(m, "exec-standardinput-file.service", 0, CLD_EXITED); } +static void test_exec_standardoutput(Manager *m) { + test(m, "exec-standardoutput-file.service", 0, CLD_EXITED); +} + +static void test_exec_standardoutput_append(Manager *m) { + test(m, "exec-standardoutput-append.service", 0, CLD_EXITED); +} + static int run_tests(UnitFileScope scope, const test_function_t *tests) { const test_function_t *test = NULL; _cleanup_(manager_freep) Manager *m = NULL; @@ -698,6 +706,8 @@ int main(int argc, char *argv[]) { test_exec_restrictnamespaces, test_exec_runtimedirectory, test_exec_standardinput, + test_exec_standardoutput, + test_exec_standardoutput_append, test_exec_supplementarygroups, test_exec_systemcallerrornumber, test_exec_systemcallfilter, |