diff --git a/man/systemd.exec.xml b/man/systemd.exec.xml
index c25d96e9f..f1624923c 100644
--- a/man/systemd.exec.xml
+++ b/man/systemd.exec.xml
@@ -1247,6 +1247,135 @@
+
+ Environment variables in spawned processes
+
+ Processes started by the system are executed in
+ a clean environment in which select variables
+ listed below are set. System processes started by systemd
+ do not inherit variables from PID 1, but processes
+ started by user systemd instances inherit all
+ environment variables from the user systemd instance.
+
+
+
+
+ $PATH
+
+ Colon-separated list
+ of directiories to use when launching
+ executables. Systemd uses a fixed
+ value of
+ /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin.
+
+
+
+
+ $LANG
+
+ Locale. Can be set in
+ locale.conf5
+ or on the kernel command line (see
+ systemd1
+ and
+ kernel-command-line7).
+
+
+
+
+ $USER
+ $LOGNAME
+ $HOME
+ $SHELL
+
+ User name (twice), home
+ directory, and the login shell.
+ Set for the units which
+ have User= set,
+ which includes user
+ systemd instances.
+ See
+ passwd5.
+
+
+
+
+ $XDG_RUNTIME_DIR
+
+ The directory for volatile
+ state. Set for the user systemd
+ instance, and also in user sessions.
+ See
+ pam_systemd8.
+
+
+
+
+ $XDG_SESSION_ID
+ $XDG_SEAT
+ $XDG_VTNR
+
+ The identifier of the
+ session, and the seat name, and
+ virtual terminal of the session. Set
+ by
+ pam_systemd8
+ for login sessions.
+ $XDG_SEAT and
+ $XDG_VTNR will be
+ only set when attached to a seat and a
+ tty.
+
+
+
+ $MANAGERPID
+
+ The PID of the user
+ systemd instance,
+ set for processes spawned by it.
+
+
+
+
+ $LISTEN_FDS
+ $LISTEN_PID
+
+ Information about file
+ descriptors passed to a service for
+ socket activation. See
+ sd_listen_fds3.
+
+
+
+
+ $TERM
+
+ Terminal type, set
+ only for units connected to a terminal
+ (StandardInput=tty,
+ StandardOutput=tty,
+ or
+ StandardError=tty).
+ See
+ termcap5.
+
+
+
+
+ Additional variables may be configured by the
+ following means: for processes spawned in specific
+ units, use the Environment= and
+ EnvironmentFile= options above; to
+ specify variables globally, use
+ DefaultEnvironment= (see
+ systemd-system.conf5)
+ or the kernel option
+ systemd.setenv= (see
+ systemd1). Additional
+ variables may also be set through PAM,
+ c.f. pam_env8.
+
+
See Also
diff --git a/src/core/execute.c b/src/core/execute.c
index 11993df01..4da44c2ea 100644
--- a/src/core/execute.c
+++ b/src/core/execute.c
@@ -1065,7 +1065,7 @@ int exec_spawn(ExecCommand *command,
if (pid == 0) {
int i, err;
sigset_t ss;
- const char *username = NULL, *home = NULL;
+ const char *username = NULL, *home = NULL, *shell = NULL;
uid_t uid = (uid_t) -1;
gid_t gid = (gid_t) -1;
char _cleanup_strv_free_ **our_env = NULL, **pam_env = NULL,
@@ -1255,7 +1255,7 @@ int exec_spawn(ExecCommand *command,
if (context->user) {
username = context->user;
- err = get_user_creds(&username, &uid, &gid, &home, NULL);
+ err = get_user_creds(&username, &uid, &gid, &home, &shell);
if (err < 0) {
r = EXIT_USER;
goto fail_child;
@@ -1453,46 +1453,28 @@ int exec_spawn(ExecCommand *command,
}
}
- our_env = new0(char*, 7);
- if (!our_env) {
+ our_env = new(char*, 8);
+ if (!our_env ||
+ (n_fds > 0 && (
+ asprintf(our_env + n_env++, "LISTEN_PID=%lu", (unsigned long) getpid()) < 0 ||
+ asprintf(our_env + n_env++, "LISTEN_FDS=%u", n_fds) < 0)) ||
+ (home && asprintf(our_env + n_env++, "HOME=%s", home) < 0) ||
+ (username && (
+ asprintf(our_env + n_env++, "LOGNAME=%s", username) < 0 ||
+ asprintf(our_env + n_env++, "USER=%s", username) < 0)) ||
+ (shell && asprintf(our_env + n_env++, "SHELL=%s", shell) < 0) ||
+ ((is_terminal_input(context->std_input) ||
+ context->std_output == EXEC_OUTPUT_TTY ||
+ context->std_error == EXEC_OUTPUT_TTY) && (
+ !(our_env[n_env++] = strdup(default_term_for_tty(tty_path(context))))))) {
+
err = -ENOMEM;
r = EXIT_MEMORY;
goto fail_child;
}
- if (n_fds > 0)
- if (asprintf(our_env + n_env++, "LISTEN_PID=%lu", (unsigned long) getpid()) < 0 ||
- asprintf(our_env + n_env++, "LISTEN_FDS=%u", n_fds) < 0) {
- err = -ENOMEM;
- r = EXIT_MEMORY;
- goto fail_child;
- }
-
- if (home)
- if (asprintf(our_env + n_env++, "HOME=%s", home) < 0) {
- err = -ENOMEM;
- r = EXIT_MEMORY;
- goto fail_child;
- }
-
- if (username)
- if (asprintf(our_env + n_env++, "LOGNAME=%s", username) < 0 ||
- asprintf(our_env + n_env++, "USER=%s", username) < 0) {
- err = -ENOMEM;
- r = EXIT_MEMORY;
- goto fail_child;
- }
-
- if (is_terminal_input(context->std_input) ||
- context->std_output == EXEC_OUTPUT_TTY ||
- context->std_error == EXEC_OUTPUT_TTY)
- if (!(our_env[n_env++] = strdup(default_term_for_tty(tty_path(context))))) {
- err = -ENOMEM;
- r = EXIT_MEMORY;
- goto fail_child;
- }
-
- assert(n_env <= 7);
+ our_env[n_env++] = NULL;
+ assert(n_env <= 8);
final_env = strv_env_merge(5,
environment,