summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorZsolt Dollenstein <zsol.zsol@gmail.com>2018-07-03 12:22:29 -0700
committerZsolt Dollenstein <zsol@fb.com>2018-07-20 03:54:22 -0700
commit566b7d23eb747e9c5a74e5647693077b52395fc5 (patch)
treed18c8eb14208a543717ed590c4548adf71874344 /src
parent48a0ab391c625b240433867ebf2c918270a93923 (diff)
downloadsystemd-566b7d23eb747e9c5a74e5647693077b52395fc5.tar.gz
Add support for opening files for appending
Addresses part of #8983
Diffstat (limited to 'src')
-rw-r--r--src/core/dbus-execute.c30
-rw-r--r--src/core/execute.c20
-rw-r--r--src/core/execute.h1
-rw-r--r--src/core/load-fragment.c11
-rw-r--r--src/core/main.c4
-rw-r--r--src/test/test-execute.c10
6 files changed, 62 insertions, 14 deletions
diff --git a/src/core/dbus-execute.c b/src/core/dbus-execute.c
index c44970c10c..1cdeaa8cfb 100644
--- a/src/core/dbus-execute.c
+++ b/src/core/dbus-execute.c
@@ -1731,7 +1731,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);
@@ -1755,23 +1758,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 8ac69d1a0f..a08e3105bf 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:
@@ -4036,8 +4043,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,
@@ -4968,6 +4979,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 77ffe82323..de44085492 100644
--- a/src/core/execute.h
+++ b/src/core/execute.h
@@ -56,6 +56,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 e18499384a..89b7bd8d09 100644
--- a/src/core/load-fragment.c
+++ b/src/core/load-fragment.c
@@ -1015,6 +1015,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 44dd8348be..6bffd6f362 100644
--- a/src/core/main.c
+++ b/src/core/main.c
@@ -604,8 +604,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 fa8efdddd2..acf28d82c4 100644
--- a/src/test/test-execute.c
+++ b/src/test/test-execute.c
@@ -625,6 +625,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;
@@ -672,6 +680,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,