diff options
Diffstat (limited to '')
-rw-r--r-- | src/lzma/error.c | 156 |
1 files changed, 156 insertions, 0 deletions
diff --git a/src/lzma/error.c b/src/lzma/error.c new file mode 100644 index 00000000..a83de27a --- /dev/null +++ b/src/lzma/error.c @@ -0,0 +1,156 @@ +/////////////////////////////////////////////////////////////////////////////// +// +/// \file error.c +/// \brief Error message printing +// +// Copyright (C) 2007 Lasse Collin +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +/////////////////////////////////////////////////////////////////////////////// + +#include "private.h" +#include <stdarg.h> + + +exit_status_type exit_status = SUCCESS; +verbosity_type verbosity = V_WARNING; +char *argv0 = NULL; +volatile sig_atomic_t user_abort = 0; + + +extern const char * +str_strm_error(lzma_ret code) +{ + switch (code) { + case LZMA_OK: + return _("Operation successful"); + + case LZMA_STREAM_END: + return _("Operation finished successfully"); + + case LZMA_PROG_ERROR: + return _("Internal error (bug)"); + + case LZMA_DATA_ERROR: + return _("Compressed data is corrupt"); + + case LZMA_MEM_ERROR: + return strerror(ENOMEM); + + case LZMA_BUF_ERROR: + return _("Unexpected end of input"); + + case LZMA_HEADER_ERROR: + return _("Unsupported options"); + + case LZMA_UNSUPPORTED_CHECK: + return _("Unsupported integrity check type"); + + default: + return NULL; + } +} + + +extern void +set_exit_status(exit_status_type new_status) +{ + static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; + pthread_mutex_lock(&mutex); + + if (new_status != WARNING || exit_status == SUCCESS) + exit_status = new_status; + + pthread_mutex_unlock(&mutex); + return; +} + + +extern void lzma_attribute((noreturn)) +my_exit(int status) +{ + // Close stdout. If something goes wrong, print an error message + // to stderr. + { + const int ferror_err = ferror(stdout); + const int fclose_err = fclose(stdout); + if (fclose_err) { + errmsg(V_ERROR, _("Writing to standard output " + "failed: %s"), strerror(errno)); + status = ERROR; + } else if (ferror_err) { + // Some error has occurred but we have no clue about + // the reason since fclose() succeeded. + errmsg(V_ERROR, _("Writing to standard output " + "failed: %s"), "Unknown error"); + status = ERROR; + } + } + + // Close stderr. If something goes wrong, there's nothing where we + // could print an error message. Just set the exit status. + { + const int ferror_err = ferror(stderr); + const int fclose_err = fclose(stderr); + if (fclose_err || ferror_err) + status = ERROR; + } + + exit(status); +} + + +extern void lzma_attribute((format(printf, 2, 3))) +errmsg(verbosity_type v, const char *fmt, ...) +{ + va_list ap; + + if (v <= verbosity) { + va_start(ap, fmt); + + static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; + pthread_mutex_lock(&mutex); + + fprintf(stderr, "%s: ", argv0); + vfprintf(stderr, fmt, ap); + fprintf(stderr, "\n"); + + pthread_mutex_unlock(&mutex); + + va_end(ap); + } + + if (v == V_ERROR) + set_exit_status(ERROR); + else if (v == V_WARNING) + set_exit_status(WARNING); + + return; +} + + +extern void +out_of_memory(void) +{ + errmsg(V_ERROR, "%s", strerror(ENOMEM)); + user_abort = 1; + return; +} + + +extern void +internal_error(void) +{ + errmsg(V_ERROR, _("Internal error (bug)")); + user_abort = 1; + return; +} |