[libvirt] [PATCH RFC 4/8] fdstream: Implement virStreamSendOffset

Michal Privoznik mprivozn at redhat.com
Fri Jan 29 13:26:55 UTC 2016


Signed-off-by: Michal Privoznik <mprivozn at redhat.com>
---
 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




More information about the libvir-list mailing list