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 | |
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.
-rw-r--r-- | man/systemd.unit.xml | 10 | ||||
-rw-r--r-- | src/core/unit.c | 46 |
2 files changed, 56 insertions, 0 deletions
diff --git a/man/systemd.unit.xml b/man/systemd.unit.xml index 3fd76f3020..3236bfa741 100644 --- a/man/systemd.unit.xml +++ b/man/systemd.unit.xml @@ -258,6 +258,16 @@ <entry>Runtime socket dir</entry> <entry>This is either /run (for the system manager) or $XDG_RUNTIME_DIR (for user managers).</entry> </row> + <row> + <entry><literal>%u</literal></entry> + <entry>User name</entry> + <entry>This is the name of the configured user of the unit, or (if none is set) the user running the systemd instance.</entry> + </row> + <row> + <entry><literal>%h</literal></entry> + <entry>User home directory</entry> + <entry>This is the home directory of the configured user of the unit, or (if none is set) the user running the systemd instance.</entry> + </row> </tbody> </tgroup> </table> 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 } }; |