#include "util.h"
#include "mkdir.h"
-
+#include "path-util.h"
#include "logind-inhibit.h"
+#include "fileio.h"
Inhibitor* inhibitor_new(Manager *m, const char* id) {
Inhibitor *i;
return NULL;
}
- i->id = file_name_from_path(i->state_file);
+ i->id = path_get_file_name(i->state_file);
if (hashmap_put(m->inhibitors, i->id, i) < 0) {
free(i->state_file);
assert(i);
- r = safe_mkdir("/run/systemd/inhibit", 0755, 0, 0);
+ r = mkdir_safe_label("/run/systemd/inhibit", 0755, 0, 0);
if (r < 0)
goto finish;
fprintf(f,
"# This is private data. Do not parse.\n"
"WHAT=%s\n"
+ "MODE=%s\n"
"UID=%lu\n"
"PID=%lu\n",
inhibit_what_to_string(i->what),
+ inhibit_mode_to_string(i->mode),
(unsigned long) i->uid,
(unsigned long) i->pid);
if (i->started)
return 0;
- log_debug("Inhibitor %s (%s) pid=%lu uid=%lu started.",
+ dual_timestamp_get(&i->since);
+
+ log_debug("Inhibitor %s (%s) pid=%lu uid=%lu mode=%s started.",
strna(i->who), strna(i->why),
- (unsigned long) i->pid, (unsigned long) i->uid);
+ (unsigned long) i->pid, (unsigned long) i->uid,
+ inhibit_mode_to_string(i->mode));
inhibitor_save(i);
i->started = true;
- manager_send_changed(i->manager, "Inhibited\0");
+ manager_send_changed(i->manager, i->mode == INHIBIT_BLOCK ? "BlockInhibited\0" : "DelayInhibited\0");
return 0;
}
assert(i);
if (i->started)
- log_debug("Inhibitor %s (%s) pid=%lu uid=%lu stopped.",
+ log_debug("Inhibitor %s (%s) pid=%lu uid=%lu mode=%s stopped.",
strna(i->who), strna(i->why),
- (unsigned long) i->pid, (unsigned long) i->uid);
+ (unsigned long) i->pid, (unsigned long) i->uid,
+ inhibit_mode_to_string(i->mode));
if (i->state_file)
unlink(i->state_file);
i->started = false;
- manager_send_changed(i->manager, "Inhibited\0");
+ manager_send_changed(i->manager, i->mode == INHIBIT_BLOCK ? "BlockInhibited\0" : "DelayInhibited\0");
return 0;
}
int inhibitor_load(Inhibitor *i) {
InhibitWhat w;
+ InhibitMode mm;
int r;
char *cc,
*what = NULL,
*uid = NULL,
*pid = NULL,
*who = NULL,
- *why = NULL;
+ *why = NULL,
+ *mode = NULL;
r = parse_env_file(i->state_file, NEWLINE,
"WHAT", &what,
"PID", &pid,
"WHO", &who,
"WHY", &why,
+ "MODE", &mode,
"FIFO", &i->fifo_path,
NULL);
if (r < 0)
goto finish;
- w = inhibit_what_from_string(what);
+ w = what ? inhibit_what_from_string(what) : 0;
if (w >= 0)
i->what = w;
- parse_uid(uid, &i->uid);
- parse_pid(pid, &i->pid);
+ mm = mode ? inhibit_mode_from_string(mode) : INHIBIT_BLOCK;
+ if (mm >= 0)
+ i->mode = mm;
+
+ if (uid) {
+ r = parse_uid(uid, &i->uid);
+ if (r < 0)
+ goto finish;
+ }
+
+ if (pid) {
+ r = parse_pid(pid, &i->pid);
+ if (r < 0)
+ goto finish;
+ }
if (who) {
cc = cunescape(who);
/* Create FIFO */
if (!i->fifo_path) {
- r = safe_mkdir("/run/systemd/inhibit", 0755, 0, 0);
+ r = mkdir_safe_label("/run/systemd/inhibit", 0755, 0, 0);
if (r < 0)
return r;
/* Open reading side */
if (i->fifo_fd < 0) {
- struct epoll_event ev;
+ struct epoll_event ev = {};
i->fifo_fd = open(i->fifo_path, O_RDONLY|O_CLOEXEC|O_NDELAY);
if (i->fifo_fd < 0)
if (r < 0)
return r;
- zero(ev);
ev.events = 0;
- ev.data.u32 = FD_FIFO_BASE + i->fifo_fd;
+ ev.data.u32 = FD_OTHER_BASE + i->fifo_fd;
if (epoll_ctl(i->manager->epoll_fd, EPOLL_CTL_ADD, i->fifo_fd, &ev) < 0)
return -errno;
}
}
-InhibitWhat manager_inhibit_what(Manager *m) {
+InhibitWhat manager_inhibit_what(Manager *m, InhibitMode mm) {
Inhibitor *i;
Iterator j;
InhibitWhat what = 0;
assert(m);
HASHMAP_FOREACH(i, m->inhibitor_fds, j)
- what |= i->what;
+ if (i->mode == mm)
+ what |= i->what;
return what;
}
-const char *inhibit_what_to_string(InhibitWhat w) {
+static int pid_is_active(Manager *m, pid_t pid) {
+ Session *s;
+ int r;
- static const char* const table[_INHIBIT_WHAT_MAX] = {
- [0] = "",
- [INHIBIT_SHUTDOWN] = "shutdown",
- [INHIBIT_SUSPEND] = "suspend",
- [INHIBIT_IDLE] = "idle",
- [INHIBIT_SHUTDOWN|INHIBIT_SUSPEND] = "shutdown:suspend",
- [INHIBIT_SHUTDOWN|INHIBIT_IDLE] = "shutdown:idle",
- [INHIBIT_SHUTDOWN|INHIBIT_SUSPEND|INHIBIT_IDLE] = "shutdown:suspend:idle",
- [INHIBIT_SUSPEND|INHIBIT_IDLE] = "suspend:idle"
- };
+ r = manager_get_session_by_pid(m, pid, &s);
+ if (r < 0)
+ return r;
+
+ /* If there's no session assigned to it, then it's globally
+ * active on all ttys */
+ if (r == 0)
+ return 1;
+
+ return session_is_active(s);
+}
+
+bool manager_is_inhibited(
+ Manager *m,
+ InhibitWhat w,
+ InhibitMode mm,
+ dual_timestamp *since,
+ bool ignore_inactive,
+ bool ignore_uid,
+ uid_t uid) {
+
+ Inhibitor *i;
+ Iterator j;
+ struct dual_timestamp ts = { 0, 0 };
+ bool inhibited = false;
+
+ assert(m);
+ assert(w > 0 && w < _INHIBIT_WHAT_MAX);
+
+ HASHMAP_FOREACH(i, m->inhibitor_fds, j) {
+ if (!(i->what & w))
+ continue;
+
+ if (i->mode != mm)
+ continue;
+
+ if (ignore_inactive && pid_is_active(m, i->pid) <= 0)
+ continue;
+
+ if (ignore_uid && i->uid == uid)
+ continue;
+
+ if (!inhibited ||
+ i->since.monotonic < ts.monotonic)
+ ts = i->since;
+
+ inhibited = true;
+ }
+
+ if (since)
+ *since = ts;
+
+ return inhibited;
+}
+
+const char *inhibit_what_to_string(InhibitWhat w) {
+ static __thread char buffer[97];
+ char *p;
if (w < 0 || w >= _INHIBIT_WHAT_MAX)
return NULL;
- return table[w];
+ p = buffer;
+ if (w & INHIBIT_SHUTDOWN)
+ p = stpcpy(p, "shutdown:");
+ if (w & INHIBIT_SLEEP)
+ p = stpcpy(p, "sleep:");
+ if (w & INHIBIT_IDLE)
+ p = stpcpy(p, "idle:");
+ if (w & INHIBIT_HANDLE_POWER_KEY)
+ p = stpcpy(p, "handle-power-key:");
+ if (w & INHIBIT_HANDLE_SUSPEND_KEY)
+ p = stpcpy(p, "handle-suspend-key:");
+ if (w & INHIBIT_HANDLE_HIBERNATE_KEY)
+ p = stpcpy(p, "handle-hibernate-key:");
+ if (w & INHIBIT_HANDLE_LID_SWITCH)
+ p = stpcpy(p, "handle-lid-switch:");
+
+ if (p > buffer)
+ *(p-1) = 0;
+ else
+ *p = 0;
+
+ return buffer;
}
InhibitWhat inhibit_what_from_string(const char *s) {
size_t l;
FOREACH_WORD_SEPARATOR(w, l, s, ":", state) {
- if (l == 8 && strncmp(w, "shutdown", l) == 0)
+ if (l == 8 && strneq(w, "shutdown", l))
what |= INHIBIT_SHUTDOWN;
- else if (l == 7 && strncmp(w, "suspend", l) == 0)
- what |= INHIBIT_SUSPEND;
- else if (l == 4 && strncmp(w, "idle", l) == 0)
+ else if (l == 5 && strneq(w, "sleep", l))
+ what |= INHIBIT_SLEEP;
+ else if (l == 4 && strneq(w, "idle", l))
what |= INHIBIT_IDLE;
+ else if (l == 16 && strneq(w, "handle-power-key", l))
+ what |= INHIBIT_HANDLE_POWER_KEY;
+ else if (l == 18 && strneq(w, "handle-suspend-key", l))
+ what |= INHIBIT_HANDLE_SUSPEND_KEY;
+ else if (l == 20 && strneq(w, "handle-hibernate-key", l))
+ what |= INHIBIT_HANDLE_HIBERNATE_KEY;
+ else if (l == 17 && strneq(w, "handle-lid-switch", l))
+ what |= INHIBIT_HANDLE_LID_SWITCH;
else
return _INHIBIT_WHAT_INVALID;
}
return what;
-
}
+
+static const char* const inhibit_mode_table[_INHIBIT_MODE_MAX] = {
+ [INHIBIT_BLOCK] = "block",
+ [INHIBIT_DELAY] = "delay"
+};
+
+DEFINE_STRING_TABLE_LOOKUP(inhibit_mode, InhibitMode);