/error.c

https://code.google.com/p/pytsk/ · C · 142 lines · 87 code · 36 blank · 19 comment · 13 complexity · c437ac8f491e0746f4e77ca38f07d642 MD5 · raw file

  1. /*
  2. ** error.c
  3. **
  4. ** Made by (mic)
  5. ** Login <mic@laptop>
  6. **
  7. ** Started on Mon Mar 15 20:45:09 2010 mic
  8. ** Last update Sun May 12 01:17:25 2002 Speed Blue
  9. */
  10. //#include "misc.h"
  11. #include "class.h"
  12. #include <string.h>
  13. #include "aff4_errors.h"
  14. #define ERROR_BUFF_SIZE 10240
  15. // Windows version not truely threadsafe for now
  16. #ifdef WIN32
  17. static char global_error_buffer[ERROR_BUFF_SIZE];
  18. static int global_error_type = 0;
  19. static void error_init(void) {
  20. memset(global_error_buffer, 0, sizeof(global_error_buffer));
  21. };
  22. DLL_PUBLIC void *aff4_raise_errors(int t, char *reason, ...) {
  23. char *tmp;
  24. // This has to succeed:
  25. int *type = aff4_get_current_error(&tmp);
  26. memset(tmp, 0, ERROR_BUFF_SIZE);
  27. if(reason) {
  28. va_list ap;
  29. va_start(ap, reason);
  30. vsnprintf(tmp, ERROR_BUFF_SIZE-1, reason,ap);
  31. tmp[ERROR_BUFF_SIZE-1]=0;
  32. va_end(ap);
  33. };
  34. if(*type == EZero) {
  35. *tmp = 0;
  36. //update the error type
  37. *type = t;
  38. };
  39. return NULL;
  40. };
  41. DLL_PUBLIC int *aff4_get_current_error(char **error_buffer) {
  42. if(error_buffer) {
  43. *error_buffer = &global_error_buffer;
  44. };
  45. return &global_error_type;
  46. };
  47. #else
  48. #include <pthread.h>
  49. /** These slots carry the TLS error keys */
  50. static pthread_key_t error_str_slot;
  51. static pthread_once_t error_once = PTHREAD_ONCE_INIT;
  52. static pthread_key_t error_value_slot;
  53. static void error_init(void);
  54. void error_dest(void *slot) {
  55. if(slot) talloc_free(slot);
  56. };
  57. DLL_PUBLIC void *aff4_raise_errors(int t, char *reason, ...) {
  58. char *error_buffer;
  59. char tmp[ERROR_BUFF_SIZE];
  60. // This has to succeed:
  61. int *type = aff4_get_current_error(&error_buffer);
  62. if(reason) {
  63. va_list ap;
  64. va_start(ap, reason);
  65. vsnprintf(tmp, ERROR_BUFF_SIZE-1, reason,ap);
  66. tmp[ERROR_BUFF_SIZE-1]=0;
  67. va_end(ap);
  68. };
  69. if(*type == EZero) {
  70. *error_buffer = 0;
  71. //update the error type
  72. *type = t;
  73. } else {
  74. strncat(error_buffer, "\n", ERROR_BUFF_SIZE -1 );
  75. };
  76. strncat(error_buffer, tmp, ERROR_BUFF_SIZE-1);
  77. return NULL;
  78. };
  79. DLL_PUBLIC int *aff4_get_current_error(char **error_buffer) {
  80. int *type;
  81. (void) pthread_once(&error_once, error_init);
  82. type = pthread_getspecific(error_value_slot);
  83. // This is optional
  84. if(error_buffer) {
  85. *error_buffer = pthread_getspecific(error_str_slot);
  86. // If TLS buffers are not set we need to create them
  87. if(!*error_buffer) {
  88. *error_buffer =talloc_size(NULL, ERROR_BUFF_SIZE);
  89. pthread_setspecific(error_str_slot, *error_buffer);
  90. };
  91. };
  92. if(!type) {
  93. type = talloc_size(NULL, ERROR_BUFF_SIZE);
  94. pthread_setspecific(error_value_slot, type);
  95. };
  96. return type;
  97. };
  98. void error_init(void) {
  99. // We create the error buffer slots
  100. if(pthread_key_create(&error_str_slot, error_dest) ||
  101. pthread_key_create(&error_value_slot, error_dest)) {
  102. printf("Unable to set up TLS variables\n");
  103. abort();
  104. };
  105. };
  106. #endif