PageRenderTime 44ms CodeModel.GetById 22ms RepoModel.GetById 0ms app.codeStats 0ms

/tags/wired-1.3/libwired/libwired/base/wi-error.c

https://bitbucket.org/balrog/zanka-full
C | 309 lines | 165 code | 100 blank | 44 comment | 4 complexity | 6e5d0796bfdff62fe098ec43f95231e5 MD5 | raw file
  1. /* $Id$ */
  2. /*
  3. * Copyright (c) 2003-2006 Axel Andersson
  4. * All rights reserved.
  5. *
  6. * Redistribution and use in source and binary forms, with or without
  7. * modification, are permitted provided that the following conditions
  8. * are met:
  9. * 1. Redistributions of source code must retain the above copyright
  10. * notice, this list of conditions and the following disclaimer.
  11. * 2. Redistributions in binary form must reproduce the above copyright
  12. * notice, this list of conditions and the following disclaimer in the
  13. * documentation and/or other materials provided with the distribution.
  14. *
  15. * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
  16. * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  17. * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  18. * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
  19. * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  20. * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
  21. * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  22. * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
  23. * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
  24. * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  25. * POSSIBILITY OF SUCH DAMAGE.
  26. */
  27. #include "config.h"
  28. #include <sys/types.h>
  29. #include <sys/socket.h>
  30. #include <netdb.h>
  31. #include <string.h>
  32. #include <errno.h>
  33. #include <regex.h>
  34. #ifdef WI_SSL
  35. #include <openssl/err.h>
  36. #include <openssl/ssl.h>
  37. #endif
  38. #include <wired/wi-assert.h>
  39. #include <wired/wi-error.h>
  40. #include <wired/wi-hash.h>
  41. #include <wired/wi-runtime.h>
  42. #include <wired/wi-string.h>
  43. #include <wired/wi-thread.h>
  44. #include "wi-private.h"
  45. #define _WI_ERROR_THREAD_KEY "_wi_error_t"
  46. #define _WI_ERROR_ASSERT(error) \
  47. WI_ASSERT((error) != NULL, "no wi_error_t created for thread", 0)
  48. struct _wi_error {
  49. wi_runtime_base_t base;
  50. wi_string_t *string;
  51. wi_error_domain_t domain;
  52. int32_t code;
  53. };
  54. static wi_error_t * _wi_error_alloc(void);
  55. static wi_error_t * _wi_error_init(wi_error_t *);
  56. static void _wi_error_dealloc(wi_runtime_instance_t *);
  57. static wi_error_t * _wi_get_error(void);
  58. static const char *_wi_error_strings[] = {
  59. /* WI_ERROR_NONE */
  60. "No error",
  61. /* WI_ERROR_ADDRESS_NOAVAILABLEADDRESSES */
  62. "No available addresses",
  63. /* WI_ERROR_HOST_NOAVAILABLEADDRESSES */
  64. "No available addresses",
  65. /* WI_ERROR_LOG_NOSUCHFACILITY */
  66. "No such syslog facility",
  67. /* WI_ERROR_REGEXP_NOSLASH */
  68. "Missing \"/\"",
  69. /* WI_ERROR_REGEXP_INVALIDOPTION */
  70. "Invalid option",
  71. /* WI_ERROR_SETTINGS_SYNTAXERROR */
  72. "Syntax error",
  73. /* WI_ERROR_SETTINGS_UNKNOWNSETTING */
  74. "Unknown setting name",
  75. /* WI_ERROR_SETTINGS_NOSUCHUSER */
  76. "User not found",
  77. /* WI_ERROR_SETTINGS_NOSUCHGROUP */
  78. "Group not found",
  79. /* WI_ERROR_SETTINGS_INVALIDPORT */
  80. "Port is not in 1-65535 range",
  81. /* WI_ERROR_SETTINGS_NOSUCHSERVICE */
  82. "Service not found",
  83. /* WI_ERROR_SOCKET_NOVALIDCIPHER */
  84. "No valid cipher",
  85. /* WI_ERROR_SOCKET_NOSSL */
  86. "Socket has no SSL support",
  87. /* WI_ERROR_SOCKET_EOF */
  88. "End of file",
  89. /* WI_ERROR_TERMCAP_NOSUCHENTRY */
  90. "No such entry in termcap database",
  91. /* WI_ERROR_TERMCAP_TERMINFONOTFOUND */
  92. "Termcap databse not found",
  93. /* WI_ERROR_THREADS_NOTSUPP */
  94. "Threads are not supported in this build",
  95. };
  96. static wi_runtime_id_t _wi_error_runtime_id = WI_RUNTIME_ID_NULL;
  97. static wi_runtime_class_t _wi_error_runtime_class = {
  98. "wi_error_t",
  99. _wi_error_dealloc,
  100. NULL,
  101. NULL,
  102. NULL,
  103. NULL
  104. };
  105. void wi_error_register(void) {
  106. _wi_error_runtime_id = wi_runtime_register_class(&_wi_error_runtime_class);
  107. }
  108. void wi_error_initialize(void) {
  109. #ifdef WI_SSL
  110. SSL_load_error_strings();
  111. #endif
  112. }
  113. #pragma mark -
  114. static wi_error_t * _wi_error_alloc(void) {
  115. return wi_runtime_create_instance(_wi_error_runtime_id, sizeof(wi_error_t));
  116. }
  117. static wi_error_t * _wi_error_init(wi_error_t *error) {
  118. return error;
  119. }
  120. static void _wi_error_dealloc(wi_runtime_instance_t *instance) {
  121. wi_error_t *error = instance;
  122. wi_release(error->string);
  123. }
  124. #pragma mark -
  125. wi_error_t * _wi_get_error(void) {
  126. return wi_hash_data_for_key(wi_thread_hash(), WI_STR(_WI_ERROR_THREAD_KEY));
  127. }
  128. #pragma mark -
  129. void wi_error_enter_thread(void) {
  130. wi_error_t *error;
  131. error = _wi_error_init(_wi_error_alloc());
  132. wi_hash_set_data_for_key(wi_thread_hash(), error, WI_STR(_WI_ERROR_THREAD_KEY));
  133. wi_release(error);
  134. wi_error_set_error(WI_ERROR_DOMAIN_NONE, WI_ERROR_NONE);
  135. }
  136. void wi_error_set_error(wi_error_domain_t domain, int code) {
  137. wi_error_t *error;
  138. error = _wi_get_error();
  139. _WI_ERROR_ASSERT(error);
  140. error->domain = domain;
  141. error->code = code;
  142. wi_release(error->string);
  143. error->string = NULL;
  144. }
  145. void wi_error_set_errno(int code) {
  146. wi_error_set_error(WI_ERROR_DOMAIN_ERRNO, code);
  147. }
  148. void wi_error_set_ssl_error(void) {
  149. #ifdef WI_SSL
  150. if(ERR_peek_error() != 0)
  151. wi_error_set_error(WI_ERROR_DOMAIN_SSL, ERR_get_error());
  152. else
  153. wi_error_set_error(WI_ERROR_DOMAIN_ERRNO, errno);
  154. #endif
  155. }
  156. void wi_error_set_regex_error(regex_t *regex, int code) {
  157. wi_error_t *error;
  158. char string[256];
  159. error = _wi_get_error();
  160. _WI_ERROR_ASSERT(error);
  161. error->domain = WI_ERROR_DOMAIN_REGEX;
  162. error->code = code;
  163. wi_release(error->string);
  164. regerror(code, regex, string, sizeof(string));
  165. error->string = wi_string_init_with_cstring(wi_string_alloc(), string);
  166. }
  167. void wi_error_set_lib_error(int code) {
  168. wi_error_set_error(WI_ERROR_DOMAIN_LIB, code);
  169. }
  170. #pragma mark -
  171. wi_string_t * wi_error_string(void) {
  172. wi_error_t *error;
  173. error = _wi_get_error();
  174. _WI_ERROR_ASSERT(error);
  175. if(!error->string) {
  176. switch(error->domain) {
  177. case WI_ERROR_DOMAIN_ERRNO:
  178. error->string = wi_string_init_with_cstring(wi_string_alloc(), strerror(error->code));
  179. break;
  180. case WI_ERROR_DOMAIN_GAI:
  181. error->string = wi_string_init_with_cstring(wi_string_alloc(), gai_strerror(error->code));
  182. break;
  183. case WI_ERROR_DOMAIN_REGEX:
  184. break;
  185. case WI_ERROR_DOMAIN_SSL:
  186. #ifdef WI_SSL
  187. error->string = wi_string_init_with_cstring(wi_string_alloc(), ERR_reason_error_string(error->code));
  188. #endif
  189. break;
  190. case WI_ERROR_DOMAIN_NONE:
  191. case WI_ERROR_DOMAIN_LIB:
  192. error->string = wi_string_init_with_cstring(wi_string_alloc(), _wi_error_strings[error->code]);
  193. break;
  194. }
  195. }
  196. return error->string;
  197. }
  198. wi_error_domain_t wi_error_domain(void) {
  199. wi_error_t *error;
  200. error = _wi_get_error();
  201. _WI_ERROR_ASSERT(error);
  202. return error->domain;
  203. }
  204. int32_t wi_error_code(void) {
  205. wi_error_t *error;
  206. error = _wi_get_error();
  207. _WI_ERROR_ASSERT(error);
  208. return error->code;
  209. }