return RET_NERRNO(ioctl(fd, VT_ACTIVATE, vt));
}
-int read_one_char(FILE *f, char *ret, usec_t t, bool *need_nl) {
+int read_one_char(FILE *f, char *ret, usec_t t, bool echo, bool *need_nl) {
_cleanup_free_ char *line = NULL;
struct termios old_termios;
int r, fd;
- assert(f);
assert(ret);
+ if (!f)
+ f = stdin;
+
/* If this is a terminal, then switch canonical mode off, so that we can read a single
* character. (Note that fmemopen() streams do not have an fd associated with them, let's handle that
- * nicely.) */
+ * nicely.) If 'echo' is false we'll also disable ECHO mode so that the pressed key is not made
+ * visible to the user. */
fd = fileno(f);
if (fd >= 0 && tcgetattr(fd, &old_termios) >= 0) {
struct termios new_termios = old_termios;
- new_termios.c_lflag &= ~ICANON;
+ new_termios.c_lflag &= ~(ICANON|(echo ? 0 : ECHO));
new_termios.c_cc[VMIN] = 1;
new_termios.c_cc[VTIME] = 0;
fflush(stdout);
- r = read_one_char(stdin, &c, DEFAULT_ASK_REFRESH_USEC, &need_nl);
+ r = read_one_char(stdin, &c, DEFAULT_ASK_REFRESH_USEC, /* echo= */ true, &need_nl);
if (r < 0) {
if (r == -ETIMEDOUT)
}
bool any_key_to_proceed(void) {
- char key = 0;
- bool need_nl = true;
- /*
- * Insert a new line here as well as to when the user inputs, as this is also used during the
- * boot up sequence when status messages may be interleaved with the current program output.
- * This ensures that the status messages aren't appended on the same line as this message.
- */
- puts("-- Press any key to proceed --");
+ /* Insert a new line here as well as to when the user inputs, as this is also used during the boot up
+ * sequence when status messages may be interleaved with the current program output. This ensures
+ * that the status messages aren't appended on the same line as this message. */
+
+ fputc('\n', stdout);
+ fputs(ansi_highlight_magenta(), stdout);
+ fputs("-- Press any key to proceed --", stdout);
+ fputs(ansi_normal(), stdout);
+ fflush(stdout);
- (void) read_one_char(stdin, &key, USEC_INFINITY, &need_nl);
+ char key = 0;
+ (void) read_one_char(stdin, &key, USEC_INFINITY, /* echo= */ false, /* need_nl= */ NULL);
- if (need_nl)
- putchar('\n');
+ fputc('\n', stdout);
+ fputc('\n', stdout);
+ fflush(stdout);
return key != 'q';
}
putchar('\n');
/* on the first screen we reserve 2 extra lines for the title */
- if (i % break_lines == break_modulo) {
+ if (i % break_lines == break_modulo)
if (!any_key_to_proceed())
return 0;
- }
}
return 0;
int chvt(int vt);
-int read_one_char(FILE *f, char *ret, usec_t timeout, bool *need_nl);
+int read_one_char(FILE *f, char *ret, usec_t timeout, bool echo, bool *need_nl);
int ask_char(char *ret, const char *replies, const char *text, ...) _printf_(3, 4);
int ask_string(char **ret, const char *text, ...) _printf_(2, 3);
bool any_key_to_proceed(void);
if (arg_batch)
(void) usleep_safe(usec_add(usec_sub_unsigned(last_refresh, t), arg_delay));
else {
- r = read_one_char(stdin, &key, usec_add(usec_sub_unsigned(last_refresh, t), arg_delay), NULL);
+ r = read_one_char(stdin, &key, usec_add(usec_sub_unsigned(last_refresh, t), arg_delay), /* echo= */ false, /* need_nl= */ NULL);
if (r == -ETIMEDOUT)
continue;
if (r < 0)
else
printf("\nWelcome to your new installation of %s!\n", pn);
- printf("\nPlease configure your system!\n\n");
+ printf("\nPlease configure your system!\n");
any_key_to_proceed();
return 0;
}
- any_key_to_proceed();
+ printf("\nPlease create your user account!\n");
+
+ if (!any_key_to_proceed()) {
+ log_notice("Skipping.");
+ return 0;
+ }
(void) terminal_reset_defensive_locked(STDOUT_FILENO, /* switch_to_text= */ false);
goto cleanup;
}
- r = read_one_char(f, &read_character_buffer, USEC_INFINITY, NULL);
+ r = read_one_char(f, &read_character_buffer, USEC_INFINITY, /* echo= */ true, /* need_nl= */ NULL);
if (r < 0 && r != -EINTR)
- log_error_errno(r, "Failed to read character: %m");
+ log_warning_errno(r, "Failed to read character, ignoring: %m");
r = 0;
assert_se(fputs("c\n", file) >= 0);
rewind(file);
- assert_se(read_one_char(file, &r, 1000000, &need_nl) >= 0);
+ assert_se(read_one_char(file, &r, 1000000, /* echo= */ true, &need_nl) >= 0);
assert_se(!need_nl);
assert_se(r == 'c');
- assert_se(read_one_char(file, &r, 1000000, &need_nl) < 0);
+ assert_se(read_one_char(file, &r, 1000000, /* echo= */ true, &need_nl) < 0);
rewind(file);
assert_se(fputs("foobar\n", file) >= 0);
rewind(file);
- assert_se(read_one_char(file, &r, 1000000, &need_nl) < 0);
+ assert_se(read_one_char(file, &r, 1000000, /* echo= */ true, &need_nl) < 0);
rewind(file);
assert_se(fputs("\n", file) >= 0);
rewind(file);
- assert_se(read_one_char(file, &r, 1000000, &need_nl) < 0);
+ assert_se(read_one_char(file, &r, 1000000, /* echo= */ true, &need_nl) < 0);
}
TEST(getttyname_malloc) {