diff --git a/man/systemd.unit.xml b/man/systemd.unit.xml index 3d0f0ff87c5..b6f4728b009 100644 --- a/man/systemd.unit.xml +++ b/man/systemd.unit.xml @@ -1626,6 +1626,11 @@ Runtime directory root This is either /run (for the system manager) or the path $XDG_RUNTIME_DIR resolves to (for user managers). + + %T + Directory for temporary files + This is either /tmp or the path $TMPDIR, $TEMP or $TMP are set to. + %u User name @@ -1641,6 +1646,11 @@ Kernel release Identical to uname -r output + + %V + Directory for larger and persistent temporary files + This is either /var/tmp or the path $TMPDIR, $TEMP or $TMP are set to. + %% Single percent sign diff --git a/man/tmpfiles.d.xml b/man/tmpfiles.d.xml index 30809f25f00..46bec912c52 100644 --- a/man/tmpfiles.d.xml +++ b/man/tmpfiles.d.xml @@ -651,6 +651,11 @@ r! /tmp/.X[0-9]*-lock System or user runtime directory In --user mode, this is the same $XDG_RUNTIME_DIR, and /run otherwise. + + %T + Directory for temporary files + This is either /tmp or the path $TMPDIR, $TEMP or $TMP are set to. + %u User name @@ -666,6 +671,11 @@ r! /tmp/.X[0-9]*-lock Kernel release Identical to uname -r output. + + %V + Directory for larger and persistent temporary files + This is either /var/tmp or the path $TMPDIR, $TEMP or $TMP are set to. + %% Escaped % diff --git a/src/core/unit-printf.c b/src/core/unit-printf.c index d2948ab6aad..20891200bad 100644 --- a/src/core/unit-printf.c +++ b/src/core/unit-printf.c @@ -232,6 +232,8 @@ int unit_full_printf(Unit *u, const char *format, char **ret) { * %S: the state directory root (e.g. /var/lib or $XDG_CONFIG_HOME) * %C: the cache directory root (e.g. /var/cache or $XDG_CACHE_HOME) * %L: the log directory root (e.g. /var/log or $XDG_CONFIG_HOME/log) + * %T: the temporary directory (e.g. /tmp, or $TMPDIR, $TEMP, $TMP) + * %V: the temporary directory for large, persistent stuff (e.g. /var/tmp, or $TMPDIR, $TEMP, $TMP) * * %h: the homedir of the running user * %s: the shell of the running user @@ -257,10 +259,13 @@ int unit_full_printf(Unit *u, const char *format, char **ret) { { 'c', specifier_cgroup, NULL }, { 'r', specifier_cgroup_slice, NULL }, { 'R', specifier_cgroup_root, NULL }, + { 't', specifier_special_directory, UINT_TO_PTR(EXEC_DIRECTORY_RUNTIME) }, { 'S', specifier_special_directory, UINT_TO_PTR(EXEC_DIRECTORY_STATE) }, { 'C', specifier_special_directory, UINT_TO_PTR(EXEC_DIRECTORY_CACHE) }, { 'L', specifier_special_directory, UINT_TO_PTR(EXEC_DIRECTORY_LOGS) }, + { 'T', specifier_tmp_dir, NULL }, + { 'V', specifier_var_tmp_dir, NULL }, { 'U', specifier_user_id, NULL }, { 'u', specifier_user_name, NULL }, diff --git a/src/shared/specifier.c b/src/shared/specifier.c index 27782b8d5b2..c4b2bdc12d7 100644 --- a/src/shared/specifier.c +++ b/src/shared/specifier.c @@ -15,6 +15,7 @@ #include "sd-id128.h" #include "alloc-util.h" +#include "fs-util.h" #include "hostname-util.h" #include "macro.h" #include "specifier.h" @@ -222,6 +223,40 @@ int specifier_user_shell(char specifier, void *data, void *userdata, char **ret) return get_shell(ret); } +int specifier_tmp_dir(char specifier, void *data, void *userdata, char **ret) { + const char *p; + char *copy; + int r; + + r = tmp_dir(&p); + if (r < 0) + return r; + + copy = strdup(p); + if (!copy) + return -ENOMEM; + + *ret = copy; + return 0; +} + +int specifier_var_tmp_dir(char specifier, void *data, void *userdata, char **ret) { + const char *p; + char *copy; + int r; + + r = var_tmp_dir(&p); + if (r < 0) + return r; + + copy = strdup(p); + if (!copy) + return -ENOMEM; + + *ret = copy; + return 0; +} + int specifier_escape_strv(char **l, char ***ret) { char **z, **p, **q; diff --git a/src/shared/specifier.h b/src/shared/specifier.h index b998c2a7592..33c0e2727e7 100644 --- a/src/shared/specifier.h +++ b/src/shared/specifier.h @@ -31,6 +31,9 @@ int specifier_user_id(char specifier, void *data, void *userdata, char **ret); int specifier_user_home(char specifier, void *data, void *userdata, char **ret); int specifier_user_shell(char specifier, void *data, void *userdata, char **ret); +int specifier_tmp_dir(char specifier, void *data, void *userdata, char **ret); +int specifier_var_tmp_dir(char specifier, void *data, void *userdata, char **ret); + static inline char* specifier_escape(const char *string) { return strreplace(string, "%", "%%"); } diff --git a/src/sysusers/sysusers.c b/src/sysusers/sysusers.c index af041d2f74b..b521200346d 100644 --- a/src/sysusers/sysusers.c +++ b/src/sysusers/sysusers.c @@ -1359,10 +1359,12 @@ static bool item_equal(Item *a, Item *b) { static int parse_line(const char *fname, unsigned line, const char *buffer) { static const Specifier specifier_table[] = { - { 'm', specifier_machine_id, NULL }, - { 'b', specifier_boot_id, NULL }, - { 'H', specifier_host_name, NULL }, + { 'm', specifier_machine_id, NULL }, + { 'b', specifier_boot_id, NULL }, + { 'H', specifier_host_name, NULL }, { 'v', specifier_kernel_release, NULL }, + { 'T', specifier_tmp_dir, NULL }, + { 'V', specifier_var_tmp_dir, NULL }, {} }; diff --git a/src/tmpfiles/tmpfiles.c b/src/tmpfiles/tmpfiles.c index 9a9cfdd8a28..049e24b8bd0 100644 --- a/src/tmpfiles/tmpfiles.c +++ b/src/tmpfiles/tmpfiles.c @@ -179,10 +179,13 @@ static const Specifier specifier_table[] = { { 'U', specifier_user_id, NULL }, { 'u', specifier_user_name, NULL }, { 'h', specifier_user_home, NULL }, + { 't', specifier_directory, UINT_TO_PTR(DIRECTORY_RUNTIME) }, { 'S', specifier_directory, UINT_TO_PTR(DIRECTORY_STATE) }, { 'C', specifier_directory, UINT_TO_PTR(DIRECTORY_CACHE) }, { 'L', specifier_directory, UINT_TO_PTR(DIRECTORY_LOGS) }, + { 'T', specifier_tmp_dir, NULL }, + { 'V', specifier_var_tmp_dir, NULL }, {} }; diff --git a/test/test-execute/exec-specifier.service b/test/test-execute/exec-specifier.service index 926d45182b1..e46373ddfe7 100644 --- a/test/test-execute/exec-specifier.service +++ b/test/test-execute/exec-specifier.service @@ -16,6 +16,8 @@ ExecStart=test %t = /run ExecStart=test %S = /var/lib ExecStart=test %C = /var/cache ExecStart=test %L = /var/log +ExecStart=test %T = /tmp +ExecStart=test %V = /var/tmp ExecStart=sh -c 'test %u = $$(id -un 0)' ExecStart=test %U = 0 ExecStart=sh -c 'test %h = $$(getent passwd 0 | cut -d: -f 6)'