mirror of
https://github.com/troglobit/finit.git
synced 2026-10-14 10:19:36 +00:00
Introducing Finit progress 𝓜𝓸𝓭𝓮𝓻𝓷
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
This commit is contained in:
1 parent
3b62f46599
commit
636f6678ed
4 files changed
+144
-41
No files matched your search
+17
-4
@@ -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
@@ -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
@@ -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)
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in new issue
Block a user