diff --git a/execute.c b/execute.c index 31e1bdc252b..0374eaec5da 100644 --- a/execute.c +++ b/execute.c @@ -489,9 +489,16 @@ int exec_spawn(const ExecCommand *command, goto fail; } - if (setpgid(0, 0) < 0) { - r = EXIT_PGID; - goto fail; + if (context->new_session) { + if (setsid() < 0) { + r = EXIT_SETSID; + goto fail; + } + } else { + if (setpgid(0, 0) < 0) { + r = EXIT_PGID; + goto fail; + } } umask(context->umask); @@ -710,6 +717,12 @@ void exec_context_init(ExecContext *c) { c->cpu_sched_set = false; CPU_ZERO(&c->cpu_affinity); c->cpu_affinity_set = false; + c->timer_slack_ns = 0; + c->timer_slack_ns_set = false; + + c->cpu_sched_reset_on_fork = false; + c->non_blocking = false; + c->new_session = false; c->input = 0; c->output = 0; @@ -790,11 +803,13 @@ void exec_context_dump(ExecContext *c, FILE* f, const char *prefix) { "%sUMask: %04o\n" "%sWorkingDirectory: %s\n" "%sRootDirectory: %s\n" - "%sNonBlocking: %s\n", + "%sNonBlocking: %s\n" + "%sNewSession: %s\n", prefix, c->umask, prefix, c->working_directory ? c->working_directory : "/", prefix, c->root_directory ? c->root_directory : "/", - prefix, yes_no(c->non_blocking)); + prefix, yes_no(c->non_blocking), + prefix, yes_no(c->new_session)); if (c->environment) for (e = c->environment; *e; e++) diff --git a/execute.h b/execute.h index cb69bb3bd82..5099a824355 100644 --- a/execute.h +++ b/execute.h @@ -93,6 +93,7 @@ struct ExecContext { bool cpu_sched_reset_on_fork; bool non_blocking; + bool new_session; ExecInput input; ExecOutput output; @@ -148,7 +149,8 @@ typedef enum ExitStatus { EXIT_GROUP, EXIT_USER, EXIT_CAPABILITIES, - EXIT_CGROUP + EXIT_CGROUP, /* 220 */ + EXIT_SETSID } ExitStatus; int exec_spawn(const ExecCommand *command, diff --git a/load-fragment.c b/load-fragment.c index c0972d04fb6..bd84e8fe79b 100644 --- a/load-fragment.c +++ b/load-fragment.c @@ -1145,7 +1145,8 @@ static int load_from_path(Unit *u, const char *path, UnitLoadState *new_state) { { "LimitRTPRIO", config_parse_limit, &(context).rlimit[RLIMIT_RTPRIO], section }, \ { "LimitRTTIME", config_parse_limit, &(context).rlimit[RLIMIT_RTTIME], section }, \ { "NonBlocking", config_parse_bool, &(context).non_blocking, section }, \ - { "ControlGroup", config_parse_cgroup, u, section } \ + { "ControlGroup", config_parse_cgroup, u, section }, \ + { "NewSession", config_parse_bool, &(context).new_session, section } const ConfigItem items[] = { { "Names", config_parse_names, u, "Meta" },