5 Author: Pekka Riikonen <priikone@silcnet.org>
7 Copyright (C) 2007 - 2008 Pekka Riikonen
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.
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.
20 #include "silcruntime.h"
24 SilcResult silc_get_errno(void)
26 SilcTls tls = silc_thread_get_tls();
36 void silc_set_errno(SilcResult error)
38 SilcTls tls = silc_thread_get_tls();
41 /* Try to create Tls */
42 tls = silc_thread_tls_init();
47 tls->error_reason[0] = '\0';
48 tls->filename[0] = '\0';
52 /* Set error, cannot fail. */
54 void silc_set_errno_nofail(SilcResult error)
56 SilcTls tls = silc_thread_get_tls();
61 tls->error_reason[0] = '\0';
62 tls->filename[0] = '\0';
66 /* Set errno and reason for error. */
68 void silc_set_errno_reason(SilcResult error, const char *format, ...)
70 SilcTls tls = silc_thread_get_tls();
74 /* Try to create Tls */
75 tls = silc_thread_tls_init();
82 silc_vsnprintf(tls->error_reason, sizeof(tls->error_reason), format, va);
89 /* Set errno and reason for error, cannot fail. */
91 void silc_set_errno_reason_nofail(SilcResult error, const char *format, ...)
93 SilcTls tls = silc_thread_get_tls();
100 va_start(va, format);
101 silc_vsnprintf(tls->error_reason, sizeof(tls->error_reason), format, va);
108 /* Set error from POSIX errno. */
110 void silc_set_errno_posix(int error)
119 silc_set_errno(SILC_ERR_INTERRUPTED);
122 silc_set_errno(SILC_ERR_BAD_FD);
125 silc_set_errno(SILC_ERR_PERMISSION_DENIED);
128 silc_set_errno(SILC_ERR_BAD_ADDRESS);
130 case WSA_INVALID_HANDLE:
132 silc_set_errno(SILC_ERR_BAD_SOCKET);
134 case WSA_INVALID_PARAMETER:
136 silc_set_errno(SILC_ERR_INVALID_ARGUMENT);
138 case WSA_NOT_ENOUGH_MEMORY:
139 silc_set_errno(SILC_ERR_OUT_OF_MEMORY);
142 silc_set_errno(SILC_ERR_WOULD_BLOCK);
144 case WSAEOPNOTSUPPORT:
145 silc_set_errno(SILC_ERR_NOT_SUPPORTED);
148 silc_set_errno(SILC_ERR_ADDR_IN_USE);
151 silc_set_errno(SILC_ERR_NET_DOWN);
154 case WSAEHOSTUNREACH:
155 silc_set_errno(SILC_ERR_UNREACHABLE);
158 silc_set_errno(SILC_ERR_RESET);
160 case WSAECONNABORTED:
161 silc_set_errno(SILC_ERR_ABORTED);
164 silc_set_errno(SILC_ERR_TIMEOUT);
166 case WSAECONNREFUSED:
167 silc_set_errno(SILC_ERR_REFUSED);
170 silc_set_errno(SILC_ERR_HOST_DOWN);
173 silc_set_errno(SILC_ERR);
178 #endif /* SILC_WIN32 */
180 /* POSIX, etc. errors */
184 silc_set_errno(SILC_ERR_OUT_OF_MEMORY);
189 silc_set_errno(SILC_ERR_WOULD_BLOCK);
194 silc_set_errno(SILC_ERR_INVALID_ARGUMENT);
199 silc_set_errno(SILC_ERR_INTERRUPTED);
204 silc_set_errno(SILC_ERR_IO);
209 silc_set_errno(SILC_ERR_BROKEN_PIPE);
214 silc_set_errno(SILC_ERR_NO_SUCH_FILE);
219 silc_set_errno(SILC_ERR_ALREADY_EXISTS);
224 silc_set_errno(SILC_ERR_NOT_DIRECTORY);
229 silc_set_errno(SILC_ERR_IS_DIRECTORY);
234 silc_set_errno(SILC_ERR_BUSY);
239 silc_set_errno(SILC_ERR_NO_SUCH_DEVICE);
244 silc_set_errno(SILC_ERR_NO_SPACE_LEFT);
249 silc_set_errno(SILC_ERR_READ_ONLY);
254 silc_set_errno(SILC_ERR_BAD_FD);
257 #if defined(EADDRINUSE)
259 silc_set_errno(SILC_ERR_ADDR_IN_USE);
262 #if defined(ECONNREFUSED)
264 silc_set_errno(SILC_ERR_REFUSED);
267 #if defined(ECONNABORTED)
269 silc_set_errno(SILC_ERR_ABORTED);
272 #if defined(ECONNRESET)
274 silc_set_errno(SILC_ERR_RESET);
277 #if defined(ENETUNREACH)
279 silc_set_errno(SILC_ERR_UNREACHABLE);
282 #if defined(EHOSTUNREACH)
284 silc_set_errno(SILC_ERR_UNREACHABLE);
287 #if defined(ENETDOWN)
289 silc_set_errno(SILC_ERR_NET_DOWN);
292 #if defined(ETIMEDOUT)
294 silc_set_errno(SILC_ERR_TIMEOUT);
297 #if defined(EHOSTDOWN)
299 silc_set_errno(SILC_ERR_HOST_DOWN);
303 silc_set_errno(SILC_ERR);
308 /* Get last reason for error */
310 const char *silc_errno_reason(void)
312 SilcTls tls = silc_thread_get_tls();
314 if (!tls || tls->error_reason[0] == '\0')
315 return (const char *)"";
317 return tls->error_reason;
320 const char *silc_errno_strings[] =
326 "Allocation by zero",
327 "Too large allocation",
330 "Feature not supported",
331 "Operation not permitted",
340 "Prohibited character",
341 "Bad character encoding",
342 "Unsupported character encoding",
344 "Bad memory address",
345 "Bad buffer encoding",
364 "No such file or directory",
368 "Directory not empty",
369 "Device or resource busy",
371 "No space left on device",
375 "Bad file descriptor",
396 "Unknown IP address",
398 "Destination unreachable",
399 "Connection refused",
400 "Connection aborted",
401 "Connection reset by peer",
406 "Address already in use",
426 "Badly placed parenthesis",
427 "Bad hexadecimal number",
428 "Bad match register number",
429 "Badly placed special character",
430 "Regular expression too complex",
431 "Bad regular expression opcode",
435 /* Map error to string */
437 const char *silc_errno_string(SilcResult error)
439 if (error < 0 || error >= SILC_ERR_MAX)
440 return (const char *)"";
442 return silc_errno_strings[error];
445 /* Set error location */
447 void silc_set_errno_location(const char *filename,
448 SilcUInt32 current_line_number,
449 SilcUInt32 current_column_number)
451 SilcTls tls = silc_thread_get_tls();
457 silc_snprintf(tls->filename, sizeof(tls->filename), filename);
458 tls->cur_line = current_line_number;
459 tls->cur_column = current_column_number;
462 /* Get error location */
464 SilcBool silc_errno_location(const char **filename,
465 SilcUInt32 *current_line,
466 SilcUInt32 *current_column)
468 SilcTls tls = silc_thread_get_tls();
472 if (tls->filename[0] == '\0' && !tls->cur_line && !tls->cur_column)
476 *filename = tls->filename;
478 *current_line = tls->cur_line;
480 *current_column = tls->cur_column;