#define ERR_CODE_LEN 512
-static canl_err_code resolve_error(glb_ctx *cc, unsigned long err_code,
+static canl_err_code resolve_error_code(glb_ctx *cc, unsigned long err_code,
canl_err_origin err_orig);
static void get_error_string(glb_ctx *cc, char *code_str);
+static canl_err_code update_error_msg(canl_ctx cc, const char *new_msg);
-/* TODO: produce error messages immediately (to chain them) */
/* Save error message into err_msg
* use NULL for empty err_format */
canl_err_code update_error (glb_ctx *cc, unsigned long err_code,
canl_err_origin err_orig,
const char *err_format, ...)
{
- unsigned int err_msg_len = 0;
- unsigned int err_msg_sum = 0; // sum of msg and format lengths
int err_format_len = 0;
- int separator_len = 0;
- const char *separator = "; ";
va_list ap;
char *new_msg = NULL;
- char *old_msg = NULL;
+ int ret = 0;
if (!cc)
return EINVAL;
if (err_format == NULL) {
return EINVAL;
}
- separator_len = strlen(separator);
va_start(ap, err_format);
-
- if (!(cc->err_msg)) {
- vasprintf(&cc->err_msg, err_format, ap);
+
+ /*TODO if vasprintf not successful?*/
+ err_format_len = vasprintf(&new_msg, err_format, ap);
+ if (!err_format_len) {
va_end(ap);
- return resolve_error(cc, err_code, err_orig);
+ return EINVAL;
}
- err_format_len = vasprintf(&new_msg, err_format, ap);
-
- err_msg_len = strlen(cc->err_msg);
- old_msg = cc->err_msg;
-
- /* Add new error message to the older one */
- err_msg_sum = err_format_len + err_msg_len + separator_len + 1;
- cc->err_msg = (char *) malloc ((err_msg_sum)*sizeof(char));
- if (cc->err_msg == NULL)
- return ENOMEM;
-
- strncpy(cc->err_msg, new_msg, err_format_len + 1);
- strncat (cc->err_msg, separator, separator_len + 1);
- strncat (cc->err_msg, old_msg, err_msg_len + 1);
+ ret = resolve_error_code(cc, err_code, err_orig);
+ update_error_msg(cc, new_msg);
free(new_msg);
- free(old_msg);
+ va_end(ap);
- return resolve_error(cc, err_code, err_orig);
+ return ret;
}
/* If there was some error message in ctx, delete it and make new */
canl_err_code set_error (glb_ctx *cc, unsigned long err_code,
- canl_err_origin err_orig,
- const char *err_format, ...)
+ canl_err_origin err_orig, const char *err_format, ...)
{
va_list ap;
- /*check cc*/
+ char *new_msg = NULL;
+ int ret;
+ int err_format_len = 0;
+
if (!cc)
return 1;
/* if message already exists, delete it */
/* make new message */
va_start(ap, err_format);
- vasprintf(&cc->err_msg, err_format, ap);
+ err_format_len = vasprintf(&new_msg, err_format, ap);
+ if (!err_format_len) {
+ va_end(ap);
+ return EINVAL;
+ }
+
+ ret = resolve_error_code(cc, err_code, err_orig);
+ update_error_msg(cc, new_msg);
+ free(new_msg);
va_end(ap);
- //0 is not error
if (!err_code)
- return 0;
- return resolve_error(cc, err_code, err_orig);
+ return 0;
+ return ret;
}
/* Delete error message in ctx, suppose msg is not empty.Set pointer to NULL*/
}
/* Provide human readable information about errors */
-canl_err_code
-canl_get_error(canl_ctx cc, char **reason)
+static canl_err_code
+update_error_msg(canl_ctx cc, const char *new_msg)
{
- int err = 0;
- int e_orig = UNKNOWN_ERROR;
int error_length = 0;
char *new_error = NULL;
char code_str[ERR_CODE_LEN];
int code_len = 0;
char *separ = ": ";
int separ_len = 0;
- int err_msg_len = 0;
+ int err_old_msg_len = 0;
+ int err_new_msg_len = 0;
glb_ctx *ctx = (glb_ctx*) cc;
code_str[0] = '\0';
return EINVAL;
}
- //TODO what to return
- if (!ctx->err_msg)
- goto end;
+ if (ctx->err_msg)
+ err_old_msg_len = strlen(ctx->err_msg);
+
+ if (new_msg)
+ err_new_msg_len = strlen(new_msg);
- /* get human readable error code*/
+ /* get human readable error code */
get_error_string(cc, code_str);
code_len = strlen(code_str);
- err_msg_len = strlen(ctx->err_msg);
-
separ_len = strlen(separ);
- error_length = err_msg_len + code_len + separ_len + 1;
+ error_length = err_new_msg_len + err_old_msg_len + code_len +
+ (2*separ_len) + 1;
new_error = (char *) malloc ((error_length) * sizeof (char));
if (!new_error) {
- err = ENOMEM;
- e_orig = POSIX_ERROR;
- goto end;
+ return set_error(ctx, ENOMEM, POSIX_ERROR, "cannot get error message");
}
-
- strncpy(new_error, ctx->err_msg, err_msg_len + 1);
+
+ new_error[0] = '\0';
+ strncpy(new_error, new_msg, err_new_msg_len + 1);
strncat(new_error, separ, separ_len + 1);
strncat(new_error, code_str, code_len + 1);
+ strncat(new_error, separ, separ_len + 1);
+ if (ctx->err_msg) {
+ strncat(new_error, ctx->err_msg, err_old_msg_len + 1);
+ }
-end:
- *reason = new_error;
- if (err)
- set_error(ctx, err, e_orig, "cannot get error message");
- return err;
+ if (ctx->err_msg)
+ free(ctx->err_msg);
+ ctx->err_msg = new_error;
+ return 0;
}
-/*TODO ! map error codes to their human readable strings */
static void get_error_string(glb_ctx *cc, char *code_str)
{
char *new_str = NULL;
ERR_CODE_LEN);
code_str[ERR_CODE_LEN - 1] = '\0';
}
+ break;
case NETDB_ERROR:
new_str = (char *) hstrerror(cc->err_code);
if (new_str) {
return ctx->err_code;
}
-/* TODO why canl_get_error, neuvolnila se pamet ctx->err_msg ???*/
char *
canl_get_error_message(canl_ctx cc)
{
glb_ctx *ctx = (glb_ctx*) cc;
- int ret;
- char *msg = NULL;
if (ctx == NULL)
- return "Context is not initialized";
-
- ret = canl_get_error(ctx, &msg);
- if (ret)
- return "No human-error available";
+ return "Context is not initialized";
- ctx->err_msg = msg;
return ctx->err_msg;
}
/*if the error code is known to canl, assign appropriate canl code
TODO go through ssl errors and assign appr. canl code
?preserve original one? */
-static canl_err_code resolve_error(glb_ctx *cc, unsigned long err_code,
+static canl_err_code resolve_error_code(glb_ctx *cc, unsigned long err_code,
canl_err_origin err_orig)
{
cc->original_err_code = err_code;