Added more wrappers for functions that make system calls
Added the following wrappers that check the results of system calls and exit non-zero if something went wrong. This is so bwa can be more robust against system failures (e.g. IO errors from remote storage, or running out of memory). The existing and new wrappers have also been modified so that they no longer try to dump core on failure. In most cases the resulting core files are not useful (especially if bwa was compiled with optimization turned on) so just pollute whatever directories they got written to. Wrappers for memory allocation functions: xcalloc xmalloc xrealloc xstrdup New wrappers for IO functions: err_fread_noeof (also dies on EOF) err_gzread err_fseek err_rewind err_ftell
This commit is contained in:
parent
292f9061ab
commit
752ce69b78
134
utils.c
134
utils.c
|
|
@ -41,33 +41,44 @@ FILE *err_xopen_core(const char *func, const char *fn, const char *mode)
|
|||
if (strcmp(fn, "-") == 0)
|
||||
return (strstr(mode, "r"))? stdin : stdout;
|
||||
if ((fp = fopen(fn, mode)) == 0) {
|
||||
fprintf(stderr, "[%s] fail to open file '%s'. Abort!\n", func, fn);
|
||||
abort();
|
||||
err_fatal(func, "fail to open file '%s' : %s", fn, strerror(errno));
|
||||
}
|
||||
return fp;
|
||||
}
|
||||
FILE *err_xreopen_core(const char *func, const char *fn, const char *mode, FILE *fp)
|
||||
{
|
||||
if (freopen(fn, mode, fp) == 0) {
|
||||
fprintf(stderr, "[%s] fail to open file '%s': ", func, fn);
|
||||
perror(NULL);
|
||||
fprintf(stderr, "Abort!\n");
|
||||
abort();
|
||||
err_fatal(func, "fail to open file '%s' : %s", fn, strerror(errno));
|
||||
}
|
||||
return fp;
|
||||
}
|
||||
gzFile err_xzopen_core(const char *func, const char *fn, const char *mode)
|
||||
{
|
||||
gzFile fp;
|
||||
if (strcmp(fn, "-") == 0)
|
||||
return gzdopen(fileno((strstr(mode, "r"))? stdin : stdout), mode);
|
||||
if (strcmp(fn, "-") == 0) {
|
||||
fp = gzdopen(fileno((strstr(mode, "r"))? stdin : stdout), mode);
|
||||
/* According to zlib.h, this is the only reason gzdopen can fail */
|
||||
if (!fp) err_fatal(func, "Out of memory");
|
||||
return fp;
|
||||
}
|
||||
if ((fp = gzopen(fn, mode)) == 0) {
|
||||
fprintf(stderr, "[%s] fail to open file '%s'. Abort!\n", func, fn);
|
||||
abort();
|
||||
err_fatal(func, "fail to open file '%s' : %s", fn, errno ? strerror(errno) : "Out of memory");
|
||||
}
|
||||
return fp;
|
||||
}
|
||||
|
||||
void err_fatal(const char *header, const char *fmt, ...)
|
||||
{
|
||||
va_list args;
|
||||
va_start(args, fmt);
|
||||
fprintf(stderr, "[%s] ", header);
|
||||
vfprintf(stderr, fmt, args);
|
||||
fprintf(stderr, "\n");
|
||||
va_end(args);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
void err_fatal_core(const char *header, const char *fmt, ...)
|
||||
{
|
||||
va_list args;
|
||||
va_start(args, fmt);
|
||||
|
|
@ -78,7 +89,13 @@ void err_fatal(const char *header, const char *fmt, ...)
|
|||
abort();
|
||||
}
|
||||
|
||||
void err_fatal_simple_core(const char *func, const char *msg)
|
||||
void _err_fatal_simple(const char *func, const char *msg)
|
||||
{
|
||||
fprintf(stderr, "[%s] %s\n", func, msg);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
void _err_fatal_simple_core(const char *func, const char *msg)
|
||||
{
|
||||
fprintf(stderr, "[%s] %s Abort!\n", func, msg);
|
||||
abort();
|
||||
|
|
@ -89,11 +106,55 @@ size_t err_fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream)
|
|||
size_t ret = fwrite(ptr, size, nmemb, stream);
|
||||
if (ret != nmemb)
|
||||
{
|
||||
err_fatal_simple_core("fwrite", strerror(errno));
|
||||
_err_fatal_simple("fwrite", strerror(errno));
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
size_t err_fread_noeof(void *ptr, size_t size, size_t nmemb, FILE *stream)
|
||||
{
|
||||
size_t ret = fread(ptr, size, nmemb, stream);
|
||||
if (ret != nmemb)
|
||||
{
|
||||
_err_fatal_simple("fread", ferror(stream) ? strerror(errno) : "Unexpected end of file");
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int err_gzread(gzFile file, void *ptr, unsigned int len)
|
||||
{
|
||||
int ret = gzread(file, ptr, len);
|
||||
|
||||
if (ret < 0)
|
||||
{
|
||||
int errnum = 0;
|
||||
const char *msg = gzerror(file, &errnum);
|
||||
_err_fatal_simple("gzread", Z_ERRNO == errnum ? strerror(errno) : msg);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int err_fseek(FILE *stream, long offset, int whence)
|
||||
{
|
||||
int ret = fseek(stream, offset, whence);
|
||||
if (0 != ret)
|
||||
{
|
||||
_err_fatal_simple("fseek", strerror(errno));
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
long err_ftell(FILE *stream)
|
||||
{
|
||||
long ret = ftell(stream);
|
||||
if (-1 == ret)
|
||||
{
|
||||
_err_fatal_simple("ftell", strerror(errno));
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int err_printf(const char *format, ...)
|
||||
{
|
||||
va_list arg;
|
||||
|
|
@ -106,7 +167,7 @@ int err_printf(const char *format, ...)
|
|||
|
||||
if (done < 0)
|
||||
{
|
||||
err_fatal_simple_core("vfprintf(stdout)", strerror(saveErrno));
|
||||
_err_fatal_simple("vfprintf(stdout)", strerror(saveErrno));
|
||||
}
|
||||
return done;
|
||||
}
|
||||
|
|
@ -123,7 +184,7 @@ int err_fprintf(FILE *stream, const char *format, ...)
|
|||
|
||||
if (done < 0)
|
||||
{
|
||||
err_fatal_simple_core("vfprintf", strerror(saveErrno));
|
||||
_err_fatal_simple("vfprintf", strerror(saveErrno));
|
||||
}
|
||||
return done;
|
||||
}
|
||||
|
|
@ -133,7 +194,7 @@ int err_fflush(FILE *stream)
|
|||
int ret = fflush(stream);
|
||||
if (ret != 0)
|
||||
{
|
||||
err_fatal_simple_core("fflush", strerror(errno));
|
||||
_err_fatal_simple("fflush", strerror(errno));
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
|
@ -143,11 +204,52 @@ int err_fclose(FILE *stream)
|
|||
int ret = fclose(stream);
|
||||
if (ret != 0)
|
||||
{
|
||||
err_fatal_simple_core("fclose", strerror(errno));
|
||||
_err_fatal_simple("fclose", strerror(errno));
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
void *err_calloc(size_t nmemb, size_t size, const char *file, unsigned int line, const char *func)
|
||||
{
|
||||
void *p = calloc(nmemb, size);
|
||||
if (NULL == p)
|
||||
{
|
||||
err_fatal(func, "Failed to allocate %zd bytes at %s line %u: %s\n", nmemb * size, file, line, strerror(errno));
|
||||
}
|
||||
return p;
|
||||
}
|
||||
|
||||
void *err_malloc(size_t size, const char *file, unsigned int line, const char *func)
|
||||
{
|
||||
void *p = malloc(size);
|
||||
if (NULL == p)
|
||||
{
|
||||
err_fatal(func, "Failed to allocate %zd bytes at %s line %u: %s\n", size, file, line, strerror(errno));
|
||||
}
|
||||
return p;
|
||||
}
|
||||
|
||||
void *err_realloc(void *ptr, size_t size, const char *file, unsigned int line, const char *func)
|
||||
{
|
||||
void *p = realloc(ptr, size);
|
||||
if (NULL == p)
|
||||
{
|
||||
err_fatal(func, "Failed to allocate %zd bytes at %s line %u: %s\n", size, file, line, strerror(errno));
|
||||
}
|
||||
return p;
|
||||
}
|
||||
|
||||
char *err_strdup(const char *s, const char *file, unsigned int line, const char *func)
|
||||
{
|
||||
char *p = strdup(s);
|
||||
|
||||
if (NULL == p)
|
||||
{
|
||||
err_fatal(func, "Failed to allocate %zd bytes at %s line %u: %s\n", strlen(s), file, line, strerror(errno));
|
||||
}
|
||||
return p;
|
||||
}
|
||||
|
||||
double cputime()
|
||||
{
|
||||
struct rusage r;
|
||||
|
|
|
|||
29
utils.h
29
utils.h
|
|
@ -40,22 +40,38 @@
|
|||
|
||||
|
||||
|
||||
#define err_fatal_simple(msg) err_fatal_simple_core(__func__, msg)
|
||||
#define err_fatal_simple(msg) _err_fatal_simple(__func__, msg)
|
||||
#define err_fatal_simple_core(msg) _err_fatal_simple_core(__func__, msg)
|
||||
#define xopen(fn, mode) err_xopen_core(__func__, fn, mode)
|
||||
#define xreopen(fn, mode, fp) err_xreopen_core(__func__, fn, mode, fp)
|
||||
#define xzopen(fn, mode) err_xzopen_core(__func__, fn, mode)
|
||||
#define xassert(cond, msg) if ((cond) == 0) err_fatal_simple_core(__func__, msg)
|
||||
|
||||
#define xassert(cond, msg) if ((cond) == 0) _err_fatal_simple_core(__func__, msg)
|
||||
|
||||
#define xcalloc(n, s) err_calloc( (n), (s), __FILE__, __LINE__, __func__)
|
||||
#define xmalloc(s) err_malloc( (s), __FILE__, __LINE__, __func__)
|
||||
#define xrealloc(p, s) err_realloc((p), (s), __FILE__, __LINE__, __func__)
|
||||
#define xstrdup(s) err_strdup( (s), __FILE__, __LINE__, __func__)
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
void err_fatal(const char *header, const char *fmt, ...);
|
||||
void err_fatal_simple_core(const char *func, const char *msg);
|
||||
void err_fatal(const char *header, const char *fmt, ...) ATTRIBUTE((noreturn));
|
||||
void err_fatal_core(const char *header, const char *fmt, ...) ATTRIBUTE((noreturn));
|
||||
void _err_fatal_simple(const char *func, const char *msg) ATTRIBUTE((noreturn));
|
||||
void _err_fatal_simple_core(const char *func, const char *msg) ATTRIBUTE((noreturn));
|
||||
FILE *err_xopen_core(const char *func, const char *fn, const char *mode);
|
||||
FILE *err_xreopen_core(const char *func, const char *fn, const char *mode, FILE *fp);
|
||||
gzFile err_xzopen_core(const char *func, const char *fn, const char *mode);
|
||||
size_t err_fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream);
|
||||
size_t err_fread_noeof(void *ptr, size_t size, size_t nmemb, FILE *stream);
|
||||
|
||||
int err_gzread(gzFile file, void *ptr, unsigned int len);
|
||||
int err_fseek(FILE *stream, long offset, int whence);
|
||||
#define err_rewind(FP) err_fseek((FP), 0, SEEK_SET)
|
||||
long err_ftell(FILE *stream);
|
||||
int err_fprintf(FILE *stream, const char *format, ...)
|
||||
ATTRIBUTE((format(printf, 2, 3)));
|
||||
int err_printf(const char *format, ...)
|
||||
|
|
@ -63,6 +79,11 @@ extern "C" {
|
|||
int err_fflush(FILE *stream);
|
||||
int err_fclose(FILE *stream);
|
||||
|
||||
void *err_calloc(size_t nmemb, size_t size, const char *file, unsigned int line, const char *func);
|
||||
void *err_malloc(size_t size, const char *file, unsigned int line, const char *func);
|
||||
void *err_realloc(void *ptr, size_t size, const char *file, unsigned int line, const char *func);
|
||||
char *err_strdup(const char *s, const char *file, unsigned int line, const char *func);
|
||||
|
||||
double cputime();
|
||||
double realtime();
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue