/* See LICENSE file for copyright and license details. */ #include "internal.h" void liberror_set_error(const char description[256], const char source[64], const char code_group[64], long long int code) { struct liberror_error *cause = NULL, *old; struct liberror_error *error; int have_cause = 0, saved_errno; const char *errstr; old = liberror_get_error(); if (old) { have_cause = 1; saved_errno = errno; cause = malloc(sizeof(*cause)); errno = saved_errno; if (cause) memcpy(cause, old, sizeof(*cause)); } error = &liberror_error_; liberror_have_error_ = 1; memset(error, 0, sizeof(*error)); if (*description) { stpcpy(error->description, description); } else if (!strcmp(code_group, "errno")) { if (code >= (long long int)INT_MIN && code <= (long long int)INT_MAX) strerror_r((int)code, error->description, sizeof(error->description)); } else if (!strcmp(code_group, "h_errno")) { if (code >= (long long int)INT_MIN && code <= (long long int)INT_MAX) { saved_errno = errno; errstr = hstrerror(code); if (errstr) strncpy(error->description, errstr, sizeof(error->description)); errno = saved_errno; } } else if (!strcmp(code_group, "addrinfo")) { if (code == (long long int)EAI_SYSTEM) { strerror_r(errno, error->description, sizeof(error->description)); } else if (code >= (long long int)INT_MIN && code <= (long long int)INT_MAX) { saved_errno = errno; errstr = gai_strerror(code); if (errstr) strncpy(error->description, errstr, sizeof(error->description)); errno = saved_errno; } } stpcpy(error->source, source); stpcpy(error->code_group, code_group); error->code = code; if (liberror_saved_backtrace) { error->backtrace = liberror_saved_backtrace; liberror_saved_backtrace = NULL; } else { liberror_save_backtrace(error); } error->cause = cause; error->failed_to_allocate_cause = have_cause && !cause; }