diff --git a/src/ac-power/ac-power.c b/src/ac-power/ac-power.c index c4bfe7cb18..12379df344 100644 --- a/src/ac-power/ac-power.c +++ b/src/ac-power/ac-power.c @@ -3,7 +3,7 @@ #include #include "main-func.h" -#include "util.h" +#include "udev-util.h" static bool arg_verbose = false; diff --git a/src/basic/util.c b/src/basic/util.c index 3aecb22fc4..d7ef382737 100644 --- a/src/basic/util.c +++ b/src/basic/util.c @@ -6,7 +6,6 @@ #include "alloc-util.h" #include "build.h" -#include "dirent-util.h" #include "env-file.h" #include "env-util.h" #include "fd-util.h" @@ -115,65 +114,6 @@ void in_initrd_force(bool value) { saved_in_initrd = value; } -int on_ac_power(void) { - bool found_offline = false, found_online = false; - _cleanup_closedir_ DIR *d = NULL; - int r; - - d = opendir("/sys/class/power_supply"); - if (!d) - return errno == ENOENT ? true : -errno; - - FOREACH_DIRENT(de, d, return -errno) { - _cleanup_close_ int device_fd = -1; - _cleanup_free_ char *contents = NULL; - unsigned v; - - device_fd = openat(dirfd(d), de->d_name, O_DIRECTORY|O_RDONLY|O_CLOEXEC); - if (device_fd < 0) { - if (IN_SET(errno, ENOENT, ENOTDIR)) - continue; - - return -errno; - } - - r = read_virtual_file_at(device_fd, "type", SIZE_MAX, &contents, NULL); - if (r == -ENOENT) - continue; - if (r < 0) - return r; - - delete_trailing_chars(contents, NEWLINE); - - /* We assume every power source is AC, except for batteries. See - * https://github.com/torvalds/linux/blob/4eef766b7d4d88f0b984781bc1bcb574a6eafdc7/include/linux/power_supply.h#L176 - * for defined power source types. Also see: - * https://www.kernel.org/doc/Documentation/ABI/testing/sysfs-class-power */ - if (streq(contents, "Battery")) - continue; - - contents = mfree(contents); - - r = read_virtual_file_at(device_fd, "online", SIZE_MAX, &contents, NULL); - if (r == -ENOENT) - continue; - if (r < 0) - return r; - - delete_trailing_chars(contents, NEWLINE); - - r = safe_atou(contents, &v); - if (r < 0) - return r; - if (v > 0) /* At least 1 and 2 are defined as different types of 'online' */ - found_online = true; - else - found_offline = true; - } - - return found_online || !found_offline; -} - int container_get_leader(const char *machine, pid_t *pid) { _cleanup_free_ char *s = NULL, *class = NULL; const char *p; diff --git a/src/basic/util.h b/src/basic/util.h index f5434c9641..94804f28e3 100644 --- a/src/basic/util.h +++ b/src/basic/util.h @@ -20,8 +20,6 @@ int prot_from_flags(int flags) _const_; bool in_initrd(void); void in_initrd_force(bool value); -int on_ac_power(void); - /* Note: log2(0) == log2(1) == 0 here and below. */ #define CONST_LOG2ULL(x) ((x) > 1 ? (unsigned) __builtin_clzll(x) ^ 63U : 0) diff --git a/src/shared/condition.c b/src/shared/condition.c index 44e26775db..68fbbf643a 100644 --- a/src/shared/condition.c +++ b/src/shared/condition.c @@ -50,9 +50,9 @@ #include "string-table.h" #include "string-util.h" #include "tomoyo-util.h" +#include "udev-util.h" #include "uid-alloc-range.h" #include "user-util.h" -#include "util.h" #include "virt.h" Condition* condition_new(ConditionType type, const char *parameter, bool trigger, bool negate) { diff --git a/src/shared/udev-util.c b/src/shared/udev-util.c index 27dfd11a6a..73ca886fb3 100644 --- a/src/shared/udev-util.c +++ b/src/shared/udev-util.c @@ -2,6 +2,7 @@ #include #include +#include #include #include @@ -9,10 +10,12 @@ #include "device-nodes.h" #include "device-private.h" #include "device-util.h" +#include "dirent-util.h" #include "env-file.h" #include "errno-util.h" #include "escape.h" #include "fd-util.h" +#include "fileio.h" #include "log.h" #include "macro.h" #include "parse-util.h" @@ -579,3 +582,62 @@ int udev_queue_init(void) { return TAKE_FD(fd); } + +int on_ac_power(void) { + bool found_offline = false, found_online = false; + _cleanup_closedir_ DIR *d = NULL; + int r; + + d = opendir("/sys/class/power_supply"); + if (!d) + return errno == ENOENT ? true : -errno; + + FOREACH_DIRENT(de, d, return -errno) { + _cleanup_close_ int device_fd = -1; + _cleanup_free_ char *contents = NULL; + unsigned v; + + device_fd = openat(dirfd(d), de->d_name, O_DIRECTORY|O_RDONLY|O_CLOEXEC); + if (device_fd < 0) { + if (IN_SET(errno, ENOENT, ENOTDIR)) + continue; + + return -errno; + } + + r = read_virtual_file_at(device_fd, "type", SIZE_MAX, &contents, NULL); + if (r == -ENOENT) + continue; + if (r < 0) + return r; + + delete_trailing_chars(contents, NEWLINE); + + /* We assume every power source is AC, except for batteries. See + * https://github.com/torvalds/linux/blob/4eef766b7d4d88f0b984781bc1bcb574a6eafdc7/include/linux/power_supply.h#L176 + * for defined power source types. Also see: + * https://www.kernel.org/doc/Documentation/ABI/testing/sysfs-class-power */ + if (streq(contents, "Battery")) + continue; + + contents = mfree(contents); + + r = read_virtual_file_at(device_fd, "online", SIZE_MAX, &contents, NULL); + if (r == -ENOENT) + continue; + if (r < 0) + return r; + + delete_trailing_chars(contents, NEWLINE); + + r = safe_atou(contents, &v); + if (r < 0) + return r; + if (v > 0) /* At least 1 and 2 are defined as different types of 'online' */ + found_online = true; + else + found_offline = true; + } + + return found_online || !found_offline; +} diff --git a/src/shared/udev-util.h b/src/shared/udev-util.h index 276686da80..8d21dc4364 100644 --- a/src/shared/udev-util.h +++ b/src/shared/udev-util.h @@ -53,6 +53,8 @@ int udev_resolve_subsys_kernel(const char *string, char *result, size_t maxsize, int udev_queue_is_empty(void); int udev_queue_init(void); +int on_ac_power(void); + #if HAVE_SYS_SDT_H /* Each trace point can have different number of additional arguments. Note that when the macro is used only diff --git a/src/test/test-condition.c b/src/test/test-condition.c index 4b22784d17..c872a6c2b9 100644 --- a/src/test/test-condition.c +++ b/src/test/test-condition.c @@ -33,6 +33,7 @@ #include "strv.h" #include "tests.h" #include "tomoyo-util.h" +#include "udev-util.h" #include "uid-alloc-range.h" #include "user-util.h" #include "virt.h"