From f8325703278692db49c867db9657b1aa14237257 Mon Sep 17 00:00:00 2001 From: Wilfried Goesgens Date: Thu, 14 Jun 2012 00:51:21 +0200 Subject: [PATCH] Add FileMoveChunked(); which can read and write with offsets. --- libcitadel/lib/libcitadel.h | 2 ++ libcitadel/lib/stringbuf.c | 69 +++++++++++++++++++++++++++++++++++++ 2 files changed, 71 insertions(+) diff --git a/libcitadel/lib/libcitadel.h b/libcitadel/lib/libcitadel.h index 4258341c1..f718536bc 100644 --- a/libcitadel/lib/libcitadel.h +++ b/libcitadel/lib/libcitadel.h @@ -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); diff --git a/libcitadel/lib/stringbuf.c b/libcitadel/lib/stringbuf.c index e1df8f465..3e81aac65 100644 --- a/libcitadel/lib/stringbuf.c +++ b/libcitadel/lib/stringbuf.c @@ -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; -- 2.30.2