error.c (8398B)
1/* 2 * Licensed to the Apache Software Foundation (ASF) under one 3 * or more contributor license agreements. See the NOTICE file 4 * distributed with this work for additional information 5 * regarding copyright ownership. The ASF licenses this file 6 * to you under the Apache License, Version 2.0 (the 7 * "License"); you may not use this file except in compliance 8 * with the License. You may obtain a copy of the License at 9 * 10 * http://www.apache.org/licenses/LICENSE-2.0 11 * 12 * Unless required by applicable law or agreed to in writing, 13 * software distributed under the License is distributed on an 14 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 * KIND, either express or implied. See the License for the 16 * specific language governing permissions and limitations 17 * under the License. 18 */ 19 20#include "config.h" 21 22#include "guacamole/mem.h" 23#include "guacamole/error.h" 24 25#include <errno.h> 26#include <stdlib.h> 27#include <string.h> 28 29#ifdef HAVE_LIBPTHREAD 30#include <pthread.h> 31#endif 32 33/* 34 * Error strings 35 */ 36 37const char* __GUAC_STATUS_SUCCESS_STR = "Success"; 38const char* __GUAC_STATUS_NO_MEMORY_STR = "Insufficient memory"; 39const char* __GUAC_STATUS_CLOSED_STR = "Closed"; 40const char* __GUAC_STATUS_TIMEOUT_STR = "Timed out"; 41const char* __GUAC_STATUS_IO_ERROR_STR = "Input/output error"; 42const char* __GUAC_STATUS_INVALID_ARGUMENT_STR = "Invalid argument"; 43const char* __GUAC_STATUS_INTERNAL_ERROR_STR = "Internal error"; 44const char* __GUAC_STATUS_UNKNOWN_STATUS_STR = "UNKNOWN STATUS CODE"; 45const char* __GUAC_STATUS_NO_SPACE_STR = "Insufficient space"; 46const char* __GUAC_STATUS_INPUT_TOO_LARGE_STR = "Input too large"; 47const char* __GUAC_STATUS_RESULT_TOO_LARGE_STR = "Result too large"; 48const char* __GUAC_STATUS_PERMISSION_DENIED_STR = "Permission denied"; 49const char* __GUAC_STATUS_BUSY_STR = "Resource busy"; 50const char* __GUAC_STATUS_NOT_AVAILABLE_STR = "Resource not available"; 51const char* __GUAC_STATUS_NOT_SUPPORTED_STR = "Not supported"; 52const char* __GUAC_STATUS_NOT_INPLEMENTED_STR = "Not implemented"; 53const char* __GUAC_STATUS_TRY_AGAIN_STR = "Temporary failure"; 54const char* __GUAC_STATUS_PROTOCOL_ERROR_STR = "Protocol violation"; 55const char* __GUAC_STATUS_NOT_FOUND_STR = "Not found"; 56const char* __GUAC_STATUS_CANCELED_STR = "Canceled"; 57const char* __GUAC_STATUS_OUT_OF_RANGE_STR = "Value out of range"; 58const char* __GUAC_STATUS_REFUSED_STR = "Operation refused"; 59const char* __GUAC_STATUS_TOO_MANY_STR = "Insufficient resources"; 60const char* __GUAC_STATUS_WOULD_BLOCK_STR = "Operation would block"; 61 62const char* guac_status_string(guac_status status) { 63 64 switch (status) { 65 66 /* No error */ 67 case GUAC_STATUS_SUCCESS: 68 return __GUAC_STATUS_SUCCESS_STR; 69 70 /* Out of memory */ 71 case GUAC_STATUS_NO_MEMORY: 72 return __GUAC_STATUS_NO_MEMORY_STR; 73 74 /* End of stream */ 75 case GUAC_STATUS_CLOSED: 76 return __GUAC_STATUS_CLOSED_STR; 77 78 /* Timeout */ 79 case GUAC_STATUS_TIMEOUT: 80 return __GUAC_STATUS_TIMEOUT_STR; 81 82 /* Further information in errno */ 83 case GUAC_STATUS_SEE_ERRNO: 84 return strerror(errno); 85 86 /* Input/output error */ 87 case GUAC_STATUS_IO_ERROR: 88 return __GUAC_STATUS_IO_ERROR_STR; 89 90 /* Invalid argument */ 91 case GUAC_STATUS_INVALID_ARGUMENT: 92 return __GUAC_STATUS_INVALID_ARGUMENT_STR; 93 94 /* Internal error */ 95 case GUAC_STATUS_INTERNAL_ERROR: 96 return __GUAC_STATUS_INTERNAL_ERROR_STR; 97 98 /* Out of space */ 99 case GUAC_STATUS_NO_SPACE: 100 return __GUAC_STATUS_NO_SPACE_STR; 101 102 /* Input too large */ 103 case GUAC_STATUS_INPUT_TOO_LARGE: 104 return __GUAC_STATUS_INPUT_TOO_LARGE_STR; 105 106 /* Result too large */ 107 case GUAC_STATUS_RESULT_TOO_LARGE: 108 return __GUAC_STATUS_RESULT_TOO_LARGE_STR; 109 110 /* Permission denied */ 111 case GUAC_STATUS_PERMISSION_DENIED: 112 return __GUAC_STATUS_PERMISSION_DENIED_STR; 113 114 /* Resource is busy */ 115 case GUAC_STATUS_BUSY: 116 return __GUAC_STATUS_BUSY_STR; 117 118 /* Resource not available */ 119 case GUAC_STATUS_NOT_AVAILABLE: 120 return __GUAC_STATUS_NOT_AVAILABLE_STR; 121 122 /* Not supported */ 123 case GUAC_STATUS_NOT_SUPPORTED: 124 return __GUAC_STATUS_NOT_SUPPORTED_STR; 125 126 /* Not implemented */ 127 case GUAC_STATUS_NOT_INPLEMENTED: 128 return __GUAC_STATUS_NOT_INPLEMENTED_STR; 129 130 /* Temporary failure */ 131 case GUAC_STATUS_TRY_AGAIN: 132 return __GUAC_STATUS_TRY_AGAIN_STR; 133 134 /* Guacamole protocol error */ 135 case GUAC_STATUS_PROTOCOL_ERROR: 136 return __GUAC_STATUS_PROTOCOL_ERROR_STR; 137 138 /* Resource not found */ 139 case GUAC_STATUS_NOT_FOUND: 140 return __GUAC_STATUS_NOT_FOUND_STR; 141 142 /* Operation canceled */ 143 case GUAC_STATUS_CANCELED: 144 return __GUAC_STATUS_CANCELED_STR; 145 146 /* Value out of range */ 147 case GUAC_STATUS_OUT_OF_RANGE: 148 return __GUAC_STATUS_OUT_OF_RANGE_STR; 149 150 /* Operation refused */ 151 case GUAC_STATUS_REFUSED: 152 return __GUAC_STATUS_REFUSED_STR; 153 154 /* Too many resource in use */ 155 case GUAC_STATUS_TOO_MANY: 156 return __GUAC_STATUS_TOO_MANY_STR; 157 158 /* Operation would block */ 159 case GUAC_STATUS_WOULD_BLOCK: 160 return __GUAC_STATUS_WOULD_BLOCK_STR; 161 162 /* Unknown status code */ 163 default: 164 return __GUAC_STATUS_UNKNOWN_STATUS_STR; 165 166 } 167 168} 169 170#ifdef HAVE_LIBPTHREAD 171 172/* PThread implementation of __guac_error */ 173 174static pthread_key_t __guac_error_key; 175static pthread_once_t __guac_error_key_init = PTHREAD_ONCE_INIT; 176 177static pthread_key_t __guac_error_message_key; 178static pthread_once_t __guac_error_message_key_init = PTHREAD_ONCE_INIT; 179 180static void __guac_mem_free_pointer(void* pointer) { 181 182 /* Free memory allocated to status variable */ 183 guac_mem_free(pointer); 184 185} 186 187static void __guac_alloc_error_key() { 188 189 /* Create key, destroy any allocated variable on thread exit */ 190 pthread_key_create(&__guac_error_key, __guac_mem_free_pointer); 191 192} 193 194static void __guac_alloc_error_message_key() { 195 196 /* Create key, destroy any allocated variable on thread exit */ 197 pthread_key_create(&__guac_error_message_key, __guac_mem_free_pointer); 198 199} 200 201guac_status* __guac_error() { 202 203 /* Pointer for thread-local data */ 204 guac_status* status; 205 206 /* Init error key, if not already initialized */ 207 pthread_once(&__guac_error_key_init, __guac_alloc_error_key); 208 209 /* Retrieve thread-local status variable */ 210 status = (guac_status*) pthread_getspecific(__guac_error_key); 211 212 /* Allocate thread-local status variable if not already allocated */ 213 if (status == NULL) { 214 status = guac_mem_alloc(sizeof(guac_status)); 215 pthread_setspecific(__guac_error_key, status); 216 } 217 218 return status; 219 220} 221 222const char** __guac_error_message() { 223 224 /* Pointer for thread-local data */ 225 const char** message; 226 227 /* Init error message key, if not already initialized */ 228 pthread_once( 229 &__guac_error_message_key_init, 230 __guac_alloc_error_message_key 231 ); 232 233 /* Retrieve thread-local message variable */ 234 message = (const char**) pthread_getspecific(__guac_error_message_key); 235 236 /* Allocate thread-local message variable if not already allocated */ 237 if (message == NULL) { 238 message = guac_mem_alloc(sizeof(const char*)); 239 pthread_setspecific(__guac_error_message_key, message); 240 } 241 242 return message; 243 244} 245 246#else 247 248/* Default (not-threadsafe) implementation */ 249static guac_status __guac_error_unsafe_storage; 250static const char** __guac_error_message_unsafe_storage; 251 252guac_status* __guac_error() { 253 return &__guac_error_unsafe_storage; 254} 255 256const char** __guac_error_message() { 257 return &__guac_error_message_unsafe_storage; 258} 259 260/* Warn about threadsafety */ 261#warn No threadsafe implementation of __guac_error exists for your platform, so a default non-threadsafe implementation has been used instead. This may lead to incorrect status codes being reported for failures. Please consider adding support for your platform, or filing a bug report with the Guacamole project. 262 263#endif 264