diff options
author | Yu Watanabe <watanabe.yu+github@gmail.com> | 2023-06-28 19:43:17 +0200 |
---|---|---|
committer | Yu Watanabe <watanabe.yu+github@gmail.com> | 2023-06-29 08:41:00 +0200 |
commit | be994c2640d806eaecaaabf7d79ec7080c42dd3a (patch) | |
tree | 7dc1404c0c5b8c3b67672fbeeb9815f0aee01383 /src/battery-check | |
parent | meson: first try dependency(), then fallback to find_library() (diff) | |
download | systemd-be994c2640d806eaecaaabf7d79ec7080c42dd3a.tar.xz systemd-be994c2640d806eaecaaabf7d79ec7080c42dd3a.zip |
battery-check: several follow-ups
Follow-ups for e3d4148d50909119c4e9327e6ad96d3ca7f4661a.
- add reference to initrd-battery-check.service in man page, and move
its section from 1 to 8,
- add link to man page in help message,
- introduce ERRNO_IS_NO_PLYMOUTH(),
- propagate error in battery_check_send_plymouth_message(),
- rename battery_check_send_plymouth_message() -> plymouth_send_message(),
- return earlier when the first battery level check passed to reduce
indentation,
- fix potential use of invalid fd on battery restored,
- do not use emoji for /dev/console,
- add simple test (mostly for coverity),
etc, etc...
Diffstat (limited to 'src/battery-check')
-rw-r--r-- | src/battery-check/battery-check.c | 129 |
1 files changed, 76 insertions, 53 deletions
diff --git a/src/battery-check/battery-check.c b/src/battery-check/battery-check.c index 14bb870ca4..ca13251ae0 100644 --- a/src/battery-check/battery-check.c +++ b/src/battery-check/battery-check.c @@ -14,47 +14,74 @@ #include "io-util.h" #include "log.h" #include "main-func.h" +#include "pretty-print.h" #include "socket-util.h" #include "terminal-util.h" +#include "time-util.h" + +#define BATTERY_LOW_MESSAGE \ + "Battery level critically low. Please connect your charger or the system will power off in 10 seconds." +#define BATTERY_RESTORED_MESSAGE \ + "A.C. power restored, continuing." + +static int help(void) { + _cleanup_free_ char *link = NULL; + int r; + + r = terminal_urlify_man("systemd-battery-check", "8", &link); + if (r < 0) + return log_oom(); -static void help(void) { printf("%s\n\n" - "Checks battery level to see whether there's enough charge.\n\n" + "%sCheck battery level to see whether there's enough charge.%s\n\n" " -h --help Show this help\n" - " --version Show package version\n", - program_invocation_short_name); + " --version Show package version\n" + "\nSee the %s for details.\n", + program_invocation_short_name, + ansi_highlight(), + ansi_normal(), + link); + + return 0; } -static void battery_check_send_plymouth_message(char *message, const char *mode) { - assert(message); - assert(mode); +static bool ERRNO_IS_NO_PLYMOUTH(int r) { + return IN_SET(abs(r), EAGAIN, ENOENT) || ERRNO_IS_DISCONNECT(r); +} - int r; +static int plymouth_send_message(const char *mode, const char *message) { static const union sockaddr_union sa = PLYMOUTH_SOCKET; - _cleanup_close_ int fd = -EBADF; _cleanup_free_ char *plymouth_message = NULL; + _cleanup_close_ int fd = -EBADF; + int c, r; + + assert(mode); + assert(message); - int c = asprintf(&plymouth_message, - "C\x02%c%s%c" - "M\x02%c%s%c", - (int) strlen(mode) + 1, mode, '\x00', - (int) strlen(message) + 1, message, '\x00'); + c = asprintf(&plymouth_message, + "C\x02%c%s%c" + "M\x02%c%s%c", + (int) strlen(mode) + 1, mode, '\x00', + (int) strlen(message) + 1, message, '\x00'); if (c < 0) - return (void) log_oom(); + return log_oom(); /* We set SOCK_NONBLOCK here so that we rather drop the * message than wait for plymouth */ fd = socket(AF_UNIX, SOCK_STREAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0); if (fd < 0) - return (void) log_warning_errno(errno, "socket() failed: %m"); + return log_warning_errno(errno, "socket() failed: %m"); if (connect(fd, &sa.sa, SOCKADDR_UN_LEN(sa.un)) < 0) - return (void) log_full_errno(IN_SET(errno, EAGAIN, ENOENT) || ERRNO_IS_DISCONNECT(errno) ? LOG_DEBUG : LOG_WARNING, errno, "Connection to plymouth failed: %m"); + return log_full_errno(ERRNO_IS_NO_PLYMOUTH(errno) ? LOG_DEBUG : LOG_WARNING, errno, + "Failed to connect to plymouth: %m"); r = loop_write(fd, plymouth_message, c, /* do_poll = */ false); if (r < 0) - return (void) log_full_errno(IN_SET(r, -EAGAIN, -ENOENT) || ERRNO_IS_DISCONNECT(r) ? -LOG_DEBUG : LOG_WARNING, r, "Failed to write to plymouth, ignoring: %m"); + return log_full_errno(ERRNO_IS_NO_PLYMOUTH(r) ? LOG_DEBUG : LOG_WARNING, r, + "Failed to write to plymouth: %m"); + + return 0; } static int parse_argv(int argc, char * argv[]) { @@ -79,8 +106,7 @@ static int parse_argv(int argc, char * argv[]) { switch (c) { case 'h': - help(); - return 0; + return help(); case ARG_VERSION: return version(); @@ -100,10 +126,11 @@ static int parse_argv(int argc, char * argv[]) { } static int run(int argc, char *argv[]) { + _cleanup_free_ char *plymouth_message = NULL; + _cleanup_close_ int fd = -EBADF; int r; - log_parse_environment(); - log_open(); + log_setup(); r = parse_argv(argc, argv); if (r <= 0) @@ -114,44 +141,40 @@ static int run(int argc, char *argv[]) { log_warning_errno(r, "Failed to check battery status, ignoring: %m"); return 0; } + if (r == 0) + return 0; - if (r > 0) { - _cleanup_close_ int fd = -EBADF; - _cleanup_free_ char *message = NULL, *plymouth_message = NULL, *ac_message = NULL; - - if (asprintf(&message, "%s Battery level critically low. Please connect your charger or the system will power off in 10 seconds.", special_glyph(SPECIAL_GLYPH_LOW_BATTERY)) < 0) - return log_oom(); + log_emergency("%s " BATTERY_LOW_MESSAGE, special_glyph(SPECIAL_GLYPH_LOW_BATTERY)); - if (asprintf(&plymouth_message, "%s Battery level critically low. Please connect your charger or the system will power off in 10 seconds.", special_glyph_force_utf(SPECIAL_GLYPH_LOW_BATTERY)) < 0) - return log_oom(); + fd = open_terminal("/dev/console", O_WRONLY|O_NOCTTY|O_CLOEXEC); + if (fd < 0) + log_warning_errno(fd, "Failed to open console, ignoring: %m"); + else + dprintf(fd, ANSI_HIGHLIGHT_RED "%s " BATTERY_LOW_MESSAGE ANSI_NORMAL "\n", + special_glyph_full(SPECIAL_GLYPH_LOW_BATTERY, /* force_utf = */ false)); - log_emergency("%s", message); + if (asprintf(&plymouth_message, "%s " BATTERY_LOW_MESSAGE, + special_glyph_full(SPECIAL_GLYPH_LOW_BATTERY, /* force_utf = */ true)) < 0) + return log_oom(); - fd = open_terminal("/dev/console", O_WRONLY|O_NOCTTY|O_CLOEXEC); - if (fd < 0) - log_warning_errno(fd, "Failed to open console, ignoring: %m"); - else - dprintf(fd, ANSI_HIGHLIGHT_RED "%s" ANSI_NORMAL "\n", message); + (void) plymouth_send_message("shutdown", plymouth_message); - battery_check_send_plymouth_message(plymouth_message, "shutdown"); - sleep(10); + usleep_safe(10 * USEC_PER_SEC); - r = battery_is_discharging_and_low(); - if (r > 0) { - log_emergency("Battery level critically low, powering off."); - return r; - } - if (r < 0) - return log_warning_errno(r, "Failed to check battery status, ignoring: %m"); + r = battery_is_discharging_and_low(); + if (r < 0) + return log_warning_errno(r, "Failed to check battery status, assuming not charged yet, powering off: %m"); + if (r > 0) { + log_emergency("Battery level critically low, powering off."); + return r; + } - if (asprintf(&ac_message, "A.C. power restored, continuing") < 0) - return log_oom(); + log_info(BATTERY_RESTORED_MESSAGE); + if (fd >= 0) + dprintf(fd, BATTERY_RESTORED_MESSAGE "\n"); + (void) plymouth_send_message("boot-up", BATTERY_RESTORED_MESSAGE); - log_info("%s",ac_message); - dprintf(fd, "%s\n", ac_message); - battery_check_send_plymouth_message(ac_message, "boot-up"); - } - return r; + return 0; } DEFINE_MAIN_FUNCTION_WITH_POSITIVE_FAILURE(run); |