diff options
author | Lennart Poettering <lennart@poettering.net> | 2015-09-23 19:46:23 +0200 |
---|---|---|
committer | Lennart Poettering <lennart@poettering.net> | 2015-09-29 21:55:51 +0200 |
commit | 5f5d8eab1f2f5f5e088bc301533b3e4636de96c7 (patch) | |
tree | d5341f3e35dc5cef2105368633c145ee75553545 /src/core/load-fragment.c | |
parent | 0521e286fc34d1ab58edc1a3fab7b8285c4b36e5 (diff) |
core: allow setting WorkingDirectory= to the special value ~
If set to ~ the working directory is set to the home directory of the
user configured in User=.
This change also exposes the existing switch for the working directory
that allowed making missing working directories non-fatal.
This also changes "machinectl shell" to make use of this to ensure that
the invoked shell is by default in the user's home directory.
Fixes #1268.
Diffstat (limited to 'src/core/load-fragment.c')
-rw-r--r-- | src/core/load-fragment.c | 129 |
1 files changed, 96 insertions, 33 deletions
diff --git a/src/core/load-fragment.c b/src/core/load-fragment.c index a13f42b5e0..7045c31f2e 100644 --- a/src/core/load-fragment.c +++ b/src/core/load-fragment.c @@ -20,44 +20,42 @@ along with systemd; If not, see <http://www.gnu.org/licenses/>. ***/ -#include <linux/oom.h> #include <errno.h> -#include <string.h> #include <fcntl.h> -#include <sched.h> #include <linux/fs.h> -#include <sys/stat.h> +#include <linux/oom.h> +#include <sched.h> +#include <string.h> #include <sys/resource.h> - +#include <sys/stat.h> #ifdef HAVE_SECCOMP #include <seccomp.h> #endif -#include "unit.h" -#include "strv.h" +#include "af-list.h" +#include "bus-error.h" +#include "bus-internal.h" +#include "bus-util.h" +#include "cap-list.h" +#include "cgroup.h" #include "conf-parser.h" -#include "load-fragment.h" -#include "log.h" +#include "env-util.h" +#include "errno-list.h" #include "ioprio.h" -#include "securebits.h" +#include "log.h" #include "missing.h" -#include "unit-name.h" -#include "unit-printf.h" -#include "utf8.h" #include "path-util.h" -#include "env-util.h" -#include "cgroup.h" -#include "bus-util.h" -#include "bus-error.h" -#include "errno-list.h" -#include "af-list.h" -#include "cap-list.h" -#include "signal-util.h" -#include "bus-internal.h" - #ifdef HAVE_SECCOMP #include "seccomp-util.h" #endif +#include "securebits.h" +#include "signal-util.h" +#include "strv.h" +#include "unit-name.h" +#include "unit-printf.h" +#include "unit.h" +#include "utf8.h" +#include "load-fragment.h" int config_parse_warn_compat( const char *unit, @@ -195,16 +193,17 @@ int config_parse_unit_strv_printf(const char *unit, k ? k : rvalue, data, userdata); } -int config_parse_unit_path_printf(const char *unit, - const char *filename, - unsigned line, - const char *section, - unsigned section_line, - const char *lvalue, - int ltype, - const char *rvalue, - void *data, - void *userdata) { +int config_parse_unit_path_printf( + const char *unit, + const char *filename, + unsigned line, + const char *section, + unsigned section_line, + const char *lvalue, + int ltype, + const char *rvalue, + void *data, + void *userdata) { _cleanup_free_ char *k = NULL; Unit *u = userdata; @@ -1846,6 +1845,70 @@ int config_parse_bus_endpoint_policy( return bus_endpoint_add_policy(c->bus_endpoint, name, access); } +int config_parse_working_directory( + const char *unit, + const char *filename, + unsigned line, + const char *section, + unsigned section_line, + const char *lvalue, + int ltype, + const char *rvalue, + void *data, + void *userdata) { + + ExecContext *c = data; + Unit *u = userdata; + bool missing_ok; + int r; + + assert(filename); + assert(lvalue); + assert(rvalue); + assert(c); + assert(u); + + if (rvalue[0] == '-') { + missing_ok = true; + rvalue++; + } else + missing_ok = false; + + if (streq(rvalue, "~")) { + c->working_directory_home = true; + c->working_directory = mfree(c->working_directory); + } else { + _cleanup_free_ char *k = NULL; + + r = unit_full_printf(u, rvalue, &k); + if (r < 0) { + log_syntax(unit, LOG_ERR, filename, line, r, "Failed to resolve unit specifiers in working directory path '%s', ignoring: %m", rvalue); + return 0; + } + + path_kill_slashes(k); + + if (!utf8_is_valid(k)) { + log_invalid_utf8(unit, LOG_ERR, filename, line, 0, rvalue); + return 0; + } + + if (!path_is_absolute(k)) { + log_syntax(unit, LOG_ERR, filename, line, 0, "Working directory path '%s' is not absolute, ignoring.", rvalue); + return 0; + } + + free(c->working_directory); + c->working_directory = k; + k = NULL; + + c->working_directory_home = false; + } + + c->working_directory_missing_ok = missing_ok; + return 0; +} + int config_parse_unit_env_file(const char *unit, const char *filename, unsigned line, |