From d0ea5c5e39dce60efbce6d86534eb9ca253440b0 Mon Sep 17 00:00:00 2001 From: Zach Smith Date: Thu, 3 Oct 2019 18:19:18 -0700 Subject: [PATCH] systemd-tmpfiles: allow appending content to file Adds support to append to files with w+ type. w /tmp/13291.out - - - - first line\n w+ /tmp/13291.out - - - - second line\n --- man/tmpfiles.d.xml | 16 ++++++++-------- src/tmpfiles/tmpfiles.c | 8 +++++--- 2 files changed, 13 insertions(+), 11 deletions(-) diff --git a/man/tmpfiles.d.xml b/man/tmpfiles.d.xml index dce05c364fe..726ae93e713 100644 --- a/man/tmpfiles.d.xml +++ b/man/tmpfiles.d.xml @@ -51,7 +51,7 @@ p /fifo/to/create mode user group - - L /symlink/to/create - - - - symlink/target/path c /dev/char-device-to-create mode user group - - b /dev/block-device-to-create mode user group - - -# p+, L+, c+, b+ create target unconditionally +# p+, L+, c+, b+ create target unconditionally, w+ appends to the file C /target/to/create - - - - /source/to/copy x /path-or-glob/to/ignore - - - - - X /path-or-glob/to/ignore/recursively - - - - - @@ -167,13 +167,13 @@ L /tmp/foobar - - - - /dev/null - w - Write the argument parameter to a file, if - the file exists. Lines of this type accept shell-style - globs in place of normal path names. The argument parameter - will be written without a trailing newline. C-style - backslash escapes are interpreted. Follows - symlinks. + w, w+ + Write the argument parameter to a file, if the file exists. + If suffixed with +, the line will be appended to the file. + If your configuration writes multiple lines to the same file, use w+. + Lines of this type accept shell-style globs in place of normal path names. + The argument parameter will be written without a trailing newline. + C-style backslash escapes are interpreted. Follows symlinks. diff --git a/src/tmpfiles/tmpfiles.c b/src/tmpfiles/tmpfiles.c index 5630cddb4db..19a2aa6f21e 100644 --- a/src/tmpfiles/tmpfiles.c +++ b/src/tmpfiles/tmpfiles.c @@ -1257,7 +1257,7 @@ static int path_set_attribute(Item *item, const char *path) { static int write_one_file(Item *i, const char *path) { _cleanup_close_ int fd = -1, dir_fd = -1; char *bn; - int r; + int flags, r; assert(i); assert(path); @@ -1272,8 +1272,10 @@ static int write_one_file(Item *i, const char *path) { bn = basename(path); + flags = O_NONBLOCK|O_CLOEXEC|O_WRONLY|O_NOCTTY; + /* Follows symlinks */ - fd = openat(dir_fd, bn, O_NONBLOCK|O_CLOEXEC|O_WRONLY|O_NOCTTY, i->mode); + fd = openat(dir_fd, bn, i->append_or_force ? flags|O_APPEND : flags, i->mode); if (fd < 0) { if (errno == ENOENT) { log_debug_errno(errno, "Not writing missing file \"%s\": %m", path); @@ -2794,7 +2796,7 @@ static int parse_line(const char *fname, unsigned line, const char *buffer, bool size_t n; for (n = 0; n < existing->n_items; n++) { - if (!item_compatible(existing->items + n, &i)) { + if (!item_compatible(existing->items + n, &i) && !i.append_or_force) { log_notice("[%s:%u] Duplicate line for path \"%s\", ignoring.", fname, line, i.path); return 0; -- 2.47.3