Use a different failure mode for when perror is unlikely to be set.

Add 2 unlikely wrappers.
This commit is contained in:
Con Kolivas 2011-02-21 14:51:20 +11:00
parent 9f3256bda8
commit a7b4708bd2
6 changed files with 52 additions and 35 deletions

30
main.c
View file

@ -112,7 +112,7 @@ static void read_magic(int fd_in, i64 *expected_size)
*expected_size = 0; *expected_size = 0;
if (unlikely(strncmp(magic, "LRZI", 4))) 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.major_version, &magic[4], 1);
memcpy(&control.minor_version, &magic[5], 1); memcpy(&control.minor_version, &magic[5], 1);
@ -646,7 +646,7 @@ int main(int argc, char *argv[])
switch (c) { switch (c) {
case 'b': case 'b':
if (control.flags & FLAG_NOT_LZMA) 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; control.flags |= FLAG_BZIP2_COMPRESS;
break; break;
case 'c': case 'c':
@ -664,7 +664,7 @@ int main(int argc, char *argv[])
break; break;
case 'g': case 'g':
if (control.flags & FLAG_NOT_LZMA) 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; control.flags |= FLAG_ZLIB_COMPRESS;
break; break;
case 'h': case 'h':
@ -682,35 +682,35 @@ int main(int argc, char *argv[])
break; break;
case 'l': case 'l':
if (control.flags & FLAG_NOT_LZMA) 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; control.flags |= FLAG_LZO_COMPRESS;
break; break;
case 'L': case 'L':
control.compression_level = atoi(optarg); control.compression_level = atoi(optarg);
if (control.compression_level < 1 || control.compression_level > 9) 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; break;
case 'M': case 'M':
control.flags |= FLAG_MAXRAM; control.flags |= FLAG_MAXRAM;
break; break;
case 'n': case 'n':
if (control.flags & FLAG_NOT_LZMA) 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; control.flags |= FLAG_NO_COMPRESS;
break; break;
case 'N': case 'N':
control.nice_val = atoi(optarg); control.nice_val = atoi(optarg);
if (control.nice_val < -20 || control.nice_val > 19) 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; break;
case 'o': case 'o':
if (control.outdir) if (control.outdir)
fatal("Cannot have -o and -O together\n"); failure("Cannot have -o and -O together\n");
control.outname = optarg; control.outname = optarg;
break; break;
case 'O': case 'O':
if (control.outname) /* can't mix -o and -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); control.outdir = malloc(strlen(optarg) + 2);
if (control.outdir == NULL) if (control.outdir == NULL)
fatal("Failed to allocate for outdir\n"); fatal("Failed to allocate for outdir\n");
@ -721,7 +721,7 @@ int main(int argc, char *argv[])
case 'p': case 'p':
control.threads = atoi(optarg); control.threads = atoi(optarg);
if (control.threads < 1) if (control.threads < 1)
fatal("Must have at least one thread\n"); failure("Must have at least one thread\n");
break; break;
case 'q': case 'q':
control.flags &= ~FLAG_SHOW_PROGRESS; control.flags &= ~FLAG_SHOW_PROGRESS;
@ -731,9 +731,9 @@ int main(int argc, char *argv[])
break; break;
case 't': case 't':
if (control.outname) 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) 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; control.flags |= FLAG_TEST_ONLY;
break; break;
case 'T': case 'T':
@ -742,7 +742,7 @@ int main(int argc, char *argv[])
*/ */
control.threshold = atoi(optarg); control.threshold = atoi(optarg);
if (control.threshold < 0 || control.threshold > 10) 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; control.threshold = 1.05 - control.threshold / 20;
break; break;
case 'U': case 'U':
@ -767,7 +767,7 @@ int main(int argc, char *argv[])
break; break;
case 'z': case 'z':
if (control.flags & FLAG_NOT_LZMA) 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; control.flags |= FLAG_ZPAQ_COMPRESS;
break; break;
} }
@ -777,7 +777,7 @@ int main(int argc, char *argv[])
argv += optind; argv += optind;
if (control.outname && argc > 1) 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) { if (VERBOSE && !SHOW_PROGRESS) {
print_err("Cannot have -v and -q options. -v wins.\n"); print_err("Cannot have -v and -q options. -v wins.\n");

View file

@ -69,7 +69,7 @@ static i64 unzip_literal(void *ss, i64 len, int fd_out, uint32 *cksum)
uchar *buf; uchar *buf;
if (unlikely(len < 0)) 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); buf = (uchar *)malloc(len);
if (unlikely(!buf)) 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; uchar *buf, *off_buf;
if (unlikely(len < 0)) 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; total = 0;
cur_pos = lseek(fd_out, 0, SEEK_CUR); 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) { if (!HAS_MD5) {
good_cksum = read_u32(ss, 0); good_cksum = read_u32(ss, 0);
if (unlikely(good_cksum != cksum)) 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); 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:"); print_output("\nOutput file:");
for (j = 0; j < MD5_DIGEST_SIZE; j++) for (j = 0; j < MD5_DIGEST_SIZE; j++)
print_output("%02x", md5_resblock[j] & 0xFF); 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:"); print_output("\nOutput file:");
for (j = 0; j < MD5_DIGEST_SIZE; j++) for (j = 0; j < MD5_DIGEST_SIZE; j++)
print_output("%02x", md5_resblock[j] & 0xFF); print_output("%02x", md5_resblock[j] & 0xFF);
fatal("\n"); failure("\n");
} }
print_output("MD5 integrity of written file matches archive\n"); print_output("MD5 integrity of written file matches archive\n");
if (!HAS_MD5) if (!HAS_MD5)

