svn commit: r277463 - head/usr.bin/grep

Xin LI delphij at FreeBSD.org
Wed Jan 21 01:11:39 UTC 2015


Author: delphij
Date: Wed Jan 21 01:11:37 2015
New Revision: 277463
URL: https://svnweb.freebsd.org/changeset/base/277463

Log:
  Fix xz handling for files larger than 32K.
  
  Submitted by:	Stefan Ehmann <shoesoft gmx net>
  PR:		bin/186861
  MFC after:	2 weeks

Modified:
  head/usr.bin/grep/file.c

Modified: head/usr.bin/grep/file.c
==============================================================================
--- head/usr.bin/grep/file.c	Wed Jan 21 01:07:58 2015	(r277462)
+++ head/usr.bin/grep/file.c	Wed Jan 21 01:11:37 2015	(r277463)
@@ -65,6 +65,8 @@ __FBSDID("$FreeBSD$");
 static gzFile gzbufdesc;
 #ifndef WITHOUT_LZMA
 static lzma_stream lstrm = LZMA_STREAM_INIT;
+static lzma_action laction;
+static uint8_t lin_buf[MAXBUFSIZ];
 #endif
 #ifndef WITHOUT_BZIP2
 static BZFILE* bzbufdesc;
@@ -123,34 +125,34 @@ grep_refill(struct file *f)
 #endif
 #ifndef WITHOUT_LZMA
 	} else if ((filebehave == FILE_XZ) || (filebehave == FILE_LZMA)) {
-		lzma_action action = LZMA_RUN;
-		uint8_t in_buf[MAXBUFSIZ];
 		lzma_ret ret;
+		lstrm.next_out = buffer;
 
-		ret = (filebehave == FILE_XZ) ?
-		    lzma_stream_decoder(&lstrm, UINT64_MAX,
-		    LZMA_CONCATENATED) :
-		    lzma_alone_decoder(&lstrm, UINT64_MAX);
+		do {
+			if (lstrm.avail_in == 0) {
+				lstrm.next_in = lin_buf;
+				nr = read(f->fd, lin_buf, MAXBUFSIZ);
+
+				if (nr < 0)
+					return (-1);
+				else if (nr == 0)
+					laction = LZMA_FINISH;
 
-		if (ret != LZMA_OK)
-			return (-1);
+				lstrm.avail_in = nr;
+			}
 
-		lstrm.next_out = buffer;
-		lstrm.avail_out = MAXBUFSIZ;
-		lstrm.next_in = in_buf;
-		nr = read(f->fd, in_buf, MAXBUFSIZ);
+			ret = lzma_code(&lstrm, laction);
+
+			if (ret != LZMA_OK && ret != LZMA_STREAM_END)
+				return (-1);
+
+			if (lstrm.avail_out == 0 || ret == LZMA_STREAM_END) {
+				bufrem = MAXBUFSIZ - lstrm.avail_out;
+				lstrm.next_out = buffer;
+				lstrm.avail_out = MAXBUFSIZ;
+			}
+		} while (bufrem == 0 && ret != LZMA_STREAM_END);
 
-		if (nr < 0)
-			return (-1);
-		else if (nr == 0)
-			action = LZMA_FINISH;
-
-		lstrm.avail_in = nr;
-		ret = lzma_code(&lstrm, action);
-
-		if (ret != LZMA_OK && ret != LZMA_STREAM_END)
-			return (-1);
-		bufrem = MAXBUFSIZ - lstrm.avail_out;
 		return (0);
 #endif	/* WIHTOUT_LZMA */
 	} else
@@ -291,6 +293,23 @@ grep_open(const char *path)
 	    (bzbufdesc = BZ2_bzdopen(f->fd, "r")) == NULL)
 		goto error2;
 #endif
+#ifndef WITHOUT_LZMA
+	else if ((filebehave == FILE_XZ) || (filebehave == FILE_LZMA)) {
+		lzma_ret ret;
+
+		ret = (filebehave == FILE_XZ) ?
+			lzma_stream_decoder(&lstrm, UINT64_MAX,
+					LZMA_CONCATENATED) :
+			lzma_alone_decoder(&lstrm, UINT64_MAX);
+
+		if (ret != LZMA_OK)
+			goto error2;
+
+		lstrm.avail_in = 0;
+		lstrm.avail_out = MAXBUFSIZ;
+		laction = LZMA_RUN;
+	}
+#endif
 
 	/* Fill read buffer, also catches errors early */
 	if (bufrem == 0 && grep_refill(f) != 0)


More information about the svn-src-all mailing list