提交 979b784b 编写于 作者: E Eric Blake

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.
上级 1468359f
......@@ -295,18 +295,24 @@ virGetLastError(void)
* Can be used to re-set an old error, which may have been squashed by
* other functions (like cleanup routines).
*
* Returns 0 on success, 1 on failure
* Returns 0 on success, -1 on failure. Leaves errno unchanged.
*/
int
virSetError(virErrorPtr newerr)
{
virErrorPtr err;
int saved_errno = errno;
int ret = -1;
err = virLastErrorObject();
if (!err)
return -1;
goto cleanup;
virResetError(err);
return virCopyError(newerr, err);
ret = virCopyError(newerr, err);
cleanup:
errno = saved_errno;
return ret;
}
/**
......@@ -339,7 +345,8 @@ virCopyLastError(virErrorPtr to)
/**
* 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.
* It is the caller's responsibility to free the error with
......@@ -349,11 +356,13 @@ virErrorPtr
virSaveLastError(void)
{
virErrorPtr to;
int saved_errno = errno;
if (VIR_ALLOC(to) < 0)
return NULL;
virCopyLastError(to);
errno = saved_errno;
return to;
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册