4
rzip.c
View file

@ -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); i64 i, n = MIN(st->chunk_size - p, control.page_size);
uchar *ckbuf = malloc(n); uchar *ckbuf = malloc(n);
if (!ckbuf) if (unlikely(!ckbuf))
fatal("Failed to malloc ckbuf in hash_search\n"); fatal("Failed to malloc ckbuf in hash_search\n");
for (i = 0; i < n; i++) for (i = 0; i < n; i++)
memcpy(ckbuf + i, get_sb(cksum_limit + i), 1); 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; i64 i, n = st->chunk_size - cksum_limit;
uchar *ckbuf = malloc(n); uchar *ckbuf = malloc(n);
if (!ckbuf) if (unlikely(!ckbuf))
fatal("Failed to malloc ckbuf in hash_search\n"); fatal("Failed to malloc ckbuf in hash_search\n");
for (i = 0; i < n; i++) for (i = 0; i < n; i++)
memcpy(ckbuf + i, get_sb(cksum_limit + i), 1); memcpy(ckbuf + i, get_sb(cksum_limit + i), 1);

1
rzip.h
View file

@ -142,6 +142,7 @@ typedef uint32_t u32;
#endif #endif
void fatal(const char *format, ...); void fatal(const char *format, ...);
void failure(const char *format, ...);
#ifdef __APPLE__ #ifdef __APPLE__
#include <sys/sysctl.h> #include <sys/sysctl.h>

View file

@ -94,7 +94,7 @@ static inline FILE *fake_fmemopen(void *buf, size_t buflen, char *mode)
FILE *in; FILE *in;
if (unlikely(strcmp(mode, "r"))) if (unlikely(strcmp(mode, "r")))
fatal("fake_fmemopen only supports mode \"r\"."); failure("fake_fmemopen only supports mode \"r\".");
in = tmpfile(); in = tmpfile();
if (unlikely(!in)) if (unlikely(!in))
return NULL; return NULL;
@ -109,7 +109,7 @@ static inline FILE *fake_open_memstream(char **buf, size_t *length)
FILE *out; FILE *out;
if (unlikely(buf == NULL || length == NULL)) if (unlikely(buf == NULL || length == NULL))
fatal("NULL parameter to fake_open_memstream"); failure("NULL parameter to fake_open_memstream");
out = tmpfile(); out = tmpfile();
if (unlikely(!out)) if (unlikely(!out))
return NULL; return NULL;
@ -949,14 +949,14 @@ retry:
ret = gzip_compress_buf(cti); ret = gzip_compress_buf(cti);
else if (ZPAQ_COMPRESS) else if (ZPAQ_COMPRESS)
ret = zpaq_compress_buf(cti, i); 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 /* If compression fails for whatever reason multithreaded, then wait
* for the previous thread to finish, serialising the work to decrease * for the previous thread to finish, serialising the work to decrease
* the memory requirements, increasing the chance of success */ * the memory requirements, increasing the chance of success */
if (unlikely(ret && waited)) if (unlikely(ret && waited))
fatal("Failed to compress in compthread\n"); failure("Failed to compress in compthread\n");
if (!waited) { if (!waited) {
lock_mutex(&output_lock); lock_mutex(&output_lock);
@ -1087,7 +1087,7 @@ retry:
ret = zpaq_decompress_buf(uci, i); ret = zpaq_decompress_buf(uci, i);
break; break;
default: default:
fatal("Dunno wtf decompression type to use!\n"); failure("Dunno wtf decompression type to use!\n");
break; break;
} }
} }
@ -1096,7 +1096,7 @@ retry:
* parallel */ * parallel */
if (unlikely(ret)) { if (unlikely(ret)) {
if (unlikely(waited)) 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"); 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 /* We do not strictly need to wait for this, so it's used when
* decompression fails due to inadequate memory to try again * 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; goto out;
fill_another: fill_another:
if (unlikely(ucthread[s->uthread_no].busy)) 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))) if (unlikely(seekto(sinfo, s->last_head)))
return -1; return -1;

