]> icculus.org git repositories - icculus/xz.git/blob - src/lzma/error.c
Replaced the range decoder optimization that used arithmetic
[icculus/xz.git] / src / lzma / error.c
1 ///////////////////////////////////////////////////////////////////////////////
2 //
3 /// \file       error.c
4 /// \brief      Error message printing
5 //
6 //  Copyright (C) 2007 Lasse Collin
7 //
8 //  This program is free software; you can redistribute it and/or
9 //  modify it under the terms of the GNU Lesser General Public
10 //  License as published by the Free Software Foundation; either
11 //  version 2.1 of the License, or (at your option) any later version.
12 //
13 //  This program is distributed in the hope that it will be useful,
14 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
15 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16 //  Lesser General Public License for more details.
17 //
18 ///////////////////////////////////////////////////////////////////////////////
19
20 #include "private.h"
21 #include <stdarg.h>
22
23
24 exit_status_type exit_status = SUCCESS;
25 verbosity_type verbosity = V_WARNING;
26 char *argv0 = NULL;
27 volatile sig_atomic_t user_abort = 0;
28
29
30 extern const char *
31 str_strm_error(lzma_ret code)
32 {
33         switch (code) {
34         case LZMA_OK:
35                 return _("Operation successful");
36
37         case LZMA_STREAM_END:
38                 return _("Operation finished successfully");
39
40         case LZMA_PROG_ERROR:
41                 return _("Internal error (bug)");
42
43         case LZMA_DATA_ERROR:
44                 return _("Compressed data is corrupt");
45
46         case LZMA_MEM_ERROR:
47                 return strerror(ENOMEM);
48
49         case LZMA_BUF_ERROR:
50                 return _("Unexpected end of input");
51
52         case LZMA_HEADER_ERROR:
53                 return _("Unsupported options");
54
55         case LZMA_UNSUPPORTED_CHECK:
56                 return _("Unsupported integrity check type");
57
58         default:
59                 return NULL;
60         }
61 }
62
63
64 extern void
65 set_exit_status(exit_status_type new_status)
66 {
67         static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
68         pthread_mutex_lock(&mutex);
69
70         if (new_status != WARNING || exit_status == SUCCESS)
71                 exit_status = new_status;
72
73         pthread_mutex_unlock(&mutex);
74         return;
75 }
76
77
78 extern void lzma_attribute((noreturn))
79 my_exit(int status)
80 {
81         // Close stdout. If something goes wrong, print an error message
82         // to stderr.
83         {
84                 const int ferror_err = ferror(stdout);
85                 const int fclose_err = fclose(stdout);
86                 if (fclose_err) {
87                         errmsg(V_ERROR, _("Writing to standard output "
88                                         "failed: %s"), strerror(errno));
89                         status = ERROR;
90                 } else if (ferror_err) {
91                         // Some error has occurred but we have no clue about
92                         // the reason since fclose() succeeded.
93                         errmsg(V_ERROR, _("Writing to standard output "
94                                         "failed: %s"), "Unknown error");
95                         status = ERROR;
96                 }
97         }
98
99         // Close stderr. If something goes wrong, there's nothing where we
100         // could print an error message. Just set the exit status.
101         {
102                 const int ferror_err = ferror(stderr);
103                 const int fclose_err = fclose(stderr);
104                 if (fclose_err || ferror_err)
105                         status = ERROR;
106         }
107
108         exit(status);
109 }
110
111
112 extern void lzma_attribute((format(printf, 2, 3)))
113 errmsg(verbosity_type v, const char *fmt, ...)
114 {
115         va_list ap;
116
117         if (v <= verbosity) {
118                 va_start(ap, fmt);
119
120                 static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
121                 pthread_mutex_lock(&mutex);
122
123                 fprintf(stderr, "%s: ", argv0);
124                 vfprintf(stderr, fmt, ap);
125                 fprintf(stderr, "\n");
126
127                 pthread_mutex_unlock(&mutex);
128
129                 va_end(ap);
130         }
131
132         if (v == V_ERROR)
133                 set_exit_status(ERROR);
134         else if (v == V_WARNING)
135                 set_exit_status(WARNING);
136
137         return;
138 }
139
140
141 extern void
142 out_of_memory(void)
143 {
144         errmsg(V_ERROR, "%s", strerror(ENOMEM));
145         user_abort = 1;
146         return;
147 }
148
149
150 extern void
151 internal_error(void)
152 {
153         errmsg(V_ERROR, _("Internal error (bug)"));
154         user_abort = 1;
155         return;
156 }