summaryrefslogtreecommitdiffstats
path: root/linenoise
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2017-04-03 21:23:39 -0700
committerKaz Kylheku <kaz@kylheku.com>2017-04-03 21:23:39 -0700
commitd2aac0db3dbabc163aad4722025db6051f56d804 (patch)
tree72cff9d5fadf539d25c51c84d9505e97fed86598 /linenoise
parent5249db385aa8434d19924457a83d8bb164d9fc96 (diff)
downloadtxr-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.c30
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)