Added guac_error_message. Added error messages to all functions.
This commit is contained in:
parent
2d02a0f3bd
commit
f935075aec
@ -116,4 +116,17 @@ const char* guac_status_string(guac_status status);
|
||||
|
||||
guac_status* __guac_error();
|
||||
|
||||
/**
|
||||
* Returns a message describing the error which occurred during the last
|
||||
* function call. If an error occurred, but no message is associated with it,
|
||||
* NULL is returned. This value is undefined if no error occurred.
|
||||
*
|
||||
* The storage of this value is thread-local. Assignment of a message to
|
||||
* guac_error_message in one thread will not affect its value in another
|
||||
* thread.
|
||||
*/
|
||||
#define guac_error_message (*__guac_error_message())
|
||||
|
||||
const char** __guac_error_message();
|
||||
|
||||
#endif
|
||||
|
@ -135,6 +135,7 @@ guac_client_plugin* guac_client_plugin_open(const char* protocol) {
|
||||
client_plugin_handle = dlopen(protocol_lib, RTLD_LAZY);
|
||||
if (!client_plugin_handle) {
|
||||
guac_error = GUAC_STATUS_BAD_ARGUMENT;
|
||||
guac_error_message = "Client plugin not found";
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@ -146,6 +147,7 @@ guac_client_plugin* guac_client_plugin_open(const char* protocol) {
|
||||
/* Fail if cannot find guac_client_init */
|
||||
if (dlerror() != NULL) {
|
||||
guac_error = GUAC_STATUS_BAD_ARGUMENT;
|
||||
guac_error_message = dlerror();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@ -155,6 +157,7 @@ guac_client_plugin* guac_client_plugin_open(const char* protocol) {
|
||||
/* Fail if cannot find GUAC_CLIENT_ARGS */
|
||||
if (dlerror() != NULL) {
|
||||
guac_error = GUAC_STATUS_BAD_ARGUMENT;
|
||||
guac_error_message = dlerror();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@ -162,6 +165,7 @@ guac_client_plugin* guac_client_plugin_open(const char* protocol) {
|
||||
plugin = malloc(sizeof(guac_client_plugin));
|
||||
if (plugin == NULL) {
|
||||
guac_error = GUAC_STATUS_NO_MEMORY;
|
||||
guac_error_message = "Could not allocate memory for client plugin";
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@ -178,6 +182,7 @@ int guac_client_plugin_close(guac_client_plugin* plugin) {
|
||||
/* Unload client plugin */
|
||||
if (dlclose(plugin->__client_plugin_handle)) {
|
||||
guac_error = GUAC_STATUS_BAD_STATE;
|
||||
guac_error_message = dlerror();
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -192,6 +197,7 @@ guac_client* guac_client_plugin_get_client(guac_client_plugin* plugin,
|
||||
guac_client* client = malloc(sizeof(guac_client));
|
||||
if (client == NULL) {
|
||||
guac_error = GUAC_STATUS_NO_MEMORY;
|
||||
guac_error_message = "Could not allocate memory for client";
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
@ -107,17 +107,27 @@ const char* guac_status_string(guac_status status) {
|
||||
static pthread_key_t __guac_error_key;
|
||||
static pthread_once_t __guac_error_key_init = PTHREAD_ONCE_INIT;
|
||||
|
||||
static void __guac_free_error(void* status) {
|
||||
static pthread_key_t __guac_error_message_key;
|
||||
static pthread_once_t __guac_error_message_key_init = PTHREAD_ONCE_INIT;
|
||||
|
||||
static void __guac_free_pointer(void* pointer) {
|
||||
|
||||
/* Free memory allocated to status variable */
|
||||
free(status);
|
||||
free(pointer);
|
||||
|
||||
}
|
||||
|
||||
static void __guac_alloc_error_key() {
|
||||
|
||||
/* Create key, destroy any allocated variable on thread exit */
|
||||
pthread_key_create(&__guac_error_key, __guac_free_error);
|
||||
pthread_key_create(&__guac_error_key, __guac_free_pointer);
|
||||
|
||||
}
|
||||
|
||||
static void __guac_alloc_error_message_key() {
|
||||
|
||||
/* Create key, destroy any allocated variable on thread exit */
|
||||
pthread_key_create(&__guac_error_message_key, __guac_free_pointer);
|
||||
|
||||
}
|
||||
|
||||
@ -142,15 +152,44 @@ guac_status* __guac_error() {
|
||||
|
||||
}
|
||||
|
||||
const char** __guac_error_message() {
|
||||
|
||||
/* Pointer for thread-local data */
|
||||
const char** message;
|
||||
|
||||
/* Init error message key, if not already initialized */
|
||||
pthread_once(
|
||||
&__guac_error_message_key_init,
|
||||
__guac_alloc_error_message_key
|
||||
);
|
||||
|
||||
/* Retrieve thread-local message variable */
|
||||
message = (const char**) pthread_getspecific(__guac_error_message_key);
|
||||
|
||||
/* Allocate thread-local message variable if not already allocated */
|
||||
if (message == NULL) {
|
||||
message = malloc(sizeof(const char*));
|
||||
pthread_setspecific(__guac_error_message_key, message);
|
||||
}
|
||||
|
||||
return message;
|
||||
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
/* Default (not-threadsafe) implementation */
|
||||
static guac_status __guac_error_unsafe_storage;
|
||||
static const char** __guac_error_message_unsafe_storage;
|
||||
|
||||
guac_status* __guac_error() {
|
||||
return &__guac_error_unsafe_storage;
|
||||
}
|
||||
|
||||
const char** __guac_error_message() {
|
||||
return &__guac_error_message_unsafe_storage;
|
||||
}
|
||||
|
||||
/* Warn about threadsafety */
|
||||
#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.
|
||||
|
||||
|
@ -414,6 +414,7 @@ guac_instruction* guac_protocol_read_instruction(guac_socket* socket, int usec_t
|
||||
parsed_instruction = malloc(sizeof(guac_instruction));
|
||||
if (parsed_instruction == NULL) {
|
||||
guac_error = GUAC_STATUS_NO_MEMORY;
|
||||
guac_error_message = "Could not allocate memory for parsed instruction";
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@ -424,6 +425,7 @@ guac_instruction* guac_protocol_read_instruction(guac_socket* socket, int usec_t
|
||||
/* Fail if memory could not be alloc'd for argv */
|
||||
if (parsed_instruction->argv == NULL) {
|
||||
guac_error = GUAC_STATUS_NO_MEMORY;
|
||||
guac_error_message = "Could not allocate memory for arguments of parsed instruction";
|
||||
free(parsed_instruction);
|
||||
return NULL;
|
||||
}
|
||||
@ -434,6 +436,7 @@ guac_instruction* guac_protocol_read_instruction(guac_socket* socket, int usec_t
|
||||
/* Fail if memory could not be alloc'd for opcode */
|
||||
if (parsed_instruction->opcode == NULL) {
|
||||
guac_error = GUAC_STATUS_NO_MEMORY;
|
||||
guac_error_message = "Could not allocate memory for opcode of parsed instruction";
|
||||
free(parsed_instruction->argv);
|
||||
free(parsed_instruction);
|
||||
return NULL;
|
||||
@ -447,6 +450,7 @@ guac_instruction* guac_protocol_read_instruction(guac_socket* socket, int usec_t
|
||||
/* Free memory and fail if out of mem */
|
||||
if (parsed_instruction->argv[j] == NULL) {
|
||||
guac_error = GUAC_STATUS_NO_MEMORY;
|
||||
guac_error_message = "Could not allocate memory for single argument of parsed instruction";
|
||||
|
||||
/* Free all alloc'd argv values */
|
||||
while (--j >= 0)
|
||||
@ -474,6 +478,7 @@ guac_instruction* guac_protocol_read_instruction(guac_socket* socket, int usec_t
|
||||
/* Error if expected comma is not present */
|
||||
else if (terminator != ',') {
|
||||
guac_error = GUAC_STATUS_BAD_ARGUMENT;
|
||||
guac_error_message = "Element terminator of instructioni was not ';' nor ','";
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@ -488,6 +493,7 @@ guac_instruction* guac_protocol_read_instruction(guac_socket* socket, int usec_t
|
||||
/* Error if length is non-numeric or does not end in a period */
|
||||
else {
|
||||
guac_error = GUAC_STATUS_BAD_ARGUMENT;
|
||||
guac_error_message = "Non-numeric character in element length";
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@ -508,6 +514,7 @@ guac_instruction* guac_protocol_read_instruction(guac_socket* socket, int usec_t
|
||||
/* EOF */
|
||||
if (retval == 0) {
|
||||
guac_error = GUAC_STATUS_NO_INPUT;
|
||||
guac_error_message = "End of stream reached while reading instruction";
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@ -532,6 +539,7 @@ guac_instruction* guac_protocol_expect_instruction(guac_socket* socket, int usec
|
||||
/* Validate instruction */
|
||||
if (strcmp(instruction->opcode, opcode) != 0) {
|
||||
guac_error = GUAC_STATUS_BAD_STATE;
|
||||
guac_error_message = "Instruction read did not have expected opcode";
|
||||
guac_instruction_free(instruction);
|
||||
return NULL;
|
||||
}
|
||||
|
@ -69,6 +69,7 @@ guac_socket* guac_socket_open(int fd) {
|
||||
/* If no memory available, return with error */
|
||||
if (socket == NULL) {
|
||||
guac_error = GUAC_STATUS_NO_MEMORY;
|
||||
guac_error_message = "Could not allocate memory for socket";
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@ -83,6 +84,7 @@ guac_socket* guac_socket_open(int fd) {
|
||||
/* If no memory available, return with error */
|
||||
if (socket->__instructionbuf == NULL) {
|
||||
guac_error = GUAC_STATUS_NO_MEMORY;
|
||||
guac_error_message = "Could not allocate memory for instruction buffer";
|
||||
free(socket);
|
||||
return NULL;
|
||||
}
|
||||
@ -116,8 +118,10 @@ ssize_t __guac_socket_write(guac_socket* socket, const char* buf, int count) {
|
||||
#endif
|
||||
|
||||
/* Record errors in guac_error */
|
||||
if (retval < 0)
|
||||
if (retval < 0) {
|
||||
guac_error = GUAC_STATUS_SEE_ERRNO;
|
||||
guac_error_message = "Error writing data to socket";
|
||||
}
|
||||
|
||||
return retval;
|
||||
}
|
||||
@ -299,8 +303,15 @@ int guac_socket_select(guac_socket* socket, int usec_timeout) {
|
||||
}
|
||||
|
||||
/* Properly set guac_error */
|
||||
if (retval < 0) guac_error = GUAC_STATUS_SEE_ERRNO;
|
||||
if (retval == 0) guac_error = GUAC_STATUS_INPUT_TIMEOUT;
|
||||
if (retval < 0) {
|
||||
guac_error = GUAC_STATUS_SEE_ERRNO;
|
||||
guac_error_message = "Error while waiting for data on socket";
|
||||
}
|
||||
|
||||
if (retval == 0) {
|
||||
guac_error = GUAC_STATUS_INPUT_TIMEOUT;
|
||||
guac_error_message = "Timeout while waiting for data on socket";
|
||||
}
|
||||
|
||||
return retval;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user