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