blob: ebf71b4c7c5d656865e11c4134a656f56a704bfc (
plain) (
tree)
|
|
/* See LICENSE file for copyright and license details. */
#include "internal.h"
#define STRDUP(S) ((S) ? strdup(S) : NULL)
struct liberror_error *
liberror_copy_error(struct liberror_error *src)
{
struct liberror_error *dest;
int saved_errno;
if (!src)
return NULL;
saved_errno = errno;
dest = malloc(sizeof(*dest));
if (dest) {
memcpy(dest, src, sizeof(*src));
if (dest->backtrace)
dest->backtrace->refcount += 1;
dest->dynamically_allocated = 1;
if (src->cause) {
dest->cause = liberror_copy_error(src->cause);
if (!dest->cause) {
if (dest->backtrace)
dest->backtrace->refcount -= 1;
free(dest);
dest = NULL;
}
}
switch (dest->details_type) {
case LIBERROR_DETAILS_USER:
dest->details.user.data = dest->details.user.copy_data(dest->details.user.data);
if (!dest->details.user.data)
goto fail;
break;
case LIBERROR_DETAILS_ONE_FILE:
dest->details.one_file.name = STRDUP(src->details.one_file.name);
if (src->details.one_file.name && !dest->details.one_file.name)
goto fail;
break;
case LIBERROR_DETAILS_TWO_FILES:
dest->details.two_files.name1 = STRDUP(src->details.two_files.name1);
dest->details.two_files.name2 = STRDUP(src->details.two_files.name2);
if (src->details.two_files.name1 && !dest->details.two_files.name1)
goto fail;
if (src->details.two_files.name2 && !dest->details.two_files.name2)
goto fail;
break;
case LIBERROR_DETAILS_NONE:
default:
break;
}
}
errno = saved_errno;
return dest;
fail:
liberror_free_error(dest);
errno = saved_errno;
return NULL;
}
|