1
0
mirror of https://github.com/systemd/systemd.git synced 2024-11-02 10:51:20 +03:00

terminal-util: excorcise fgets()

This commit is contained in:
Lennart Poettering 2018-10-18 13:32:05 +02:00
parent 6d3db278fe
commit 715bcf361d

View File

@ -81,14 +81,16 @@ int chvt(int vt) {
}
int read_one_char(FILE *f, char *ret, usec_t t, bool *need_nl) {
struct termios old_termios, new_termios;
char c, line[LINE_MAX];
_cleanup_free_ char *line = NULL;
struct termios old_termios;
int r;
assert(f);
assert(ret);
/* If this is a terminal, then switch canonical mode off, so that we can read a single character */
if (tcgetattr(fileno(f), &old_termios) >= 0) {
new_termios = old_termios;
struct termios new_termios = old_termios;
new_termios.c_lflag &= ~ICANON;
new_termios.c_cc[VMIN] = 1;
@ -124,11 +126,13 @@ int read_one_char(FILE *f, char *ret, usec_t t, bool *need_nl) {
return -ETIMEDOUT;
}
errno = 0;
if (!fgets(line, sizeof(line), f))
return errno > 0 ? -errno : -EIO;
/* If this is not a terminal, then read a full line instead */
truncate_nl(line);
r = read_line(f, 16, &line); /* longer than necessary, to eat up UTF-8 chars/vt100 key sequences */
if (r < 0)
return r;
if (r == 0)
return -EIO;
if (strlen(line) != 1)
return -EBADMSG;
@ -196,11 +200,13 @@ int ask_char(char *ret, const char *replies, const char *fmt, ...) {
}
int ask_string(char **ret, const char *text, ...) {
int r;
assert(ret);
assert(text);
for (;;) {
char line[LINE_MAX];
_cleanup_free_ char *line = NULL;
va_list ap;
if (colors_enabled())
@ -215,24 +221,14 @@ int ask_string(char **ret, const char *text, ...) {
fflush(stdout);
errno = 0;
if (!fgets(line, sizeof(line), stdin))
return errno > 0 ? -errno : -EIO;
r = read_line(stdin, LONG_LINE_MAX, &line);
if (r < 0)
return r;
if (r == 0)
return -EIO;
if (!endswith(line, "\n"))
putchar('\n');
else {
char *s;
if (isempty(line))
continue;
truncate_nl(line);
s = strdup(line);
if (!s)
return -ENOMEM;
*ret = s;
if (!isempty(line)) {
*ret = TAKE_PTR(line);
return 0;
}
}