Add FileMoveChunked(); which can read and write with offsets.
authorWilfried Goesgens <dothebart@citadel.org>
Wed, 13 Jun 2012 22:51:21 +0000 (00:51 +0200)
committerWilfried Goesgens <dothebart@citadel.org>
Wed, 13 Jun 2012 22:51:21 +0000 (00:51 +0200)
libcitadel/lib/libcitadel.h
libcitadel/lib/stringbuf.c

index 4258341c1eb6be25eb5b12de742549a2997549ce..f718536bc8063eef564825085cd253c732edcfc8 100644 (file)
@@ -258,6 +258,7 @@ typedef struct __fd_iobuffer {
        int PipeSize;
        long TotalSendSize;
        long TotalSentAlready;
+       long TotalReadAlready;
        long ChunkSize;
        long ChunkSendRemain;
        StrBuf *ChunkBuffer; /* just used if we don't have sendfile */
@@ -268,6 +269,7 @@ void FDIOBufferInit(FDIOBuffer *FDB, IOBuffer *IO, int FD, long TotalSendSize);
 void FDIOBufferDelete(FDIOBuffer *FDB);
 int FileSendChunked(FDIOBuffer *FDB, const char **Err);
 int FileRecvChunked(FDIOBuffer *FDB, const char **Err);
+int FileMoveChunked(FDIOBuffer *FDB, const char **Err);
 eReadState WriteIOBAlreadyRead(FDIOBuffer *FDB, const char **Error);
 
 long StrBuf_read_one_chunk_callback (int fd, short event, IOBuffer *FB);
index e1df8f4655ee9ea312fc5097b5c06d4271d1721a..3e81aac65efa992a96496250c6668201e848e391 100644 (file)
@@ -4041,6 +4041,75 @@ int FileRecvChunked(FDIOBuffer *FDB, const char **Err)
        return 0;
 }
 
+int FileMoveChunked(FDIOBuffer *FDB, const char **Err)
+{
+       ssize_t sent, pipesize;
+
+#ifdef LINUX_SPLICE
+       if (FDB->PipeSize == 0)
+       {
+               pipesize = splice(FDB->IOB->fd,
+                                 &FDB->TotalReadAlready, 
+                                 FDB->SplicePipe[1],
+                                 NULL, 
+                                 FDB->ChunkSendRemain, 
+                                 SPLICE_F_MORE | SPLICE_F_MOVE|SPLICE_F_NONBLOCK);
+
+               if (pipesize == -1)
+               {
+                       *Err = strerror(errno);
+                       return pipesize;
+               }
+               FDB->PipeSize = pipesize;
+       }
+       
+       sent = splice(FDB->SplicePipe[0],
+                     NULL, 
+                     FDB->OtherFD,
+                     &FDB->TotalSentAlready, 
+                     FDB->PipeSize,
+                     SPLICE_F_MORE | SPLICE_F_MOVE);
+
+       if (sent == -1)
+       {
+               *Err = strerror(errno);
+               return sent;
+       }
+       FDB->PipeSize -= sent;
+       FDB->ChunkSendRemain -= sent;
+       return sent;
+#else
+       
+       sent = read(FDB->IOB->fd, FDB->ChunkBuffer->buf, FDB->ChunkSendRemain);
+       if (sent > 0) {
+               int nWritten = 0;
+               int rc; 
+               
+               FDB->ChunkBuffer->BufUsed = sent;
+
+               while (nWritten < FDB->ChunkBuffer->BufUsed) {
+                       rc =  write(FDB->OtherFD, FDB->ChunkBuffer->buf + nWritten, FDB->ChunkBuffer->BufUsed - nWritten);
+                       if (rc < 0) {
+                               *Err = strerror(errno);
+                               return rc;
+                       }
+                       nWritten += rc;
+
+               }
+               FDB->ChunkBuffer->BufUsed = 0;
+               FDB->TotalSentAlready += sent;
+               FDB->ChunkSendRemain -= sent;
+               return FDB->ChunkSendRemain;
+       }
+       else if (sent < 0) {
+               *Err = strerror(errno);
+               return sent;
+       }
+
+#endif
+       return 0;
+}
+
 eReadState WriteIOBAlreadyRead(FDIOBuffer *FDB, const char **Error)
 {
        int IsNonBlock;