changeset 64:67ee3a0b76e1

In bunzip replace setjmp/longjmp handling with error_exit(), replace string based handling of a 6-byte header with with two 24-bit integer reads. Use xmalloc() and xzalloc().
author Rob Landley <rob@landley.net>
date Thu, 18 Jan 2007 22:00:12 -0500
parents 69efffcacd70
children 329e2b37d0e1
files lib/bunzip.c lib/lib.h toys/bzcat.c
diffstat 3 files changed, 17 insertions(+), 37 deletions(-) [+]
line wrap: on
line diff
--- a/lib/bunzip.c	Thu Jan 18 21:54:08 2007 -0500
+++ b/lib/bunzip.c	Thu Jan 18 22:00:12 2007 -0500
@@ -27,18 +27,12 @@
 #define RETVAL_OK						0
 #define RETVAL_LAST_BLOCK				(-1)
 #define RETVAL_NOT_BZIP_DATA			(-2)
-#define RETVAL_UNEXPECTED_INPUT_EOF		(-3)
-#define RETVAL_UNEXPECTED_OUTPUT_EOF	(-4)
-#define RETVAL_DATA_ERROR				(-5)
-#define RETVAL_OUT_OF_MEMORY			(-6)
-#define RETVAL_OBSOLETE_INPUT			(-7)
+#define RETVAL_DATA_ERROR				(-3)
+#define RETVAL_OBSOLETE_INPUT			(-4)
 
 char *bunzip_errors[]={
 	NULL,
-	"Bad file checksum",
 	"Not bzip data",
-	"Unexpected input EOF",
-	"Unexpected output EOF",
 	"Data error",
 	"Out of memory",
 	"Obsolete (pre 0.9.5) bzip format not supported."
@@ -54,9 +48,6 @@
 // memory that persists between calls to bunzip
 typedef struct {
 
-	// For I/O error handling
-	jmp_buf jmpbuf;
-
 	// Input stream, input buffer, input bit buffer
 	int in_fd, inbufCount, inbufPos;
 	char *inbuf;
@@ -93,7 +84,7 @@
 		// If we need to read more data from file into byte buffer, do so
 		if (bd->inbufPos == bd->inbufCount) {
 			if (0 >= (bd->inbufCount = read(bd->in_fd, bd->inbuf, IOBUF_SIZE)))
-				longjmp(bd->jmpbuf, RETVAL_UNEXPECTED_INPUT_EOF);
+				error_exit("Unexpected input EOF");
 			bd->inbufPos = 0;
 		}
 
@@ -128,20 +119,16 @@
 	char uc, mtfSymbol[256], symToByte[256], *selectors;
 	unsigned int *dbuf;
 
-	// Read in header signature (borrowing mtfSymbol for temp space).
-	for (i=0; i<6; i++) mtfSymbol[i] = get_bits(bd,8);
-	mtfSymbol[6] = 0;
-
-	// Read CRC (which is stored big endian).
+	// Read in header signature and CRC (which is stored big endian)
+	i = get_bits(bd, 24);
+	j = get_bits(bd, 24);
 	bd->headerCRC = get_bits(bd,32);
 
-	// Is this the last block (with CRC for file)?
-	if (!strcmp(mtfSymbol, "\x17\x72\x45\x38\x50\x90"))
-		return RETVAL_LAST_BLOCK;
+	// Is this the EOF block with CRC for whole file?
+	if (i==0x177245 && j==0x385090) return RETVAL_LAST_BLOCK;
 
-	// If it's not a valid data block, barf.
-	if (strcmp(mtfSymbol, "\x31\x41\x59\x26\x53\x59"))
-		return RETVAL_NOT_BZIP_DATA;
+	// Is this a valid data block?
+	if (i!=0x314159 || j!=0x265359) return RETVAL_NOT_BZIP_DATA;
 
 	dbuf = bd->dbuf;
 	dbufSize = bd->dbufSize;
@@ -414,7 +401,7 @@
 {
 	if (bd->outbufPos) {
 		if (write(out_fd, bd->outbuf, bd->outbufPos) != bd->outbufPos)
-			longjmp(bd->jmpbuf,RETVAL_UNEXPECTED_OUTPUT_EOF);
+			error_exit("Unexpected output EOF");
 		bd->outbufPos = 0;
 	}
 }
@@ -526,8 +513,7 @@
 	if (!len) i += IOBUF_SIZE;
 
 	// Allocate bunzip_data.  Most fields initialize to zero.
-	if (!(bd = *bdp = malloc(i))) return RETVAL_OUT_OF_MEMORY;
-	memset(bd,0,sizeof(bunzip_data));
+	bd = *bdp = xzalloc(i);
 	if (len) {
 		bd->inbuf = inbuf;
 		bd->inbufCount = len;
@@ -545,10 +531,6 @@
 		bd->crc32Table[i] = c;
 	}
 
-	// Setup for I/O error handling via longjmp.
-	i = setjmp(bd->jmpbuf);
-	if (i) return i;
-
 	// Ensure that file starts with "BZh".
     for (i=0;i<3;i++)
 		if (get_bits(bd,8)!="BZh"[i]) return RETVAL_NOT_BZIP_DATA;
@@ -558,15 +540,14 @@
 	i = get_bits(bd, 8);
 	if (i<'1' || i>'9') return RETVAL_NOT_BZIP_DATA;
 	bd->dbufSize = 100000*(i-'0');
-	if (!(bd->dbuf = malloc(bd->dbufSize * sizeof(int))))
-		return RETVAL_OUT_OF_MEMORY;
+	bd->dbuf = xmalloc(bd->dbufSize * sizeof(int));
 
 	return RETVAL_OK;
 }
 
 // Example usage: decompress src_fd to dst_fd.  (Stops at end of bzip data,
 // not end of file.)
-char *bunzipStream(int src_fd, int dst_fd)
+void bunzipStream(int src_fd, int dst_fd)
 {
 	bunzip_data *bd;
 	int i;
@@ -578,5 +559,5 @@
 	flush_bunzip_outbuf(bd,dst_fd);
 	free(bd->dbuf);
 	free(bd);
-	return bunzip_errors[-i];
+	if (i) error_exit(bunzip_errors[-i]);
 }
--- a/lib/lib.h	Thu Jan 18 21:54:08 2007 -0500
+++ b/lib/lib.h	Thu Jan 18 22:00:12 2007 -0500
@@ -68,4 +68,4 @@
 
 struct mtab_list *getmountlist(int die);
 
-char *bunzipStream(int src_fd, int dst_fd);
+void bunzipStream(int src_fd, int dst_fd);
--- a/toys/bzcat.c	Thu Jan 18 21:54:08 2007 -0500
+++ b/toys/bzcat.c	Thu Jan 18 22:00:12 2007 -0500
@@ -7,8 +7,7 @@
 
 int bzcat_main(void)
 {
-	char *error = bunzipStream(0, 1);
+	bunzipStream(0, 1);
 
-	if (error) error_exit(error);
 	return 0;
 }