[PATCH] input: Fix pungetc on PEOF

Herbert Xu <[email protected]>
Newsgroups org.kernel.vger.dash
Message-ID <[email protected]>
Calling pungetc upon PEOF must cause the next pgetc call to return
PEOF.  This was broken by the multi-byte pungetc patch.  Fix it by
adding the EOF logic to pgetc.

Note that pungetn will always disregard the PEOF.

Fixes: 2c92409145d0 ("input: Allow MB_LEN_MAX calls to pungetc")
Signed-off-by: Herbert Xu <[email protected]>
---
 src/input.c | 32 ++++++++++++++------------------
 src/input.h |  8 +++++---
 2 files changed, 19 insertions(+), 21 deletions(-)

diff --git a/src/input.c b/src/input.c
index 8f8c173..6388b83 100644
--- a/src/input.c
+++ b/src/input.c
@@ -224,15 +224,13 @@ static int __pgetc(void)
 	if (parsefile->unget) {
 		long unget = -(long)(unsigned)parsefile->unget--;
 
-		if (parsefile->nleft < 0)
-			return preadbuffer();
-
 		return parsefile->nextc[unget];
 	}
 
-	if (--parsefile->nleft >= 0)
+	if (parsefile->nleft > 0) {
+		parsefile->nleft--;
 		c = (signed char)*parsefile->nextc++;
-	else
+	} else
 		c = preadbuffer();
 
 	return c;
@@ -372,8 +370,11 @@ static int preadbuffer(void)
 		popstring();
 		return __pgetc();
 	}
-	if (parsefile->buf == NULL)
+	if (parsefile->eof & 2) {
+eof:
+		parsefile->eof = 3;
 		return PEOF;
+	}
 	flushall();
 
 	q = parsefile->nextc;
@@ -394,7 +395,7 @@ again:
 			if (!IS_DEFINED_SMALL && nr > 0)
 				goto save;
 			INTON;
-			return PEOF;
+			goto eof;
 		}
 	}
 
@@ -477,7 +478,8 @@ void pungetn(int n)
 void
 pungetc(void)
 {
-	pungetn(1);
+	pungetn(1 - (parsefile->eof & 1));
+	parsefile->eof &= ~1;
 }
 
 /*
@@ -575,8 +577,6 @@ setinputfd(int fd, int push)
 		toppf = parsefile;
 	parsefile->fd = fd;
 	parsefile->nextc = parsefile->buf = ckmalloc(IBUFSIZ);
-	input_set_lleft(parsefile, parsefile->nleft = 0);
-	plinno = 1;
 }
 
 
@@ -591,8 +591,7 @@ setinputstring(char *string)
 	pushfile();
 	parsefile->nextc = string;
 	parsefile->nleft = strlen(string);
-	parsefile->buf = NULL;
-	plinno = 1;
+	parsefile->eof = 2;
 	INTON;
 }
 
@@ -609,12 +608,10 @@ pushfile(void)
 	struct parsefile *pf;
 
 	pf = (struct parsefile *)ckmalloc(sizeof (struct parsefile));
+	memset(pf, 0, sizeof(*pf));
 	pf->prev = parsefile;
+	pf->linno = 1;
 	pf->fd = -1;
-	pf->strpush = NULL;
-	pf->spfree = NULL;
-	pf->basestrpush.prev = NULL;
-	pf->unget = 0;
 	parsefile = pf;
 }
 
@@ -639,8 +636,7 @@ popfile(void)
 
 	if (pf->fd >= 0)
 		close(pf->fd);
-	if (pf->buf)
-		ckfree(pf->buf);
+	ckfree(pf->buf);
 	if (parsefile->spfree)
 		freestrings(parsefile->spfree);
 	while (pf->strpush) {
diff --git a/src/input.h b/src/input.h
index af1c1be..706ac73 100644
--- a/src/input.h
+++ b/src/input.h
@@ -79,9 +79,7 @@ struct parsefile {
 	int linno;		/* current line */
 	int fd;			/* file descriptor (or -1 if string) */
 	int nleft;		/* number of chars left in this line */
-#ifndef SMALL
-	int lleft;		/* number of chars left in this buffer */
-#endif
+	int eof;		/* do not read again once we hit EOF */
 	char *nextc;		/* next char in buffer */
 	char *buf;		/* input buffer */
 	struct strpush *strpush; /* for pushing strings at this level */
@@ -90,6 +88,10 @@ struct parsefile {
 	/* Delay freeing so we can stop nested aliases. */
 	struct strpush *spfree;
 
+#ifndef SMALL
+	int lleft;		/* number of chars left in this buffer */
+#endif
+
 	/* Number of outstanding calls to pungetc. */
 	int unget;
 };
-- 
2.39.2

-- 
Email: Herbert Xu <[email protected]>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.