diff options
author | Kaz Kylheku <kaz@kylheku.com> | 2017-04-03 21:23:39 -0700 |
---|---|---|
committer | Kaz Kylheku <kaz@kylheku.com> | 2017-04-03 21:23:39 -0700 |
commit | d2aac0db3dbabc163aad4722025db6051f56d804 (patch) | |
tree | 72cff9d5fadf539d25c51c84d9505e97fed86598 /linenoise | |
parent | 5249db385aa8434d19924457a83d8bb164d9fc96 (diff) | |
download | txr-d2aac0db3dbabc163aad4722025db6051f56d804.tar.gz txr-d2aac0db3dbabc163aad4722025db6051f56d804.tar.bz2 txr-d2aac0db3dbabc163aad4722025db6051f56d804.zip |
linenoise: bugfix: use persistent stream for non-tty.
This bug causes data to be thrown away after reading
one line.
* linenoise/linenoise.c (struct lino_state): New member, ifs.
(linenoise): Do not fdopen a new stream on each call, because
this will read a buffer full of data, from which it will just
read one line, and then throw the rest of away when fclose
is called on the stream. Open the stream once and store it
in the ifs member.
(lino_cleanup): If the ifs member is non-null, then
call fclose on it.
Diffstat (limited to 'linenoise')
-rw-r--r-- | linenoise/linenoise.c | 30 |
1 files changed, 18 insertions, 12 deletions
diff --git a/linenoise/linenoise.c b/linenoise/linenoise.c index 50422e50..90fd1529 100644 --- a/linenoise/linenoise.c +++ b/linenoise/linenoise.c @@ -100,6 +100,7 @@ struct lino_state { int ifd; /* Terminal stdin file descriptor. */ int ofd; /* Terminal stdout file descriptor. */ int save_hist_idx; /* Jump to history position on entry into edit */ + FILE *ifs; /* Input stream, used for non-tty mode */ /* Volatile state pertaining to just one linenoise call */ char buf[LINENOISE_MAX_DISP]; /* Displayed line bufer. */ @@ -2185,25 +2186,28 @@ char *linenoise(lino_t *ls, const char *prompt) { int count; - if (!isatty(ls->ifd)) { - int fd = dup(ls->ifd); - FILE *fi = (fd > 0) ? fdopen(fd, "r") : 0; + if (ls->ifs || !isatty(ls->ifd)) { + if (!ls->ifs) { + int fd = dup(ls->ifd); + FILE *fi = (fd > 0) ? fdopen(fd, "r") : 0; - if (!fi) { - ls->error = lino_error; - if (fd > 0) - close(fd); - return 0; + if (!fi) { + ls->error = lino_error; + if (fd > 0) + close(fd); + return 0; + } + + ls->ifs = fi; } + /* Not a tty: read from file / pipe. */ - if (fgets(ls->data, sizeof ls->data, fi) == NULL) { - ls->error = (ferror(fi) ? lino_ioerr : lino_eof); - fclose(fi); + if (fgets(ls->data, sizeof ls->data, ls->ifs) == NULL) { + ls->error = (ferror(ls->ifs) ? lino_ioerr : lino_eof); return 0; } - fclose(fi); count = strlen(ls->data); if (count && ls->data[count-1] == '\n') @@ -2305,6 +2309,8 @@ static void lino_cleanup(lino_t *ls) ls->clip = 0; free(ls->result); ls->result = 0; + if (ls->ifs) + fclose(ls->ifs); } void lino_free(lino_t *ls) |