diff options
author | Auke Kok <auke-jan.h.kok@intel.com> | 2012-07-13 22:28:43 -0700 |
---|---|---|
committer | Lennart Poettering <lennart@poettering.net> | 2012-07-16 12:25:25 +0200 |
commit | b2896c905bef7be7ed9a760d9d61aa6ad0f614a3 (patch) | |
tree | 618cd1bb963e9a1904452a4db4d0063d2a5ff8e7 /src/core/unit.c | |
parent | 7c5f152acafcf0964db2f3a111195b3b2f36176f (diff) |
unit: printf specifiers %u and %h: $USER and $HOME.
These printf specifiers allow us to refer to $HOME and $USER
in unit files. These are particularly helpful in instanced
units that have "User=" set, and in systemd --user domains.
The specifiers will return the pw_name and pw_dir fields
if the unit file has a User= field.
If the unit file does not have a User= field, the value
substituted is either $USER or $HOME from the environment,
or, if unset, the values from pw_name or pw_dir.
This patch is somewhat after Ran Benita's original patch,
which didn't get merged. I've split up the 2 specifiers
and extended them to do what is logically expected from
these specifiers.
Note that expansion is done at `start` time, not after
the units are parsed. Using `systemctl show` will just
show the specifiers.
Diffstat (limited to 'src/core/unit.c')
-rw-r--r-- | src/core/unit.c | 46 |
1 files changed, 46 insertions, 0 deletions
diff --git a/src/core/unit.c b/src/core/unit.c index 6914ccdb99..ed519b3bd5 100644 --- a/src/core/unit.c +++ b/src/core/unit.c @@ -2221,6 +2221,48 @@ static char *specifier_runtime(char specifier, void *data, void *userdata) { return strdup("/run"); } +static char *specifier_user_name(char specifier, void *data, void *userdata) { + Service *s = userdata; + int r; + const char *username; + + /* get USER env from our own env if set */ + if (!s->exec_context.user) + return getusername_malloc(); + + /* fish username from passwd */ + username = s->exec_context.user; + r = get_user_creds(&username, NULL, NULL, NULL); + if (r < 0) + return NULL; + + return strdup(username); +} + +static char *specifier_user_home(char specifier, void *data, void *userdata) { + Service *s = userdata; + int r; + const char *username, *home; + + /* return HOME if set, otherwise from passwd */ + if (!s->exec_context.user) { + char *h; + + r = get_home_dir(&h); + if (r < 0) + return NULL; + + return h; + } + + username = s->exec_context.user; + r = get_user_creds(&username, NULL, NULL, &home); + if (r < 0) + return NULL; + + return strdup(home); +} + char *unit_name_printf(Unit *u, const char* format) { /* @@ -2256,6 +2298,8 @@ char *unit_full_printf(Unit *u, const char *format) { * %r root cgroup path of this systemd instance (e.g. "/user/lennart/shared/systemd-4711") * %R parent of root cgroup path (e.g. "/usr/lennart/shared") * %t the runtime directory to place sockets in (e.g. "/run" or $XDG_RUNTIME_DIR) + * %u the username of the configured User or running user + * %h the homedir of the configured User or running user */ const Specifier table[] = { @@ -2270,6 +2314,8 @@ char *unit_full_printf(Unit *u, const char *format) { { 'r', specifier_cgroup_root, NULL }, { 'R', specifier_cgroup_root, NULL }, { 't', specifier_runtime, NULL }, + { 'u', specifier_user_name, NULL }, + { 'h', specifier_user_home, NULL }, { 0, NULL, NULL } }; |