chiark / gitweb /
unit: add ConditionACPower=
[elogind.git] / src / shared / util.c
index 9ec6e2fe2f5e2ad54bb373eb12da157806f7bab8..3f00db7f2c2ed8fc521b892069827d1d0d28392f 100644 (file)
@@ -2851,6 +2851,9 @@ int get_ctty_devnr(pid_t pid, dev_t *d) {
                    &ttynr) != 1)
                 return -EIO;
 
+        if (major(ttynr) == 0 && minor(ttynr) == 0)
+                return -ENOENT;
+
         *d = (dev_t) ttynr;
         return 0;
 }
@@ -2869,7 +2872,8 @@ int get_ctty(pid_t pid, dev_t *_devnr, char **r) {
         snprintf(fn, sizeof(fn), "/dev/char/%u:%u", major(devnr), minor(devnr));
         char_array_0(fn);
 
-        if ((k = readlink_malloc(fn, &s)) < 0) {
+        k = readlink_malloc(fn, &s);
+        if (k < 0) {
 
                 if (k != -ENOENT)
                         return k;
@@ -2890,7 +2894,8 @@ int get_ctty(pid_t pid, dev_t *_devnr, char **r) {
                  * symlink in /dev/char. Let's return something
                  * vaguely useful. */
 
-                if (!(b = strdup(fn + 5)))
+                b = strdup(fn + 5);
+                if (!b)
                         return -ENOMEM;
 
                 *r = b;
@@ -5277,9 +5282,13 @@ int can_sleep(const char *type) {
 
         assert(type);
 
+        /* If /sys is read-only we cannot sleep */
+        if (access("/sys/power/state", W_OK) < 0)
+                return false;
+
         r = read_one_line_file("/sys/power/state", &p);
         if (r < 0)
-                return r == -ENOENT ? 0 : r;
+                return false;
 
         k = strlen(type);
         FOREACH_WORD_SEPARATOR(w, l, p, WHITESPACE, state)
@@ -5297,9 +5306,14 @@ int can_sleep_disk(const char *type) {
 
         assert(type);
 
+        /* If /sys is read-only we cannot sleep */
+        if (access("/sys/power/state", W_OK) < 0 ||
+            access("/sys/power/disk", W_OK) < 0)
+                return false;
+
         r = read_one_line_file("/sys/power/disk", &p);
         if (r < 0)
-                return r == -ENOENT ? 0 : r;
+                return false;
 
         k = strlen(type);
         FOREACH_WORD_SEPARATOR(w, l, p, WHITESPACE, state) {
@@ -5749,3 +5763,81 @@ char *strip_tab_ansi(char **ibuf, size_t *_isz) {
 
         return obuf;
 }
+
+int on_ac_power(void) {
+        bool found_offline = false, found_online = false;
+        _cleanup_closedir_ DIR *d = NULL;
+
+        d = opendir("/sys/class/power_supply");
+        if (!d)
+                return -errno;
+
+        for (;;) {
+                struct dirent *de;
+                union dirent_storage buf;
+                _cleanup_free_ char *p = NULL;
+                _cleanup_close_ int fd = -1, device = -1;
+                char contents[6];
+                ssize_t n;
+                int k;
+
+                k = readdir_r(d, &buf.de, &de);
+                if (k != 0)
+                        return -k;
+
+                if (!de)
+                        break;
+
+                if (ignore_file(de->d_name))
+                        continue;
+
+                device = openat(dirfd(d), de->d_name, O_DIRECTORY|O_RDONLY|O_CLOEXEC|O_NOCTTY);
+                if (device < 0) {
+                        if (errno == ENOENT || errno == ENOTDIR)
+                                continue;
+
+                        return -errno;
+                }
+
+                fd = openat(device, "type", O_RDONLY|O_CLOEXEC|O_NOCTTY);
+                if (fd < 0) {
+                        if (errno == ENOENT)
+                                continue;
+
+                        return -errno;
+                }
+
+                n = read(fd, contents, sizeof(contents));
+                if (n < 0)
+                        return -errno;
+
+                if (n != 6 || memcmp(contents, "Mains\n", 6))
+                        continue;
+
+                close_nointr_nofail(fd);
+                fd = openat(device, "online", O_RDONLY|O_CLOEXEC|O_NOCTTY);
+                if (fd < 0) {
+                        if (errno == ENOENT)
+                                continue;
+
+                        return -errno;
+                }
+
+                n = read(fd, contents, sizeof(contents));
+                if (n < 0)
+                        return -errno;
+
+                if (n != 2 || contents[1] != '\n')
+                        return -EIO;
+
+                if (contents[0] == '1') {
+                        found_online = true;
+                        break;
+                } else if (contents[0] == '0')
+                        found_offline = true;
+                else
+                        return -EIO;
+        }
+
+        return found_online || !found_offline;
+}