]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
systemd-tmpfiles: allow appending content to file 13709/head
authorZach Smith <z@zxmth.us>
Fri, 4 Oct 2019 01:19:18 +0000 (18:19 -0700)
committerZach Smith <z@zxmth.us>
Fri, 4 Oct 2019 01:28:15 +0000 (18:28 -0700)
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
src/tmpfiles/tmpfiles.c

index dce05c364fe17e2e98520607753dde40835c3d37..726ae93e713d21b9a487b2a2ece4a83b2ff91b24 100644 (file)
@@ -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</programlisting>
         </varlistentry>
 
         <varlistentry>
-          <term><varname>w</varname></term>
-          <listitem><para>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.</para></listitem>
+          <term><varname>w, w+</varname></term>
+          <listitem><para>Write the argument parameter to a file, if the file exists.
+          If suffixed with <varname>+</varname>, the line will be appended to the file.
+          If your configuration writes multiple lines to the same file, use <varname>w+</varname>.
+          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.</para></listitem>
         </varlistentry>
 
         <varlistentry>
index 5630cddb4dbcc06be8fd458070964091d4537017..19a2aa6f21eee3782b6b1a7b8d65a67fd6ac31be 100644 (file)
@@ -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;