mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2025-01-11 09:17:52 +03:00
error: preserve errno when saving last error
It is common to see the sequence: virErrorPtr save_err = virSaveLastError(); // do cleanup virSetError(save_err); virFreeError(save_err); on cleanup paths. But for functions where it is desirable to return the errno that caused failure, this sequence can clobber that errno. virFreeError was already safe; this makes the other two functions in the sequence safe as well, assuming all goes well (on OOM, errno will be clobbered, but then again, save_err won't reflect the real error that happened, so you are no longer preserving the real situation - that's life with OOM). * src/util/virterror.c (virSaveLastError, virSetError): Preserve errno.
This commit is contained in:
parent
1468359f16
commit
979b784be2
@ -295,18 +295,24 @@ virGetLastError(void)
|
|||||||
* Can be used to re-set an old error, which may have been squashed by
|
* Can be used to re-set an old error, which may have been squashed by
|
||||||
* other functions (like cleanup routines).
|
* other functions (like cleanup routines).
|
||||||
*
|
*
|
||||||
* Returns 0 on success, 1 on failure
|
* Returns 0 on success, -1 on failure. Leaves errno unchanged.
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
virSetError(virErrorPtr newerr)
|
virSetError(virErrorPtr newerr)
|
||||||
{
|
{
|
||||||
virErrorPtr err;
|
virErrorPtr err;
|
||||||
|
int saved_errno = errno;
|
||||||
|
int ret = -1;
|
||||||
|
|
||||||
err = virLastErrorObject();
|
err = virLastErrorObject();
|
||||||
if (!err)
|
if (!err)
|
||||||
return -1;
|
goto cleanup;
|
||||||
|
|
||||||
virResetError(err);
|
virResetError(err);
|
||||||
return virCopyError(newerr, err);
|
ret = virCopyError(newerr, err);
|
||||||
|
cleanup:
|
||||||
|
errno = saved_errno;
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -339,7 +345,8 @@ virCopyLastError(virErrorPtr to)
|
|||||||
/**
|
/**
|
||||||
* virSaveLastError:
|
* virSaveLastError:
|
||||||
*
|
*
|
||||||
* Save the last error into a new error object.
|
* Save the last error into a new error object. On success, errno is
|
||||||
|
* unchanged; on failure, errno is ENOMEM.
|
||||||
*
|
*
|
||||||
* Returns a pointer to the copied error or NULL if allocation failed.
|
* Returns a pointer to the copied error or NULL if allocation failed.
|
||||||
* It is the caller's responsibility to free the error with
|
* It is the caller's responsibility to free the error with
|
||||||
@ -349,11 +356,13 @@ virErrorPtr
|
|||||||
virSaveLastError(void)
|
virSaveLastError(void)
|
||||||
{
|
{
|
||||||
virErrorPtr to;
|
virErrorPtr to;
|
||||||
|
int saved_errno = errno;
|
||||||
|
|
||||||
if (VIR_ALLOC(to) < 0)
|
if (VIR_ALLOC(to) < 0)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
virCopyLastError(to);
|
virCopyLastError(to);
|
||||||
|
errno = saved_errno;
|
||||||
return to;
|
return to;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user