diff --git a/TODO b/TODO
index 16a7bdf7aa..0bb9bc6205 100644
--- a/TODO
+++ b/TODO
@@ -949,7 +949,6 @@ Features:
* tmpfiles:
- apply "x" on "D" too (see patch from William Douglas)
- - replace F with f+.
- instead of ignoring unknown fields, reject them.
- creating new directories/subvolumes/fifos/device nodes
should not follow symlinks. None of the other adjustment or creation
diff --git a/man/tmpfiles.d.xml b/man/tmpfiles.d.xml
index 726ae93e71..aae63b7591 100644
--- a/man/tmpfiles.d.xml
+++ b/man/tmpfiles.d.xml
@@ -39,8 +39,9 @@
#Type Path Mode User Group Age Argument
f /file/to/create mode user group - content
-F /file/to/create-or-truncate mode user group - content
+f+ /file/to/create-or-truncate mode user group - content
w /file/to/write-to - - - - content
+w+ /file/to/append-to - - - - content
d /directory/to/create-and-cleanup mode user group cleanup-age -
D /directory/to/create-and-remove mode user group cleanup-age -
e /directory/to/cleanup mode user group cleanup-age -
@@ -48,10 +49,13 @@ v /subvolume/to/create mode user group - -
v /subvolume-or-directory/to/create mode user group - -
Q /subvolume/to/create mode user group - -
p /fifo/to/create mode user group - -
+p+ /fifo/to/[re]create mode user group - -
L /symlink/to/create - - - - symlink/target/path
+L+ /symlink/to/[re]create - - - - symlink/target/path
c /dev/char-device-to-create mode user group - -
+c+ /dev/char-device-to-[re]create mode user group - -
b /dev/block-device-to-create mode user group - -
-# p+, L+, c+, b+ create target unconditionally, w+ appends to the file
+b+ /dev/block-device-to-[re]create mode user group - -
C /target/to/create - - - - /source/to/copy
x /path-or-glob/to/ignore - - - - -
X /path-or-glob/to/ignore/recursively - - - - -
@@ -64,8 +68,10 @@ T /path-or-glob/to/set/xattrs/recursively - - - - xattr
h /path-or-glob/to/set/attrs - - - - file attrs
H /path-or-glob/to/set/attrs/recursively - - - - file attrs
a /path-or-glob/to/set/acls - - - - POSIX ACLs
+a+ /path-or-glob/to/append/acls - - - - POSIX ACLs
A /path-or-glob/to/set/acls/recursively - - - - POSIX ACLs
-# a+, A+ append ACLs
+A+ /path-or-glob/to/append/acls/recursively - - - - POSIX ACLs
+
@@ -155,19 +161,16 @@ L /tmp/foobar - - - - /dev/null
f
- Create a file if it does not exist yet. If the argument parameter is given and the file did
- not exist yet, it will be written to the file. Does not follow symlinks.
+ f+
+ f will create a file if it does not exist yet. If the argument
+ parameter is given and the file did not exist yet, it will be written to the file.
+ f+ will create or truncate the file. If the argument parameter is given, it will
+ be written to the file. Does not follow symlinks.
- F
- Create or truncate a file. If the argument
- parameter is given, it will be written to the file. Does not follow symlinks.
-
-
-
-
- w, w+
+ 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+.
diff --git a/src/tmpfiles/tmpfiles.c b/src/tmpfiles/tmpfiles.c
index f4f7705a32..193ed0bc78 100644
--- a/src/tmpfiles/tmpfiles.c
+++ b/src/tmpfiles/tmpfiles.c
@@ -72,7 +72,7 @@ typedef enum OperationMask {
typedef enum ItemType {
/* These ones take file names */
CREATE_FILE = 'f',
- TRUNCATE_FILE = 'F',
+ TRUNCATE_FILE = 'F', /* deprecated: use f+ */
CREATE_DIRECTORY = 'd',
TRUNCATE_DIRECTORY = 'D',
CREATE_SUBVOLUME = 'v',
@@ -1365,7 +1365,7 @@ static int truncate_file(Item *i, const char *path) {
assert(i);
assert(path);
- assert(i->type == TRUNCATE_FILE);
+ assert(i->type == TRUNCATE_FILE || (i->type == CREATE_FILE && i->append_or_force));
/* We want to operate on regular file exclusively especially since
* O_TRUNC is unspecified if the file is neither a regular file nor a
@@ -1922,20 +1922,16 @@ static int create_item(Item *i) {
case RECURSIVE_REMOVE_PATH:
return 0;
+ case TRUNCATE_FILE:
case CREATE_FILE:
RUN_WITH_UMASK(0000)
(void) mkdir_parents_label(i->path, 0755);
- r = create_file(i, i->path);
- if (r < 0)
- return r;
- break;
+ if ((i->type == CREATE_FILE && i->append_or_force) || i->type == TRUNCATE_FILE)
+ r = truncate_file(i, i->path);
+ else
+ r = create_file(i, i->path);
- case TRUNCATE_FILE:
- RUN_WITH_UMASK(0000)
- (void) mkdir_parents_label(i->path, 0755);
-
- r = truncate_file(i, i->path);
if (r < 0)
return r;
break;