summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--util.c47
-rw-r--r--util.h14
2 files changed, 34 insertions, 27 deletions
diff --git a/util.c b/util.c
index 207e34d..d913b7d 100644
--- a/util.c
+++ b/util.c
@@ -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;
+ }
+}
diff --git a/util.h b/util.h
index 1a34fba..be38db5 100644
--- a/util.h
+++ b/util.h
@@ -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