+ if (arg_nice_set) {
+ if (setpriority(PRIO_PROCESS, 0, arg_nice) < 0) {
+ log_error("Failed to set nice level: %m");
+ return -errno;
+ }
+ }
+
+ if (arg_exec_group) {
+ gid_t gid;
+
+ r = get_group_creds(&arg_exec_group, &gid);
+ if (r < 0) {
+ log_error("Failed to resolve group %s: %s", arg_exec_group, strerror(-r));
+ return r;
+ }
+
+ if (setresgid(gid, gid, gid) < 0) {
+ log_error("Failed to change GID to " GID_FMT ": %m", gid);
+ return -errno;
+ }
+ }
+
+ if (arg_exec_user) {
+ const char *home, *shell;
+ uid_t uid;
+ gid_t gid;
+
+ r = get_user_creds(&arg_exec_user, &uid, &gid, &home, &shell);
+ if (r < 0) {
+ log_error("Failed to resolve user %s: %s", arg_exec_user, strerror(-r));
+ return r;
+ }
+
+ r = strv_extendf(&user_env, "HOME=%s", home);
+ if (r < 0)
+ return log_oom();
+
+ r = strv_extendf(&user_env, "SHELL=%s", shell);
+ if (r < 0)
+ return log_oom();
+
+ r = strv_extendf(&user_env, "USER=%s", arg_exec_user);
+ if (r < 0)
+ return log_oom();
+
+ r = strv_extendf(&user_env, "LOGNAME=%s", arg_exec_user);
+ if (r < 0)
+ return log_oom();
+
+ if (!arg_exec_group) {
+ if (setresgid(gid, gid, gid) < 0) {
+ log_error("Failed to change GID to " GID_FMT ": %m", gid);
+ return -errno;
+ }
+ }
+
+ if (setresuid(uid, uid, uid) < 0) {
+ log_error("Failed to change UID to " UID_FMT ": %m", uid);
+ return -errno;
+ }
+ }
+
+ env = strv_env_merge(3, environ, user_env, arg_environment);
+ if (!env)
+ return log_oom();
+
+ log_info("Running as unit %s.", name);
+
+ execvpe(argv[0], argv, env);