diff options
author | Lennart Poettering <lennart@poettering.net> | 2011-07-13 19:58:35 +0200 |
---|---|---|
committer | Lennart Poettering <lennart@poettering.net> | 2011-07-13 19:59:28 +0200 |
commit | de07ab16c6b919cead26c9a5209a362127ff6142 (patch) | |
tree | 9b4d4f674ae5fa607fb8516be541d16dcca9e9c8 /src/logind-session.c | |
parent | a17204af0e950be7a5199db62ef400814e29aa3c (diff) |
loginctl: implement missing kill verb
Diffstat (limited to 'src/logind-session.c')
-rw-r--r-- | src/logind-session.c | 53 |
1 files changed, 51 insertions, 2 deletions
diff --git a/src/logind-session.c b/src/logind-session.c index ab4de66ca4..201cd394ec 100644 --- a/src/logind-session.c +++ b/src/logind-session.c @@ -588,7 +588,7 @@ static bool session_shall_kill(Session *s) { return strv_contains(s->manager->kill_only_users, s->user->name); } -static int session_kill_cgroup(Session *s) { +static int session_terminate_cgroup(Session *s) { int r; char **k; @@ -661,7 +661,7 @@ int session_stop(Session *s) { log_info("Removed session %s.", s->id); /* Kill cgroup */ - k = session_kill_cgroup(s); + k = session_terminate_cgroup(s); if (k < 0) r = k; @@ -886,6 +886,48 @@ void session_add_to_gc_queue(Session *s) { s->in_gc_queue = true; } +int session_kill(Session *s, KillWho who, int signo) { + int r = 0; + Set *pid_set = NULL; + + assert(s); + + if (!s->cgroup_path) + return -ESRCH; + + if (s->leader <= 0 && who == KILL_LEADER) + return -ESRCH; + + if (s->leader > 0) + if (kill(s->leader, signo) < 0) + r = -errno; + + if (who == KILL_ALL) { + int q; + + pid_set = set_new(trivial_hash_func, trivial_compare_func); + if (!pid_set) + return -ENOMEM; + + if (s->leader > 0) { + q = set_put(pid_set, LONG_TO_PTR(s->leader)); + if (q < 0) + r = q; + } + + q = cg_kill_recursive(SYSTEMD_CGROUP_CONTROLLER, s->cgroup_path, signo, false, true, false, pid_set); + if (q < 0) + if (q != -EAGAIN && q != -ESRCH && q != -ENOENT) + r = q; + } + +finish: + if (pid_set) + set_free(pid_set); + + return r; +} + static const char* const session_type_table[_SESSION_TYPE_MAX] = { [SESSION_TTY] = "tty", [SESSION_X11] = "x11", @@ -893,3 +935,10 @@ static const char* const session_type_table[_SESSION_TYPE_MAX] = { }; DEFINE_STRING_TABLE_LOOKUP(session_type, SessionType); + +static const char* const kill_who_table[_KILL_WHO_MAX] = { + [KILL_LEADER] = "leader", + [KILL_ALL] = "all" +}; + +DEFINE_STRING_TABLE_LOOKUP(kill_who, KillWho); |