Signed-off-by: Michal Privoznik <mprivozn@xxxxxxxxxx> --- src/fdstream.c | 35 +++++++++++++++++++++++++++++++---- 1 file changed, 31 insertions(+), 4 deletions(-) diff --git a/src/fdstream.c b/src/fdstream.c index a85cf9d..403ddf6 100644 --- a/src/fdstream.c +++ b/src/fdstream.c @@ -353,10 +353,14 @@ virFDStreamAbort(virStreamPtr st) return virFDStreamCloseInt(st, true); } -static int virFDStreamWrite(virStreamPtr st, const char *bytes, size_t nbytes) +static int +virFDStreamWriteInternal(virStreamPtr st, + off_t offset, + const char *bytes, + size_t nbytes) { struct virFDStreamData *fdst = st->privateData; - int ret; + int ret = -1; if (nbytes > INT_MAX) { virReportSystemError(ERANGE, "%s", @@ -376,14 +380,20 @@ static int virFDStreamWrite(virStreamPtr st, const char *bytes, size_t nbytes) if (fdst->length == fdst->offset) { virReportSystemError(ENOSPC, "%s", _("cannot write to stream")); - virMutexUnlock(&fdst->lock); - return -1; + goto cleanup; } if ((fdst->length - fdst->offset) < nbytes) nbytes = fdst->length - fdst->offset; } + if (offset != (off_t) -1 && + lseek(fdst->fd, offset, SEEK_SET) < 0) { + virReportSystemError(errno, "%s", + _("unable to set stream position")); + goto cleanup; + } + retry: ret = write(fdst->fd, bytes, nbytes); if (ret < 0) { @@ -395,15 +405,31 @@ static int virFDStreamWrite(virStreamPtr st, const char *bytes, size_t nbytes) ret = -1; virReportSystemError(errno, "%s", _("cannot write to stream")); + goto cleanup; } } else if (fdst->length) { fdst->offset += ret; } + cleanup: virMutexUnlock(&fdst->lock); return ret; } +static int +virFDStreamWrite(virStreamPtr st, const char *bytes, size_t nbytes) +{ + return virFDStreamWriteInternal(st, (off_t) -1, bytes, nbytes); +} + +static int +virFDStreamWriteOffset(virStreamPtr st, + unsigned long long offset, + const char *bytes, + size_t nbytes) +{ + return virFDStreamWriteInternal(st, offset, bytes, nbytes); +} static int virFDStreamRead(virStreamPtr st, char *bytes, size_t nbytes) { @@ -457,6 +483,7 @@ static int virFDStreamRead(virStreamPtr st, char *bytes, size_t nbytes) static virStreamDriver virFDStreamDrv = { .streamSend = virFDStreamWrite, + .streamSendOffset = virFDStreamWriteOffset, .streamRecv = virFDStreamRead, .streamFinish = virFDStreamClose, .streamAbort = virFDStreamAbort, -- 2.4.10 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list