shared: add a generic prompt_loop_yes_no() helper

Factor a yes/no variant of prompt_loop() out into prompt-util.[ch], so the
various interactive tools can share a single implementation, and convert
systemd-sysinstall's installation confirmation question over to it.
This commit is contained in:
Lennart Poettering
2026-06-27 17:28:39 +02:00
parent 91631d899b
commit 77ee077dfe
3 changed files with 49 additions and 21 deletions
+41
View File
@@ -213,6 +213,47 @@ int prompt_loop(
}
}
static int boolean_is_valid(const char *name, void *userdata) {
return parse_boolean(name) >= 0;
}
int prompt_loop_yes_no(const char *question, bool def, bool *ret) {
int r;
assert(question);
assert(ret);
char **l = STRV_MAKE("yes", "no");
_cleanup_free_ char *reply = NULL;
r = prompt_loop(question,
GLYPH_WARNING_SIGN,
/* prefill= */ def ? "yes" : "no",
/* menu= */ l,
/* accepted= */ NULL,
/* ellipsize_percentage= */ 20,
/* n_columns= */ 2,
/* column_width= */ 40,
/* is_valid= */ boolean_is_valid,
/* refresh= */ NULL,
/* userdata= */ NULL,
PROMPT_SHOW_MENU|PROMPT_MAY_SKIP|PROMPT_HIDE_MENU_HINT|PROMPT_HIDE_SKIP_HINT,
&reply);
if (r < 0)
return r;
if (r == 0) { /* Skipped (empty input): fall back to the default. */
*ret = def;
return 0;
}
r = parse_boolean(reply);
if (r < 0)
return log_error_errno(r, "Failed to parse reply: %s", reply);
*ret = r;
return 1;
}
/* Default: bright white on blue background */
#define ANSI_COLOR_CHROME "\x1B[0;44;1;37m"
+2
View File
@@ -26,6 +26,8 @@ int prompt_loop(const char *text,
PromptFlags flags,
char **ret);
int prompt_loop_yes_no(const char *question, bool def, bool *ret);
int chrome_show(const char *top, const char *bottom);
void chrome_hide(void);
+6 -21
View File
@@ -613,29 +613,14 @@ static int prompt_confirm(void) {
putchar('\n');
char **l = STRV_MAKE("yes", "no");
_cleanup_free_ char *reply = NULL;
r = prompt_loop(arg_summary ? "Please type 'yes' to confirm the choices above and begin the installation" :
"Please type 'yes' to begin the installation",
GLYPH_WARNING_SIGN,
/* prefill= */ NULL,
/* menu= */ l,
/* accepted= */ l,
/* ellipsize_percentage= */ 20,
/* n_columns= */ 2,
/* column_width= */ 40,
/* is_valid= */ NULL,
/* refresh= */ NULL,
/* userdata= */ NULL,
PROMPT_SHOW_MENU|PROMPT_MAY_SKIP|PROMPT_HIDE_MENU_HINT|PROMPT_HIDE_SKIP_HINT,
&reply);
bool yes;
r = prompt_loop_yes_no(arg_summary ? "Please type 'yes' to confirm the choices above and begin the installation" :
"Please type 'yes' to begin the installation",
/* def= */ false,
&yes);
if (r < 0)
return r;
if (r == 0)
return log_error_errno(SYNTHETIC_ERRNO(ECANCELED), "Installation cancelled.");
if (!streq(reply, "yes"))
if (!yes)
return log_error_errno(SYNTHETIC_ERRNO(ECANCELED), "Installation not confirmed, cancelling.");
return 0;