]> icculus.org git repositories - icculus/xz.git/blob - src/lzma/error.c
Update the code to mostly match the new simpler file format
[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         case LZMA_MEMLIMIT_ERROR:
59                 return _("Memory usage limit reached");
60
61         case LZMA_FORMAT_ERROR:
62                 return _("File format not recognized");
63
64         default:
65                 return NULL;
66         }
67 }
68
69
70 extern void
71 set_exit_status(exit_status_type new_status)
72 {
73         static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
74         pthread_mutex_lock(&mutex);
75
76         if (new_status != WARNING || exit_status == SUCCESS)
77                 exit_status = new_status;
78
79         pthread_mutex_unlock(&mutex);
80         return;
81 }
82
83
84 extern void lzma_attribute((noreturn))
85 my_exit(int status)
86 {
87         // Close stdout. If something goes wrong, print an error message
88         // to stderr.
89         {
90                 const int ferror_err = ferror(stdout);
91                 const int fclose_err = fclose(stdout);
92                 if (fclose_err) {
93                         errmsg(V_ERROR, _("Writing to standard output "
94                                         "failed: %s"), strerror(errno));
95                         status = ERROR;
96                 } else if (ferror_err) {
97                         // Some error has occurred but we have no clue about
98                         // the reason since fclose() succeeded.
99                         errmsg(V_ERROR, _("Writing to standard output "
100                                         "failed: %s"), "Unknown error");
101                         status = ERROR;
102                 }
103         }
104
105         // Close stderr. If something goes wrong, there's nothing where we
106         // could print an error message. Just set the exit status.
107         {
108                 const int ferror_err = ferror(stderr);
109                 const int fclose_err = fclose(stderr);
110                 if (fclose_err || ferror_err)
111                         status = ERROR;
112         }
113
114         exit(status);
115 }
116
117
118 extern void lzma_attribute((format(printf, 2, 3)))
119 errmsg(verbosity_type v, const char *fmt, ...)
120 {
121         va_list ap;
122
123         if (v <= verbosity) {
124                 va_start(ap, fmt);
125
126                 static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
127                 pthread_mutex_lock(&mutex);
128
129                 fprintf(stderr, "%s: ", argv0);
130                 vfprintf(stderr, fmt, ap);
131                 fprintf(stderr, "\n");
132
133                 pthread_mutex_unlock(&mutex);
134
135                 va_end(ap);
136         }
137
138         if (v == V_ERROR)
139                 set_exit_status(ERROR);
140         else if (v == V_WARNING)
141                 set_exit_status(WARNING);
142
143         return;
144 }
145
146
147 extern void
148 out_of_memory(void)
149 {
150         errmsg(V_ERROR, "%s", strerror(ENOMEM));
151         user_abort = 1;
152         return;
153 }
154
155
156 extern void
157 internal_error(void)
158 {
159         errmsg(V_ERROR, _("Internal error (bug)"));
160         user_abort = 1;
161         return;
162 }