logind-inhibit.c revision 527b7a421ff3927d4f3f170b1b143452e88ae1dc
f8e2fb7b14e53f5a4bcfd66d26910af1dee185c6Lennart Poettering/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
f8e2fb7b14e53f5a4bcfd66d26910af1dee185c6Lennart Poettering This file is part of systemd.
f8e2fb7b14e53f5a4bcfd66d26910af1dee185c6Lennart Poettering Copyright 2012 Lennart Poettering
f8e2fb7b14e53f5a4bcfd66d26910af1dee185c6Lennart Poettering systemd is free software; you can redistribute it and/or modify it
f8e2fb7b14e53f5a4bcfd66d26910af1dee185c6Lennart Poettering under the terms of the GNU Lesser General Public License as published by
f8e2fb7b14e53f5a4bcfd66d26910af1dee185c6Lennart Poettering the Free Software Foundation; either version 2.1 of the License, or
f8e2fb7b14e53f5a4bcfd66d26910af1dee185c6Lennart Poettering (at your option) any later version.
f8e2fb7b14e53f5a4bcfd66d26910af1dee185c6Lennart Poettering systemd is distributed in the hope that it will be useful, but
f8e2fb7b14e53f5a4bcfd66d26910af1dee185c6Lennart Poettering WITHOUT ANY WARRANTY; without even the implied warranty of
f8e2fb7b14e53f5a4bcfd66d26910af1dee185c6Lennart Poettering MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
f8e2fb7b14e53f5a4bcfd66d26910af1dee185c6Lennart Poettering Lesser General Public License for more details.
f8e2fb7b14e53f5a4bcfd66d26910af1dee185c6Lennart Poettering You should have received a copy of the GNU Lesser General Public License
f8e2fb7b14e53f5a4bcfd66d26910af1dee185c6Lennart Poettering along with systemd; If not, see <http://www.gnu.org/licenses/>.
f8e2fb7b14e53f5a4bcfd66d26910af1dee185c6Lennart PoetteringInhibitor* inhibitor_new(Manager *m, const char* id) {
f8e2fb7b14e53f5a4bcfd66d26910af1dee185c6Lennart Poettering i->state_file = strappend("/run/systemd/inhibit/", id);
2b6bf07dd23bb467099d213c97b3875c5e453491Zbigniew Jędrzejewski-Szmek i->id = basename(i->state_file);
f8e2fb7b14e53f5a4bcfd66d26910af1dee185c6Lennart Poettering if (hashmap_put(m->inhibitors, i->id, i) < 0) {
f8e2fb7b14e53f5a4bcfd66d26910af1dee185c6Lennart Poettering hashmap_remove(i->manager->inhibitors, i->id);
d2e54fae5ca7a0f71b5ac8b356a589ff0a09ea0aKay Sievers r = mkdir_safe_label("/run/systemd/inhibit", 0755, 0, 0);
f8e2fb7b14e53f5a4bcfd66d26910af1dee185c6Lennart Poettering r = fopen_temporary(i->state_file, &f, &temp_path);
f8e2fb7b14e53f5a4bcfd66d26910af1dee185c6Lennart Poettering "# This is private data. Do not parse.\n"
f8e2fb7b14e53f5a4bcfd66d26910af1dee185c6Lennart Poettering if (ferror(f) || rename(temp_path, i->state_file) < 0) {
da927ba997d68401563b927f92e6e40e021a8e5cMichal Schmidt log_error_errno(r, "Failed to save inhibit data %s: %m", i->state_file);
de0671ee7fe465e108f62dcbbbe9366f81dd9e9aZbigniew Jędrzejewski-Szmek log_debug("Inhibitor %s (%s) pid="PID_FMT" uid="UID_FMT" mode=%s started.",
cc3773810855956bad92337cee8fa193584ab62eLennart Poettering manager_send_changed(i->manager, i->mode == INHIBIT_BLOCK ? "BlockInhibited" : "DelayInhibited", NULL);
de0671ee7fe465e108f62dcbbbe9366f81dd9e9aZbigniew Jędrzejewski-Szmek log_debug("Inhibitor %s (%s) pid="PID_FMT" uid="UID_FMT" mode=%s stopped.",
cc3773810855956bad92337cee8fa193584ab62eLennart Poettering manager_send_changed(i->manager, i->mode == INHIBIT_BLOCK ? "BlockInhibited" : "DelayInhibited", NULL);
f8e2fb7b14e53f5a4bcfd66d26910af1dee185c6Lennart Poettering r = parse_env_file(i->state_file, NEWLINE,
eecd1362f7f4de432483b5d77c56726c3621a83aLennart Poettering w = what ? inhibit_what_from_string(what) : 0;
eecd1362f7f4de432483b5d77c56726c3621a83aLennart Poettering mm = mode ? inhibit_mode_from_string(mode) : INHIBIT_BLOCK;
cc3773810855956bad92337cee8fa193584ab62eLennart Poetteringstatic int inhibitor_dispatch_fifo(sd_event_source *s, int fd, uint32_t revents, void *userdata) {
f8e2fb7b14e53f5a4bcfd66d26910af1dee185c6Lennart Poettering /* Create FIFO */
d2e54fae5ca7a0f71b5ac8b356a589ff0a09ea0aKay Sievers r = mkdir_safe_label("/run/systemd/inhibit", 0755, 0, 0);
cc3773810855956bad92337cee8fa193584ab62eLennart Poettering i->fifo_path = strjoin("/run/systemd/inhibit/", i->id, ".ref", NULL);
f8e2fb7b14e53f5a4bcfd66d26910af1dee185c6Lennart Poettering if (mkfifo(i->fifo_path, 0600) < 0 && errno != EEXIST)
f8e2fb7b14e53f5a4bcfd66d26910af1dee185c6Lennart Poettering /* Open reading side */
f8e2fb7b14e53f5a4bcfd66d26910af1dee185c6Lennart Poettering i->fifo_fd = open(i->fifo_path, O_RDONLY|O_CLOEXEC|O_NDELAY);
151b9b9662a90455262ce575a8a8ae74bf4ff336Lennart Poettering r = sd_event_add_io(i->manager->event, &i->event_source, i->fifo_fd, 0, inhibitor_dispatch_fifo, i);
718db96199eb307751264e4163555662c9a389faLennart Poettering r = sd_event_source_set_priority(i->event_source, SD_EVENT_PRIORITY_IDLE);
f8e2fb7b14e53f5a4bcfd66d26910af1dee185c6Lennart Poettering /* Open writing side */
f8e2fb7b14e53f5a4bcfd66d26910af1dee185c6Lennart Poettering r = open(i->fifo_path, O_WRONLY|O_CLOEXEC|O_NDELAY);
f8e2fb7b14e53f5a4bcfd66d26910af1dee185c6Lennart Poetteringvoid inhibitor_remove_fifo(Inhibitor *i) {
03e334a1c7dc8c20c38902aa039440763acc9b17Lennart Poettering i->event_source = sd_event_source_unref(i->event_source);
eecd1362f7f4de432483b5d77c56726c3621a83aLennart PoetteringInhibitWhat manager_inhibit_what(Manager *m, InhibitMode mm) {
beaafb2ea6be591882aef21fe19b88e3b2461087Lennart Poetteringstatic int pid_is_active(Manager *m, pid_t pid) {
beaafb2ea6be591882aef21fe19b88e3b2461087Lennart Poettering r = manager_get_session_by_pid(m, pid, &s);
2c4f86c1298f402220965682ab0e7729e150a562Lennart Poettering /* If there's no session assigned to it, then it's globally
2c4f86c1298f402220965682ab0e7729e150a562Lennart Poettering * active on all ttys */
c7b5eb98e8eeafe63a079ee3c51e9670872437aeLennart Poettering if (!(i->what & w))
409133be63387fc04d927e8aecd2f6ba03d2f143Lennart Poettering if (ignore_inactive && pid_is_active(m, i->pid) <= 0)
f8e2fb7b14e53f5a4bcfd66d26910af1dee185c6Lennart Poetteringconst char *inhibit_what_to_string(InhibitWhat w) {
f8e2fb7b14e53f5a4bcfd66d26910af1dee185c6Lennart Poettering if (w < 0 || w >= _INHIBIT_WHAT_MAX)
f8e2fb7b14e53f5a4bcfd66d26910af1dee185c6Lennart PoetteringInhibitWhat inhibit_what_from_string(const char *s) {
a2a5291b3f5ab6ed4c92f51d0fd10a03047380d8Zbigniew Jędrzejewski-Szmek FOREACH_WORD_SEPARATOR(word, l, s, ":", state) {
a2a5291b3f5ab6ed4c92f51d0fd10a03047380d8Zbigniew Jędrzejewski-Szmek if (l == 8 && strneq(word, "shutdown", l))
a2a5291b3f5ab6ed4c92f51d0fd10a03047380d8Zbigniew Jędrzejewski-Szmek else if (l == 5 && strneq(word, "sleep", l))
a2a5291b3f5ab6ed4c92f51d0fd10a03047380d8Zbigniew Jędrzejewski-Szmek else if (l == 4 && strneq(word, "idle", l))
a2a5291b3f5ab6ed4c92f51d0fd10a03047380d8Zbigniew Jędrzejewski-Szmek else if (l == 16 && strneq(word, "handle-power-key", l))
a2a5291b3f5ab6ed4c92f51d0fd10a03047380d8Zbigniew Jędrzejewski-Szmek else if (l == 18 && strneq(word, "handle-suspend-key", l))
a2a5291b3f5ab6ed4c92f51d0fd10a03047380d8Zbigniew Jędrzejewski-Szmek else if (l == 20 && strneq(word, "handle-hibernate-key", l))
a2a5291b3f5ab6ed4c92f51d0fd10a03047380d8Zbigniew Jędrzejewski-Szmek else if (l == 17 && strneq(word, "handle-lid-switch", l))
eecd1362f7f4de432483b5d77c56726c3621a83aLennart Poetteringstatic const char* const inhibit_mode_table[_INHIBIT_MODE_MAX] = {