summaryrefslogtreecommitdiffstats
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
commit68c39b11f4da3ae352d9dd8dfb35767c69736cfb (patch)
tree72cff9d5fadf539d25c51c84d9505e97fed86598
parent7d265d9f5e901487dc30a57e64cd604430a378b8 (diff)
downloadtxr-68c39b11f4da3ae352d9dd8dfb35767c69736cfb.tar.gz
txr-68c39b11f4da3ae352d9dd8dfb35767c69736cfb.tar.bz2
txr-68c39b11f4da3ae352d9dd8dfb35767c69736cfb.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.
-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)