X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=blobdiff_plain;f=src%2Fshared%2Futil.c;h=49b58444c7213da9a96f7cbe9afffb3410babeeb;hb=d5a89d7dc17a5ba5cf4fc71f82963c5c94a31c3d;hp=d01c2061b423c6b60a4dc422a1d358e46eb5dad5;hpb=23406ce58aa7142e8df3c5c9e5ac34a01e90e3e0;p=elogind.git diff --git a/src/shared/util.c b/src/shared/util.c index d01c2061b..49b58444c 100644 --- a/src/shared/util.c +++ b/src/shared/util.c @@ -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; } @@ -5279,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) @@ -5299,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) { @@ -5670,7 +5682,7 @@ oom: } char *strip_tab_ansi(char **ibuf, size_t *_isz) { - const char *i, *begin; + const char *i, *begin = NULL; enum { STATE_OTHER, STATE_ESCAPE, @@ -5751,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; +}