Introducing Finit progress 𝓜𝓸𝓭𝓮𝓻𝓷

Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
This commit is contained in:
Joachim Nilsson committed 2020-01-02 14:59:32 +01:00
1 parent 3b62f46599
commit 636f6678ed
4 files changed
+144 -41

No files matched your search

+17 -4
View File
@@ -62,9 +62,13 @@ AC_ARG_ENABLE(rw-rootfs,
enable_rw_rootfs=no])
AC_ARG_ENABLE(progress,
AS_HELP_STRING([--enable-progress], [Pre Finit v3 bootup progress and heading]),,[
AS_HELP_STRING([--enable-progress], [Modern progress display at bootup]),,[
enable_progress=no])
AC_ARG_ENABLE(progress-classic,
AS_HELP_STRING([--enable-progress-classic], [Pre Finit v3 bootup progress and heading]),,[
enable_progress_classic=no])
AC_ARG_ENABLE(watchdog,
AS_HELP_STRING([--enable-watchdog], [Enable built-in watchdog, uses /dev/watchdog]),,[
enable_watchdog=no])
@@ -154,9 +158,17 @@ AS_IF([test "x$enable_rw_rootfs" = "xyes"], [
AC_DEFINE(REMOUNT_ROOTFS, 1, [Remount / as rw at boot])])
AS_IF([test "x$enable_progress" = "xyes"], [
AC_DEFINE(SILENT_MODE, 0, [Pre Finit v3 bootup messages and heading])
AC_DEFINE(PROGRESS_STYLE, 2, [Modern bootup messages, systemd inspired])])
AS_IF([test "x$enable_progress_classic" = "xyes"], [
enable_progress=no
AC_DEFINE(PROGRESS_STYLE, 1, [Pre Finit v3 bootup messages and heading])])
AS_IF([test "x$enable_progress_classic" = "xyes" -o "x$enable_progress" = "xyes"], [
AC_DEFINE(SILENT_MODE, 0, [Display bootup progress, see above for style])
], [
AC_DEFINE(SILENT_MODE, 1, [Completely silent until login prompt])])
AC_DEFINE(PROGRESS_STYLE, 0, [Default progress style])
AC_DEFINE(SILENT_MODE, 1, [Completely silent until login prompt (default)])])
AS_IF([test "x$enable_watchdog" = "xyes"], [
AC_DEFINE(BUILTIN_WATCHDOG, 1, [Enable built-in watchdog, kicks on /dev/watchdog])])
@@ -275,7 +287,8 @@ Optional features:
Emergency shell.......: $enable_emergency_shell
Fallback shell........: $enable_fallback_shell
Remount / RW at boot..: $enable_rw_rootfs
Traditional progress..: $enable_progress
Modern progress.......: $enable_progress
Classic progress......: $enable_progress_classic
Default console dev...: $console
Default hostname......: $hostname
Default runlevel......: $runlevel
+1 -5
View File
@@ -73,9 +73,6 @@ static int udev = 0; /* Runtime detection of udev */
*/
static void banner(void)
{
char *buf = INIT_HEADING;
char separator[SCREEN_WIDTH];
if (plugin_exists(HOOK_BANNER)) {
plugin_run_hooks(HOOK_BANNER);
return;
@@ -84,8 +81,7 @@ static void banner(void)
if (log_is_silent())
return;
memset(separator, '=', sizeof(separator));
fprintf(stderr, "\n\e[2K\e[1m%s %.*s\e[0m\n", buf, SCREEN_WIDTH - (int)strlen(buf) - 2, separator);
print_banner(INIT_HEADING);
}
static int ismnt(char *file, char *dir)
+125 -32
View File
@@ -39,6 +39,30 @@
#include "util.h"
#include "utmp-api.h"
static int progress_style = PROGRESS_STYLE;
/*
* Note: the pending status (⋯) must be last item. Also, ⋯ is not
* off-by-one, it's a multi-byte character.
*/
#define STATUS_CLASS { \
CHOOSE(" OK ", " OK ", "\e[1;32m"), /* Green */ \
CHOOSE("FAIL", "FAIL", "\e[1;31m"), /* Red */ \
CHOOSE("WARN", "WARN", "\e[1;31m"), /* Red */ \
CHOOSE(" \\/ ", " ⋯ ", "\e[1;33m"), /* Yellow */ \
}
#define CHOOSE(x,y,z) x
static const char *status1[] = STATUS_CLASS;
#undef CHOOSE
#define CHOOSE(x,y,z) y
static const char *status2[] = STATUS_CLASS;
#undef CHOOSE
#define CHOOSE(x,y,z) z
static const char *color[] = STATUS_CLASS;
char *strip_line(char *line)
{
@@ -57,6 +81,74 @@ char *strip_line(char *line)
return line;
}
/*
* Return screen length of string, not counting escape chars, and
* accounting for unicode characters as only one screen byte wide
*/
size_t slen(char *string)
{
unsigned char *buf = (unsigned char *)string;
size_t len = 0;
while (*buf) {
/* Skip ANSI escape sequences */
if (*buf == '\e') {
while (*buf && !isalpha(*buf))
buf++;
continue;
}
/* Skip 3-byte unicode */
if (*buf == 0xe2) {
for (int cnt = 3; *buf && cnt >= 0; cnt--)
buf++;
continue;
}
len++;
buf++;
}
return len;
}
static char *pad(char *buf, size_t len, char ch, size_t width)
{
size_t pos = strlen(buf);
size_t i = slen(buf);
if (pos < len)
buf[pos++] = ' ';
while (i < width - 8 && pos < len) {
buf[pos++] = ch;
i++;
}
return buf;
}
void print_banner(const char *heading)
{
char buf[SCREEN_WIDTH + 10];
memset(buf, 0, sizeof(buf));
strlcat(buf, "\r\e[2K", sizeof(buf));
if (progress_style == 1) {
strlcat(buf, "\e[1m", sizeof(buf));
strlcat(buf, heading, sizeof(buf));
pad(buf, sizeof(buf), '=', SCREEN_WIDTH - 2);
} else {
size_t wmax = 80 <= SCREEN_WIDTH ? 80 : SCREEN_WIDTH;
strlcat(buf, "\e[1;31m⏺ \e[1;33m⏺ \e[1;32m⏺ \e[0m\e[1m ", sizeof(buf));
strlcat(buf, heading, sizeof(buf));
pad(buf, sizeof(buf), '=', wmax + 8);
}
strlcat(buf, "\e[0m\n", sizeof(buf));
(void)write(STDERR_FILENO, buf, strlen(buf));
}
static size_t print_timestamp(char *buf, size_t len)
{
#if defined(CONFIG_PRINTK_TIME)
@@ -77,6 +169,26 @@ static size_t print_timestamp(char *buf, size_t len)
#endif
}
static char *status(int rc)
{
static char buf[64];
if (rc < 0 || rc >= (int)NELEMS(status1))
rc = NELEMS(status1) - 1; /* Default to "⋯" (pending) */
if (progress_style == 1) {
int hl = 1;
if (rc == 1 || rc == 2)
hl = 7;
snprintf(buf, sizeof(buf), "\e[%dm[%s]\e[0m", hl, status1[rc]);
} else
snprintf(buf, sizeof(buf), "\e[1m[%s%s\e[0m\e[1m]\e[0m ", color[rc], status2[rc]);
return buf;
}
void printv(const char *fmt, va_list ap)
{
char buf[SCREEN_WIDTH];
@@ -91,51 +203,32 @@ void printv(const char *fmt, va_list ap)
len = print_timestamp(buf, sizeof(buf));
vsnprintf(&buf[len], sizeof(buf) - len, fmt, ap);
len = strlen(buf);
buf[len++] = ' ';
for (size_t i = len; i < (sizeof(buf) - 8); i++)
buf[i] = '.'; /* pad with dots. */
fprintf(stderr, "\r%s ", buf);
if (progress_style == 1)
fprintf(stderr, "\r%s ", pad(buf, sizeof(buf), '.', sizeof(buf)));
else
fprintf(stderr, "\r\e[2K%s%s", status(3), buf);
}
void print(int action, const char *fmt, ...)
void print(int rc, const char *fmt, ...)
{
va_list ap;
const char success[] = "\e[1m[ OK ]\e[0m\n";
const char failure[] = "\e[7m[FAIL]\e[0m\n";
const char warning[] = "\e[7m[WARN]\e[0m\n";
const char pending[] = "\e[1m[ \\/ ]\e[0m\n";
if (log_is_silent())
return;
if (fmt) {
va_list ap;
va_start(ap, fmt);
printv(fmt, ap);
va_end(ap);
}
switch (action) {
case -1:
break;
if (rc < 0)
return;
case 0:
write(STDERR_FILENO, success, sizeof(success));
break;
case 1:
write(STDERR_FILENO, failure, sizeof(failure));
break;
case 2:
write(STDERR_FILENO, warning, sizeof(warning));
break;
default:
write(STDERR_FILENO, pending, sizeof(pending));
break;
}
if (progress_style == 1)
fprintf(stderr, "%s\n", status(rc));
else
fprintf(stderr, ".\r%s\n", status(rc));
}
void print_desc(char *action, char *desc)
+1
View File
@@ -57,6 +57,7 @@ int sh (char *tty);
int stty (int fd, speed_t speed);
speed_t stty_parse_speed(char *baud);
void print_banner (const char *heading);
void printv (const char *fmt, va_list ap);
void print (int action, const char *fmt, ...);
void print_desc (char *action, char *desc);