Created SILC Runtime Toolkit git repository Part II.
[runtime.git] / lib / silcutil / silcerrno.c
1 /*
2
3   silcerrno.c
4
5   Author: Pekka Riikonen <priikone@silcnet.org>
6
7   Copyright (C) 2007 - 2008 Pekka Riikonen
8
9   This program is free software; you can redistribute it and/or modify
10   it under the terms of the GNU General Public License as published by
11   the Free Software Foundation; version 2 of the License.
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
16   GNU General Public License for more details.
17
18 */
19
20 #include "silcruntime.h"
21
22 /* Get last error */
23
24 SilcResult silc_get_errno(void)
25 {
26   SilcTls tls = silc_thread_get_tls();
27
28   if (!tls)
29     return SILC_OK;
30
31   return tls->error;
32 }
33
34 /* Set error */
35
36 void silc_set_errno(SilcResult error)
37 {
38   SilcTls tls = silc_thread_get_tls();
39
40   if (!tls) {
41     /* Try to create Tls */
42     tls = silc_thread_tls_init();
43     if (!tls)
44       return;
45   }
46
47   tls->error_reason[0] = '\0';
48   tls->error = error;
49 }
50
51 /* Set error, cannot fail. */
52
53 void silc_set_errno_nofail(SilcResult error)
54 {
55   SilcTls tls = silc_thread_get_tls();
56
57   if (!tls)
58     return;
59
60   tls->error_reason[0] = '\0';
61   tls->error = error;
62 }
63
64 /* Set errno and reason for error. */
65
66 void silc_set_errno_reason(SilcResult error, const char *format, ...)
67 {
68   SilcTls tls = silc_thread_get_tls();
69   va_list va;
70
71   if (!tls) {
72     /* Try to create Tls */
73     tls = silc_thread_tls_init();
74     if (!tls)
75       return;
76   }
77
78   va_start(va, format);
79   silc_vsnprintf(tls->error_reason, sizeof(tls->error_reason), format, va);
80   va_end(va);
81
82   tls->error = error;
83 }
84
85 /* Set errno and reason for error, cannot fail. */
86
87 void silc_set_errno_reason_nofail(SilcResult error, const char *format, ...)
88 {
89   SilcTls tls = silc_thread_get_tls();
90   va_list va;
91
92   if (!tls)
93     return;
94
95   va_start(va, format);
96   silc_vsnprintf(tls->error_reason, sizeof(tls->error_reason), format, va);
97   va_end(va);
98
99   tls->error = error;
100 }
101
102 /* Set error from POSIX errno. */
103
104 void silc_set_errno_posix(int error)
105 {
106   if (!error)
107     return;
108
109 #ifdef SILC_WIN32
110   /* WSA errors */
111   switch (error) {
112   case WSAEINTR:
113     silc_set_errno(SILC_ERR_INTERRUPTED);
114     break;
115   case WSAEBADF:
116     silc_set_errno(SILC_ERR_BAD_FD);
117     break;
118   case WSAEACCESS:
119     silc_set_errno(SILC_ERR_PERMISSION_DENIED);
120     break;
121   case WSAEFAULT:
122     silc_set_errno(SILC_ERR_BAD_ADDRESS);
123     break;
124   case WSA_INVALID_HANDLE:
125   case WSAENOTSOCK:
126     silc_set_errno(SILC_ERR_BAD_SOCKET);
127     break;
128   case WSA_INVALID_PARAMETER:
129   case WSAEINVAL:
130     silc_set_errno(SILC_ERR_INVALID_ARGUMENT);
131     break;
132   case WSA_NOT_ENOUGH_MEMORY:
133     silc_set_errno(SILC_ERR_OUT_OF_MEMORY);
134     break;
135   case WSAEWOULDBLOCK:
136     silc_set_errno(SILC_ERR_WOULD_BLOCK);
137     break;
138   case WSAEOPNOTSUPPORT:
139     silc_set_errno(SILC_ERR_NOT_SUPPORTED);
140     break;
141   case WSAEADDRINUSE:
142     silc_set_errno(SILC_ERR_ADDR_IN_USE);
143     break;
144   case WSAEANETDOWN:
145     silc_set_errno(SILC_ERR_NET_DOWN);
146     break;
147   case WSAENETUNREACH:
148   case WSAEHOSTUNREACH:
149     silc_set_errno(SILC_ERR_UNREACHABLE);
150     break;
151   case WSAENETRESET:
152     silc_set_errno(SILC_ERR_RESET);
153     break;
154   case WSAECONNABORTED:
155     silc_set_errno(SILC_ERR_ABORTED);
156     break;
157   case WSAETIMEDOUT:
158     silc_set_errno(SILC_ERR_TIMEOUT);
159     break;
160   case WSAECONNREFUSED:
161     silc_set_errno(SILC_ERR_REFUSED);
162     break;
163   case WSAEHOSTDOWN:
164     silc_set_errno(SILC_ERR_HOST_DOWN);
165     break;
166   default:
167     silc_set_errno(SILC_ERR);
168     break;
169   }
170
171   return;
172 #endif /* SILC_WIN32 */
173
174   /* POSIX, etc. errors */
175   switch (error) {
176 #if defined(ENOMEM)
177   case ENOMEM:
178     silc_set_errno(SILC_ERR_OUT_OF_MEMORY);
179     break;
180 #endif
181 #if defined(EAGAIN)
182   case EAGAIN:
183     silc_set_errno(SILC_ERR_WOULD_BLOCK);
184     break;
185 #endif
186 #if defined(EINVAL)
187   case EINVAL:
188     silc_set_errno(SILC_ERR_INVALID_ARGUMENT);
189     break;
190 #endif
191 #if defined(EINTR)
192   case EINTR:
193     silc_set_errno(SILC_ERR_INTERRUPTED);
194     break;
195 #endif
196 #if defined(EIO)
197   case EIO:
198     silc_set_errno(SILC_ERR_IO);
199     break;
200 #endif
201 #if defined(EPIPE)
202   case EPIPE:
203     silc_set_errno(SILC_ERR_BROKEN_PIPE);
204     break;
205 #endif
206 #if defined(ENOENT)
207   case ENOENT:
208     silc_set_errno(SILC_ERR_NO_SUCH_FILE);
209     break;
210 #endif
211 #if defined(EEXIST)
212   case EEXIST:
213     silc_set_errno(SILC_ERR_ALREADY_EXISTS);
214     break;
215 #endif
216 #if defined(ENOTDIR)
217   case ENOTDIR:
218     silc_set_errno(SILC_ERR_NOT_DIRECTORY);
219     break;
220 #endif
221 #if defined(EISDIR)
222   case EISDIR:
223     silc_set_errno(SILC_ERR_IS_DIRECTORY);
224     break;
225 #endif
226 #if defined(EBUSY)
227   case EBUSY:
228     silc_set_errno(SILC_ERR_BUSY);
229     break;
230 #endif
231 #if defined(ENODEV)
232   case ENODEV:
233     silc_set_errno(SILC_ERR_NO_SUCH_DEVICE);
234     break;
235 #endif
236 #if defined(ENOSPC)
237   case ENOSPC:
238     silc_set_errno(SILC_ERR_NO_SPACE_LEFT);
239     break;
240 #endif
241 #if defined(EROFS)
242   case EROFS:
243     silc_set_errno(SILC_ERR_READ_ONLY);
244     break;
245 #endif
246 #if defined(EBADFS)
247   case EBADFS:
248     silc_set_errno(SILC_ERR_BAD_FD);
249     break;
250 #endif
251 #if defined(EADDRINUSE)
252   case EADDRINUSE:
253     silc_set_errno(SILC_ERR_ADDR_IN_USE);
254     break;
255 #endif
256 #if defined(ECONNREFUSED)
257   case ECONNREFUSED:
258     silc_set_errno(SILC_ERR_REFUSED);
259     break;
260 #endif
261 #if defined(ECONNABORTED)
262   case ECONNABORTED:
263     silc_set_errno(SILC_ERR_ABORTED);
264     break;
265 #endif
266 #if defined(ECONNRESET)
267   case ECONNRESET:
268     silc_set_errno(SILC_ERR_RESET);
269     break;
270 #endif
271 #if defined(ENETUNREACH)
272   case ENETUNREACH:
273     silc_set_errno(SILC_ERR_UNREACHABLE);
274     break;
275 #endif
276 #if defined(EHOSTUNREACH)
277   case EHOSTUNREACH:
278     silc_set_errno(SILC_ERR_UNREACHABLE);
279     break;
280 #endif
281 #if defined(ENETDOWN)
282   case ENETDOWN:
283     silc_set_errno(SILC_ERR_NET_DOWN);
284     break;
285 #endif
286 #if defined(ETIMEDOUT)
287   case ETIMEDOUT:
288     silc_set_errno(SILC_ERR_TIMEOUT);
289     break;
290 #endif
291 #if defined(EHOSTDOWN)
292   case EHOSTDOWN:
293     silc_set_errno(SILC_ERR_HOST_DOWN);
294     break;
295 #endif
296   default:
297     silc_set_errno(SILC_ERR);
298     break;
299   }
300 }
301
302 /* Get last reason for error */
303
304 const char *silc_errno_reason(void)
305 {
306   SilcTls tls = silc_thread_get_tls();
307
308   if (!tls || tls->error_reason[0] == '\0')
309     return (const char *)"";
310
311   return tls->error_reason;
312 }
313
314 const char *silc_errno_strings[] =
315 {
316   "Ok",
317
318   "Error",
319   "Out of memory",
320   "Allocation by zero",
321   "Too large allocation",
322   "Overflow",
323   "Underflow",
324   "Feature not supported",
325   "Operation not permitted",
326   "Try again",
327   "Permission denied",
328   "Invalid argument",
329   "Bad time",
330   "Timeout",
331   "Assert",
332   "Not found",
333   "Unknown character",
334   "Prohibited character",
335   "Bad character encoding",
336   "Unsupported character encoding",
337   "Bad version",
338   "Bad memory address",
339   "Bad buffer encoding",
340   "Interrupted",
341   "Not valid",
342   "Limit reached",
343   "Syntax error",
344   "",
345   "",
346   "",
347   "",
348   "",
349   "",
350   "",
351   "",
352   "",
353   "",
354   "",
355   "",
356   "",
357
358   "No such file or directory",
359   "Already exists",
360   "Not a directory",
361   "Is a directory",
362   "Directory not empty",
363   "Device or resource busy",
364   "No such device",
365   "No space left on device",
366   "Broken pipe",
367   "Read only",
368   "I/O error",
369   "Bad file descriptor",
370   "End of file",
371   "",
372   "",
373   "",
374   "",
375   "",
376   "",
377   "",
378   "",
379   "",
380   "",
381   "",
382   "",
383   "",
384   "",
385   "",
386   "",
387   "",
388
389   "Bad IP address",
390   "Unknown IP address",
391   "Unknown host",
392   "Destination unreachable",
393   "Connection refused",
394   "Connection aborted",
395   "Connection reset by peer",
396   "Would block",
397   "Host is down",
398   "Bad socket",
399   "Bad stream",
400   "Address already in use",
401   "Network is down",
402   "End of stream",
403   "",
404   "",
405   "",
406   "",
407   "",
408   "",
409   "",
410   "",
411   "",
412   "",
413   "",
414   "",
415   "",
416   "",
417   "",
418   "",
419
420   "Badly placed parenthesis",
421   "Bad hexadecimal number",
422   "Bad match register number",
423   "Badly placed special character",
424   "Regular expression too complex",
425   "Bad regular expression opcode",
426   "Bad repeat value",
427 };
428
429 /* Map error to string */
430
431 const char *silc_errno_string(SilcResult error)
432 {
433   if (error < 0 || error >= SILC_ERR_MAX)
434     return (const char *)"";
435
436   return silc_errno_strings[error];
437 }