28
util.c
View file

@ -42,6 +42,7 @@ static void unlink_files(void)
unlink(control.infile); unlink(control.infile);
} }
/* Failure when there is likely to be a meaningful error in perror */
void fatal(const char *format, ...) void fatal(const char *format, ...)
{ {
va_list ap; va_list ap;
@ -58,6 +59,21 @@ void fatal(const char *format, ...)
exit(1); 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() void sighandler()
{ {
unlink_files(); unlink_files();
@ -131,11 +147,11 @@ void read_config( struct rzip_control *control )
} else if (!strcasecmp(parameter, "compressionlevel")) { } else if (!strcasecmp(parameter, "compressionlevel")) {
control->compression_level = atoi(parametervalue); control->compression_level = atoi(parametervalue);
if ( control->compression_level < 1 || control->compression_level > 9 ) 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")) { } else if (!strcasecmp(parameter, "compressionmethod")) {
/* valid are rzip, gzip, bzip2, lzo, lzma (default), and zpaq */ /* valid are rzip, gzip, bzip2, lzo, lzma (default), and zpaq */
if (control->flags & FLAG_NOT_LZMA) 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")) if (!strcasecmp(parametervalue, "bzip2"))
control->flags |= FLAG_BZIP2_COMPRESS; control->flags |= FLAG_BZIP2_COMPRESS;
else if (!strcasecmp(parametervalue, "gzip")) else if (!strcasecmp(parametervalue, "gzip"))
@ -147,11 +163,11 @@ void read_config( struct rzip_control *control )
else if (!strcasecmp(parametervalue, "zpaq")) else if (!strcasecmp(parametervalue, "zpaq"))
control->flags |= FLAG_ZPAQ_COMPRESS; control->flags |= FLAG_ZPAQ_COMPRESS;
else if (strcasecmp(parametervalue, "lzma")) 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")) { } else if (!strcasecmp(parameter, "testthreshold")) {
control->threshold = atoi(parametervalue); control->threshold = atoi(parametervalue);
if (control->threshold < 1 || control->threshold > 10) 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; control->threshold = 1.05-control->threshold / 20;
} else if (!strcasecmp(parameter, "outputdirectory")) { } else if (!strcasecmp(parameter, "outputdirectory")) {
control->outdir = malloc(strlen(parametervalue) + 2); control->outdir = malloc(strlen(parametervalue) + 2);
@ -162,7 +178,7 @@ void read_config( struct rzip_control *control )
strcat(control->outdir, "/"); strcat(control->outdir, "/");
} else if (!strcasecmp(parameter,"verbosity")) { } else if (!strcasecmp(parameter,"verbosity")) {
if (control->flags & FLAG_VERBOSE) 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")) if (!strcasecmp(parametervalue, "true") || !strcasecmp(parametervalue, "1"))
control->flags |= FLAG_VERBOSITY; control->flags |= FLAG_VERBOSITY;
@ -171,7 +187,7 @@ void read_config( struct rzip_control *control )
} else if (!strcasecmp(parameter,"nice")) { } else if (!strcasecmp(parameter,"nice")) {
control->nice_val = atoi(parametervalue); control->nice_val = atoi(parametervalue);
if (control->nice_val < -20 || control->nice_val > 19) 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")) { } else if (!strcasecmp(parameter, "showprogress")) {
/* true by default */ /* true by default */
if (!strcasecmp(parametervalue, "false") || !strcasecmp(parametervalue," 0")) if (!strcasecmp(parametervalue, "false") || !strcasecmp(parametervalue," 0"))