提交 5b16a499 编写于 作者: M Michal Privoznik

virStream*All: Report error if a callback fails

All of these four functions (virStreamRecvAll, virStreamSendAll,
virStreamSparseRecvAll, virStreamSparseSendAll) take one or more
callback functions that handle various aspects of streams.
However, if any of them fails no error is reported therefore
caller does not know what went wrong.

At the same time, we silently presumed callbacks to set errno on
failure. With this change we should document it explicitly as the
error is not properly reported.
Signed-off-by: NMichal Privoznik <mprivozn@redhat.com>
Reviewed-by: NJohn Ferlan <jferlan@redhat.com>
上级 5b62dacb
...@@ -82,7 +82,10 @@ int virStreamRecvHole(virStreamPtr, ...@@ -82,7 +82,10 @@ int virStreamRecvHole(virStreamPtr,
* of bytes. The callback will continue to be * of bytes. The callback will continue to be
* invoked until it indicates the end of the source * invoked until it indicates the end of the source
* has been reached by returning 0. A return value * has been reached by returning 0. A return value
* of -1 at any time will abort the send operation * of -1 at any time will abort the send operation.
*
* Please note that for more accurate error reporting the
* callback should set appropriate errno on failure.
* *
* Returns the number of bytes filled, 0 upon end * Returns the number of bytes filled, 0 upon end
* of file, or -1 upon error * of file, or -1 upon error
...@@ -119,6 +122,9 @@ int virStreamSendAll(virStreamPtr st, ...@@ -119,6 +122,9 @@ int virStreamSendAll(virStreamPtr st,
* This function should not adjust the current position within * This function should not adjust the current position within
* the file. * the file.
* *
* Please note that for more accurate error reporting the
* callback should set appropriate errno on failure.
*
* Returns 0 on success, * Returns 0 on success,
* -1 upon error * -1 upon error
*/ */
...@@ -142,6 +148,9 @@ typedef int (*virStreamSourceHoleFunc)(virStreamPtr st, ...@@ -142,6 +148,9 @@ typedef int (*virStreamSourceHoleFunc)(virStreamPtr st,
* processing the hole in the stream source and then return. * processing the hole in the stream source and then return.
* A return value of -1 at any time will abort the send operation. * A return value of -1 at any time will abort the send operation.
* *
* Please note that for more accurate error reporting the
* callback should set appropriate errno on failure.
*
* Returns 0 on success, * Returns 0 on success,
* -1 upon error. * -1 upon error.
*/ */
...@@ -176,6 +185,9 @@ int virStreamSparseSendAll(virStreamPtr st, ...@@ -176,6 +185,9 @@ int virStreamSparseSendAll(virStreamPtr st,
* has been reached. A return value of -1 at any time * has been reached. A return value of -1 at any time
* will abort the receive operation * will abort the receive operation
* *
* Please note that for more accurate error reporting the
* callback should set appropriate errno on failure.
*
* Returns the number of bytes consumed or -1 upon * Returns the number of bytes consumed or -1 upon
* error * error
*/ */
...@@ -203,6 +215,9 @@ int virStreamRecvAll(virStreamPtr st, ...@@ -203,6 +215,9 @@ int virStreamRecvAll(virStreamPtr st,
* hole in the stream target and then return. A return value of * hole in the stream target and then return. A return value of
* -1 at any time will abort the receive operation. * -1 at any time will abort the receive operation.
* *
* Please note that for more accurate error reporting the
* callback should set appropriate errno on failure.
*
* Returns 0 on success, * Returns 0 on success,
* -1 upon error * -1 upon error
*/ */
......
...@@ -569,7 +569,7 @@ virStreamInData(virStreamPtr stream, ...@@ -569,7 +569,7 @@ virStreamInData(virStreamPtr stream,
* *
* Returns -1 upon any error, with virStreamAbort() already * Returns -1 upon any error, with virStreamAbort() already
* having been called, so the caller need only call * having been called, so the caller need only call
* virStreamFree() * virStreamFree().
*/ */
int int
virStreamSendAll(virStreamPtr stream, virStreamSendAll(virStreamPtr stream,
...@@ -595,11 +595,17 @@ virStreamSendAll(virStreamPtr stream, ...@@ -595,11 +595,17 @@ virStreamSendAll(virStreamPtr stream,
if (VIR_ALLOC_N(bytes, want) < 0) if (VIR_ALLOC_N(bytes, want) < 0)
goto cleanup; goto cleanup;
errno = 0;
for (;;) { for (;;) {
int got, offset = 0; int got, offset = 0;
got = (handler)(stream, bytes, want, opaque); got = (handler)(stream, bytes, want, opaque);
if (got < 0) if (got < 0) {
if (errno == 0)
errno = EIO;
virReportSystemError(errno, "%s", _("send handler failed"));
goto cleanup; goto cleanup;
}
if (got == 0) if (got == 0)
break; break;
while (offset < got) { while (offset < got) {
...@@ -728,6 +734,7 @@ int virStreamSparseSendAll(virStreamPtr stream, ...@@ -728,6 +734,7 @@ int virStreamSparseSendAll(virStreamPtr stream,
if (VIR_ALLOC_N(bytes, bufLen) < 0) if (VIR_ALLOC_N(bytes, bufLen) < 0)
goto cleanup; goto cleanup;
errno = 0;
for (;;) { for (;;) {
int inData, got, offset = 0; int inData, got, offset = 0;
long long sectionLen; long long sectionLen;
...@@ -735,16 +742,22 @@ int virStreamSparseSendAll(virStreamPtr stream, ...@@ -735,16 +742,22 @@ int virStreamSparseSendAll(virStreamPtr stream,
const unsigned int skipFlags = 0; const unsigned int skipFlags = 0;
if (!dataLen) { if (!dataLen) {
if (holeHandler(stream, &inData, &sectionLen, opaque) < 0) if (holeHandler(stream, &inData, &sectionLen, opaque) < 0) {
if (errno == 0)
errno = EIO;
virReportSystemError(errno, "%s", _("send holeHandler failed"));
goto cleanup; goto cleanup;
}
if (!inData && sectionLen) { if (!inData && sectionLen) {
if (virStreamSendHole(stream, sectionLen, skipFlags) < 0) if (virStreamSendHole(stream, sectionLen, skipFlags) < 0)
goto cleanup; goto cleanup;
if (skipHandler(stream, sectionLen, opaque) < 0) { if (skipHandler(stream, sectionLen, opaque) < 0) {
if (errno == 0)
errno = EIO;
virReportSystemError(errno, "%s", virReportSystemError(errno, "%s",
_("unable to skip hole")); _("send skipHandler failed"));
goto cleanup; goto cleanup;
} }
continue; continue;
...@@ -757,8 +770,13 @@ int virStreamSparseSendAll(virStreamPtr stream, ...@@ -757,8 +770,13 @@ int virStreamSparseSendAll(virStreamPtr stream,
want = dataLen; want = dataLen;
got = (handler)(stream, bytes, want, opaque); got = (handler)(stream, bytes, want, opaque);
if (got < 0) if (got < 0) {
if (errno == 0)
errno = EIO;
virReportSystemError(errno, "%s",
_("send handler failed"));
goto cleanup; goto cleanup;
}
if (got == 0) if (got == 0)
break; break;
while (offset < got) { while (offset < got) {
...@@ -854,8 +872,10 @@ virStreamRecvAll(virStreamPtr stream, ...@@ -854,8 +872,10 @@ virStreamRecvAll(virStreamPtr stream,
if (VIR_ALLOC_N(bytes, want) < 0) if (VIR_ALLOC_N(bytes, want) < 0)
goto cleanup; goto cleanup;
errno = 0;
for (;;) { for (;;) {
int got, offset = 0; int got, offset = 0;
got = virStreamRecv(stream, bytes, want); got = virStreamRecv(stream, bytes, want);
if (got < 0) if (got < 0)
goto cleanup; goto cleanup;
...@@ -864,8 +884,13 @@ virStreamRecvAll(virStreamPtr stream, ...@@ -864,8 +884,13 @@ virStreamRecvAll(virStreamPtr stream,
while (offset < got) { while (offset < got) {
int done; int done;
done = (handler)(stream, bytes + offset, got - offset, opaque); done = (handler)(stream, bytes + offset, got - offset, opaque);
if (done < 0) if (done < 0) {
if (errno == 0)
errno = EIO;
virReportSystemError(errno, "%s",
_("recv handler failed"));
goto cleanup; goto cleanup;
}
offset += done; offset += done;
} }
} }
...@@ -968,6 +993,7 @@ virStreamSparseRecvAll(virStreamPtr stream, ...@@ -968,6 +993,7 @@ virStreamSparseRecvAll(virStreamPtr stream,
if (VIR_ALLOC_N(bytes, want) < 0) if (VIR_ALLOC_N(bytes, want) < 0)
goto cleanup; goto cleanup;
errno = 0;
for (;;) { for (;;) {
int got, offset = 0; int got, offset = 0;
long long holeLen; long long holeLen;
...@@ -978,8 +1004,12 @@ virStreamSparseRecvAll(virStreamPtr stream, ...@@ -978,8 +1004,12 @@ virStreamSparseRecvAll(virStreamPtr stream,
if (virStreamRecvHole(stream, &holeLen, holeFlags) < 0) if (virStreamRecvHole(stream, &holeLen, holeFlags) < 0)
goto cleanup; goto cleanup;
if (holeHandler(stream, holeLen, opaque) < 0) if (holeHandler(stream, holeLen, opaque) < 0) {
if (errno == 0)
errno = EIO;
virReportSystemError(errno, "%s", _("recv holeHandler failed"));
goto cleanup; goto cleanup;
}
continue; continue;
} else if (got < 0) { } else if (got < 0) {
goto cleanup; goto cleanup;
...@@ -989,8 +1019,12 @@ virStreamSparseRecvAll(virStreamPtr stream, ...@@ -989,8 +1019,12 @@ virStreamSparseRecvAll(virStreamPtr stream,
while (offset < got) { while (offset < got) {
int done; int done;
done = (handler)(stream, bytes + offset, got - offset, opaque); done = (handler)(stream, bytes + offset, got - offset, opaque);
if (done < 0) if (done < 0) {
if (errno == 0)
errno = EIO;
virReportSystemError(errno, "%s", _("recv handler failed"));
goto cleanup; goto cleanup;
}
offset += done; offset += done;
} }
} }
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册