From a7b4708bd25cc7814e385a75b1114e2ac1cce7a6 Mon Sep 17 00:00:00 2001 From: Con Kolivas Date: Mon, 21 Feb 2011 14:51:20 +1100 Subject: [PATCH] Use a different failure mode for when perror is unlikely to be set. Add 2 unlikely wrappers. --- main.c | 30 +++++++++++++++--------------- runzip.c | 10 +++++----- rzip.c | 4 ++-- rzip.h | 1 + stream.c | 14 +++++++------- util.c | 28 ++++++++++++++++++++++------ 6 files changed, 52 insertions(+), 35 deletions(-) diff --git a/main.c b/main.c index c8c46e2..82d693f 100644 --- a/main.c +++ b/main.c @@ -112,7 +112,7 @@ static void read_magic(int fd_in, i64 *expected_size) *expected_size = 0; if (unlikely(strncmp(magic, "LRZI", 4))) - fatal("Not an lrzip file\n"); + failure("Not an lrzip file\n"); memcpy(&control.major_version, &magic[4], 1); memcpy(&control.minor_version, &magic[5], 1); @@ -646,7 +646,7 @@ int main(int argc, char *argv[]) switch (c) { case 'b': if (control.flags & FLAG_NOT_LZMA) - fatal("Can only use one of -l, -b, -g, -z or -n\n"); + failure("Can only use one of -l, -b, -g, -z or -n\n"); control.flags |= FLAG_BZIP2_COMPRESS; break; case 'c': @@ -664,7 +664,7 @@ int main(int argc, char *argv[]) break; case 'g': if (control.flags & FLAG_NOT_LZMA) - fatal("Can only use one of -l, -b, -g, -z or -n\n"); + failure("Can only use one of -l, -b, -g, -z or -n\n"); control.flags |= FLAG_ZLIB_COMPRESS; break; case 'h': @@ -682,35 +682,35 @@ int main(int argc, char *argv[]) break; case 'l': if (control.flags & FLAG_NOT_LZMA) - fatal("Can only use one of -l, -b, -g, -z or -n\n"); + failure("Can only use one of -l, -b, -g, -z or -n\n"); control.flags |= FLAG_LZO_COMPRESS; break; case 'L': control.compression_level = atoi(optarg); if (control.compression_level < 1 || control.compression_level > 9) - fatal("Invalid compression level (must be 1-9)\n"); + failure("Invalid compression level (must be 1-9)\n"); break; case 'M': control.flags |= FLAG_MAXRAM; break; case 'n': if (control.flags & FLAG_NOT_LZMA) - fatal("Can only use one of -l, -b, -g, -z or -n\n"); + failure("Can only use one of -l, -b, -g, -z or -n\n"); control.flags |= FLAG_NO_COMPRESS; break; case 'N': control.nice_val = atoi(optarg); if (control.nice_val < -20 || control.nice_val > 19) - fatal("Invalid nice value (must be -20..19)\n"); + failure("Invalid nice value (must be -20..19)\n"); break; case 'o': if (control.outdir) - fatal("Cannot have -o and -O together\n"); + failure("Cannot have -o and -O together\n"); control.outname = optarg; break; case 'O': if (control.outname) /* can't mix -o and -O */ - fatal("Cannot have options -o and -O together\n"); + failure("Cannot have options -o and -O together\n"); control.outdir = malloc(strlen(optarg) + 2); if (control.outdir == NULL) fatal("Failed to allocate for outdir\n"); @@ -721,7 +721,7 @@ int main(int argc, char *argv[]) case 'p': control.threads = atoi(optarg); if (control.threads < 1) - fatal("Must have at least one thread\n"); + failure("Must have at least one thread\n"); break; case 'q': control.flags &= ~FLAG_SHOW_PROGRESS; @@ -731,9 +731,9 @@ int main(int argc, char *argv[]) break; case 't': if (control.outname) - fatal("Cannot specify an output file name when just testing.\n"); + failure("Cannot specify an output file name when just testing.\n"); if (!KEEP_FILES) - fatal("Doubt that you want to delete a file when just testing.\n"); + failure("Doubt that you want to delete a file when just testing.\n"); control.flags |= FLAG_TEST_ONLY; break; case 'T': @@ -742,7 +742,7 @@ int main(int argc, char *argv[]) */ control.threshold = atoi(optarg); if (control.threshold < 0 || control.threshold > 10) - fatal("Threshold value must be between 0 and 10\n"); + failure("Threshold value must be between 0 and 10\n"); control.threshold = 1.05 - control.threshold / 20; break; case 'U': @@ -767,7 +767,7 @@ int main(int argc, char *argv[]) break; case 'z': if (control.flags & FLAG_NOT_LZMA) - fatal("Can only use one of -l, -b, -g, -z or -n\n"); + failure("Can only use one of -l, -b, -g, -z or -n\n"); control.flags |= FLAG_ZPAQ_COMPRESS; break; } @@ -777,7 +777,7 @@ int main(int argc, char *argv[]) argv += optind; if (control.outname && argc > 1) - fatal("Cannot specify output filename with more than 1 file\n"); + failure("Cannot specify output filename with more than 1 file\n"); if (VERBOSE && !SHOW_PROGRESS) { print_err("Cannot have -v and -q options. -v wins.\n"); diff --git a/runzip.c b/runzip.c index 0ec18b2..49f9c59 100644 --- a/runzip.c +++ b/runzip.c @@ -69,7 +69,7 @@ static i64 unzip_literal(void *ss, i64 len, int fd_out, uint32 *cksum) uchar *buf; if (unlikely(len < 0)) - fatal("len %lld is negative in unzip_literal!\n",len); + failure("len %lld is negative in unzip_literal!\n",len); buf = (uchar *)malloc(len); if (unlikely(!buf)) @@ -97,7 +97,7 @@ static i64 unzip_match(void *ss, i64 len, int fd_out, int fd_hist, uint32 *cksum uchar *buf, *off_buf; if (unlikely(len < 0)) - fatal("len %lld is negative in unzip_match!\n",len); + failure("len %lld is negative in unzip_match!\n",len); total = 0; cur_pos = lseek(fd_out, 0, SEEK_CUR); @@ -218,7 +218,7 @@ static i64 runzip_chunk(int fd_in, int fd_out, int fd_hist, i64 expected_size, i if (!HAS_MD5) { good_cksum = read_u32(ss, 0); if (unlikely(good_cksum != cksum)) - fatal("Bad checksum: 0x%08x - expected: 0x%08x\n", cksum, good_cksum); + failure("Bad checksum: 0x%08x - expected: 0x%08x\n", cksum, good_cksum); print_maxverbose("Checksum for block: 0x%08x\n", cksum); } @@ -266,7 +266,7 @@ i64 runzip_fd(int fd_in, int fd_out, int fd_hist, i64 expected_size) print_output("\nOutput file:"); for (j = 0; j < MD5_DIGEST_SIZE; j++) print_output("%02x", md5_resblock[j] & 0xFF); - fatal("\n"); + failure("\n"); } } @@ -297,7 +297,7 @@ i64 runzip_fd(int fd_in, int fd_out, int fd_hist, i64 expected_size) print_output("\nOutput file:"); for (j = 0; j < MD5_DIGEST_SIZE; j++) print_output("%02x", md5_resblock[j] & 0xFF); - fatal("\n"); + failure("\n"); } print_output("MD5 integrity of written file matches archive\n"); if (!HAS_MD5) diff --git a/rzip.c b/rzip.c index aea98f1..ea2d424 100644 --- a/rzip.c +++ b/rzip.c @@ -589,7 +589,7 @@ static void hash_search(struct rzip_state *st, double pct_base, double pct_multi i64 i, n = MIN(st->chunk_size - p, control.page_size); uchar *ckbuf = malloc(n); - if (!ckbuf) + if (unlikely(!ckbuf)) fatal("Failed to malloc ckbuf in hash_search\n"); for (i = 0; i < n; i++) memcpy(ckbuf + i, get_sb(cksum_limit + i), 1); @@ -610,7 +610,7 @@ static void hash_search(struct rzip_state *st, double pct_base, double pct_multi i64 i, n = st->chunk_size - cksum_limit; uchar *ckbuf = malloc(n); - if (!ckbuf) + if (unlikely(!ckbuf)) fatal("Failed to malloc ckbuf in hash_search\n"); for (i = 0; i < n; i++) memcpy(ckbuf + i, get_sb(cksum_limit + i), 1); diff --git a/rzip.h b/rzip.h index ea15b14..f7474e5 100644 --- a/rzip.h +++ b/rzip.h @@ -142,6 +142,7 @@ typedef uint32_t u32; #endif void fatal(const char *format, ...); +void failure(const char *format, ...); #ifdef __APPLE__ #include diff --git a/stream.c b/stream.c index c01c72a..af84c57 100644 --- a/stream.c +++ b/stream.c @@ -94,7 +94,7 @@ static inline FILE *fake_fmemopen(void *buf, size_t buflen, char *mode) FILE *in; if (unlikely(strcmp(mode, "r"))) - fatal("fake_fmemopen only supports mode \"r\"."); + failure("fake_fmemopen only supports mode \"r\"."); in = tmpfile(); if (unlikely(!in)) return NULL; @@ -109,7 +109,7 @@ static inline FILE *fake_open_memstream(char **buf, size_t *length) FILE *out; if (unlikely(buf == NULL || length == NULL)) - fatal("NULL parameter to fake_open_memstream"); + failure("NULL parameter to fake_open_memstream"); out = tmpfile(); if (unlikely(!out)) return NULL; @@ -949,14 +949,14 @@ retry: ret = gzip_compress_buf(cti); else if (ZPAQ_COMPRESS) ret = zpaq_compress_buf(cti, i); - else fatal("Dunno wtf compression to use!\n"); + else failure("Dunno wtf compression to use!\n"); } /* If compression fails for whatever reason multithreaded, then wait * for the previous thread to finish, serialising the work to decrease * the memory requirements, increasing the chance of success */ if (unlikely(ret && waited)) - fatal("Failed to compress in compthread\n"); + failure("Failed to compress in compthread\n"); if (!waited) { lock_mutex(&output_lock); @@ -1087,7 +1087,7 @@ retry: ret = zpaq_decompress_buf(uci, i); break; default: - fatal("Dunno wtf decompression type to use!\n"); + failure("Dunno wtf decompression type to use!\n"); break; } } @@ -1096,7 +1096,7 @@ retry: * parallel */ if (unlikely(ret)) { if (unlikely(waited)) - fatal("Failed to decompress in ucompthread\n"); + failure("Failed to decompress in ucompthread\n"); print_maxverbose("Unable to decompress in parallel, waiting for previous thread to complete before trying again\n"); /* We do not strictly need to wait for this, so it's used when * decompression fails due to inadequate memory to try again @@ -1127,7 +1127,7 @@ static int fill_buffer(struct stream_info *sinfo, int stream) goto out; fill_another: if (unlikely(ucthread[s->uthread_no].busy)) - fatal("Trying to start a busy thread, this shouldn't happen!\n"); + failure("Trying to start a busy thread, this shouldn't happen!\n"); if (unlikely(seekto(sinfo, s->last_head))) return -1; diff --git a/util.c b/util.c index 53984ec..6f2aea1 100644 --- a/util.c +++ b/util.c @@ -42,6 +42,7 @@ static void unlink_files(void) unlink(control.infile); } +/* Failure when there is likely to be a meaningful error in perror */ void fatal(const char *format, ...) { va_list ap; @@ -58,6 +59,21 @@ void fatal(const char *format, ...) exit(1); } +void failure(const char *format, ...) +{ + va_list ap; + + if (format) { + va_start(ap, format); + vfprintf(stderr, format, ap); + va_end(ap); + } + + unlink_files(); + print_output("Fatal error - exiting\n"); + exit(1); +} + void sighandler() { unlink_files(); @@ -131,11 +147,11 @@ void read_config( struct rzip_control *control ) } else if (!strcasecmp(parameter, "compressionlevel")) { control->compression_level = atoi(parametervalue); if ( control->compression_level < 1 || control->compression_level > 9 ) - fatal("CONF.FILE error. Compression Level must between 1 and 9"); + failure("CONF.FILE error. Compression Level must between 1 and 9"); } else if (!strcasecmp(parameter, "compressionmethod")) { /* valid are rzip, gzip, bzip2, lzo, lzma (default), and zpaq */ if (control->flags & FLAG_NOT_LZMA) - fatal("CONF.FILE error. Can only specify one compression method"); + failure("CONF.FILE error. Can only specify one compression method"); if (!strcasecmp(parametervalue, "bzip2")) control->flags |= FLAG_BZIP2_COMPRESS; else if (!strcasecmp(parametervalue, "gzip")) @@ -147,11 +163,11 @@ void read_config( struct rzip_control *control ) else if (!strcasecmp(parametervalue, "zpaq")) control->flags |= FLAG_ZPAQ_COMPRESS; else if (strcasecmp(parametervalue, "lzma")) - fatal("CONF.FILE error. Invalid compression method %s specified",parametervalue); + failure("CONF.FILE error. Invalid compression method %s specified",parametervalue); } else if (!strcasecmp(parameter, "testthreshold")) { control->threshold = atoi(parametervalue); if (control->threshold < 1 || control->threshold > 10) - fatal("CONF.FILE error. Threshold value out of range %d", parametervalue); + failure("CONF.FILE error. Threshold value out of range %d", parametervalue); control->threshold = 1.05-control->threshold / 20; } else if (!strcasecmp(parameter, "outputdirectory")) { control->outdir = malloc(strlen(parametervalue) + 2); @@ -162,7 +178,7 @@ void read_config( struct rzip_control *control ) strcat(control->outdir, "/"); } else if (!strcasecmp(parameter,"verbosity")) { if (control->flags & FLAG_VERBOSE) - fatal("CONF.FILE error. Verbosity already defined."); + failure("CONF.FILE error. Verbosity already defined."); if (!strcasecmp(parametervalue, "true") || !strcasecmp(parametervalue, "1")) control->flags |= FLAG_VERBOSITY; @@ -171,7 +187,7 @@ void read_config( struct rzip_control *control ) } else if (!strcasecmp(parameter,"nice")) { control->nice_val = atoi(parametervalue); if (control->nice_val < -20 || control->nice_val > 19) - fatal("CONF.FILE error. Nice must be between -20 and 19"); + failure("CONF.FILE error. Nice must be between -20 and 19"); } else if (!strcasecmp(parameter, "showprogress")) { /* true by default */ if (!strcasecmp(parametervalue, "false") || !strcasecmp(parametervalue," 0"))