diff options
-rw-r--r-- | util.c | 47 | ||||
-rw-r--r-- | util.h | 14 |
2 files changed, 34 insertions, 27 deletions
@@ -266,31 +266,6 @@ bool is_nonexistence_error(int error) { return error == ENOENT || errno == ENOTDIR; } -/** Read a line from standard input. */ -static char *xgetline(void) { - char *line = dstralloc(0); - if (!line) { - return NULL; - } - - while (true) { - int c = fgetc(stdin); - if (c == '\n' || c == EOF) { - break; - } - - if (dstrapp(&line, c) != 0) { - goto error; - } - } - - return line; - -error: - dstrfree(line); - return NULL; -} - /** Compile and execute a regular expression for xrpmatch(). */ static int xrpregex(nl_item item, const char *response) { const char *pattern = nl_langinfo(item); @@ -339,9 +314,9 @@ static int xrpmatch(const char *response) { int ynprompt() { fflush(stderr); - char *line = xgetline(); + char *line = xgetdelim(stdin, '\n'); int ret = line ? xrpmatch(line) : -1; - dstrfree(line); + free(line); return ret; } @@ -433,3 +408,21 @@ char *xconfstr(int name) { return str; } + +char *xgetdelim(FILE *file, char delim) { + char *chunk = NULL; + size_t n = 0; + ssize_t len = getdelim(&chunk, &n, delim, file); + if (len >= 0) { + if (chunk[len] == delim) { + chunk[len] = '\0'; + } + return chunk; + } else { + free(chunk); + if (!ferror(file)) { + errno = 0; + } + return NULL; + } +} @@ -26,6 +26,7 @@ #include <regex.h> #include <stdbool.h> #include <stddef.h> +#include <stdio.h> #include <sys/types.h> // Some portability concerns @@ -274,4 +275,17 @@ size_t xwrite(int fd, const void *buf, size_t nbytes); */ char *xconfstr(int name); +/** + * Convenience wrapper for getdelim(). + * + * @param file + * The file to read. + * @param delim + * The delimiter character to split on. + * @return + * The read chunk (without the delimiter), allocated with malloc(). + * NULL is returned on error (errno != 0) or end of file (errno == 0). + */ +char *xgetdelim(FILE *file, char delim); + #endif // BFS_UTIL_H |