changeset 133:788d8536ee18 HEAD

s/io_buffer_send_buf/io_buffer_send_iobuffer/, also we set buf_errno when send or receiving fails, which can be checked later.
author Timo Sirainen <tss@iki.fi>
date Tue, 03 Sep 2002 23:28:09 +0300
parents 4dc5d31e2282
children 2ec94f1bf60b
files src/lib/iobuffer.c src/lib/iobuffer.h
diffstat 2 files changed, 25 insertions(+), 6 deletions(-) [+]
line wrap: on
line diff
--- a/src/lib/iobuffer.c	Tue Sep 03 23:26:07 2002 +0300
+++ b/src/lib/iobuffer.c	Tue Sep 03 23:28:09 2002 +0300
@@ -227,6 +227,7 @@
 
 	if (ret < 0) {
 		buf->closed = TRUE;
+		buf->buf_errno = errno;
 	} else {
 		buf->offset += ret;
 		buf->skip += ret;
@@ -287,6 +288,7 @@
 
 		if (ret < 0) {
 			ctx->outbuf->closed = TRUE;
+			ctx->outbuf->buf_errno = errno;
 		} else {
 			ctx->outbuf->offset += ret;
 			ctx->data += ret;
@@ -430,6 +432,7 @@
 			if (ret < 0) {
 				/* disconnected */
 				buf->closed = TRUE;
+				buf->buf_errno = errno;
 				return -1;
 			}
 
@@ -457,6 +460,8 @@
 		}
 	}
 
+	i_assert(buf->pos + size <= buf->buffer_size);
+
 	/* add to buffer */
 	memcpy(buf->buffer + buf->pos, data, size);
 	buf->pos += size;
@@ -470,17 +475,20 @@
 
 static void block_loop_sendfile(IOBufferBlockContext *ctx)
 {
+	uoff_t offset;
 	int ret;
 
 	i_assert(ctx->inbuf->offset < OFF_T_MAX);
 
+	offset = ctx->inbuf->offset;
 	ret = safe_sendfile(ctx->outbuf->fd, ctx->inbuf->fd,
-			    &ctx->inbuf->offset, ctx->size);
+			    &offset, ctx->size);
 	if (ret < 0) {
 		if (errno != EINTR && errno != EAGAIN)
 			ctx->outbuf->closed = TRUE;
 		ret = 0;
 	}
+	io_buffer_skip(ctx->inbuf, (unsigned int)ret);
 
 	ctx->size -= ret;
 	if (ctx->outbuf->closed || ctx->size == 0)
@@ -491,6 +499,7 @@
 			      unsigned int size)
 {
         IOBufferBlockContext ctx;
+	uoff_t offset;
 	int ret;
 
 	i_assert(inbuf->offset < OFF_T_MAX);
@@ -498,12 +507,14 @@
 	io_buffer_send_flush(outbuf);
 
 	/* first try if we can do it with a single sendfile() call */
-	ret = safe_sendfile(outbuf->fd, inbuf->fd, &inbuf->offset, size);
+	offset = inbuf->offset;
+	ret = safe_sendfile(outbuf->fd, inbuf->fd, &offset, size);
 	if (ret < 0) {
 		if (errno != EINTR && errno != EAGAIN)
 			return -1;
 		ret = 0;
 	}
+	io_buffer_skip(inbuf, (unsigned int)ret);
 
 	if ((unsigned int) ret == size) {
 		/* yes, all sent */
@@ -547,7 +558,8 @@
 	io_buffer_skip(ctx->inbuf, size - ctx->size);
 }
 
-int io_buffer_send_buf(IOBuffer *outbuf, IOBuffer *inbuf, unsigned int size)
+int io_buffer_send_iobuffer(IOBuffer *outbuf, IOBuffer *inbuf,
+			    unsigned int size)
 {
 	IOBufferBlockContext ctx;
 	unsigned char *in_data;
@@ -571,8 +583,10 @@
 	ret = !outbuf->file ?
 		net_transmit(outbuf->fd, in_data, in_size) :
 		my_write(outbuf->fd, in_data, in_size);
-	if (ret < 0)
+	if (ret < 0) {
+		outbuf->buf_errno = errno;
 		return -1;
+	}
 
 	outbuf->offset += ret;
 	io_buffer_skip(inbuf, (unsigned int)ret);
@@ -647,6 +661,7 @@
 	buf->buffer = mmap(NULL, buf->buffer_size, PROT_READ, MAP_PRIVATE,
 			   buf->fd, buf->mmap_offset);
 	if (buf->buffer == MAP_FAILED) {
+		buf->buf_errno = errno;
 		i_error("io_buffer_read_mmaped(): mmap() failed: %m");
 		return -1;
 	}
@@ -703,6 +718,7 @@
 
 	if (ret < 0) {
 		/* disconnected */
+		buf->buf_errno = errno;
                 return -1;
 	}
 
@@ -892,7 +908,8 @@
 			net_transmit(buf->fd, buf->buffer, size);
 		if (ret < 0) {
 			/* disconnected */
-                        buf->closed = TRUE;
+			buf->closed = TRUE;
+			buf->buf_errno = errno;
 			return -1;
 		}
 
--- a/src/lib/iobuffer.h	Tue Sep 03 23:26:07 2002 +0300
+++ b/src/lib/iobuffer.h	Tue Sep 03 23:28:09 2002 +0300
@@ -12,6 +12,7 @@
 
 	uoff_t start_offset;
 	uoff_t offset, size; /* virtual offset, 0 = start_offset */
+	int buf_errno; /* set when write() or read() failed. */
 
 /* private: */
 	Pool pool;
@@ -86,7 +87,8 @@
 /* Send data from input buffer to output buffer using the fastest
    possible method. Returns 1 if all was ok, -1 if disconnected.
    Note that this function may block. */
-int io_buffer_send_buf(IOBuffer *outbuf, IOBuffer *inbuf, unsigned int size);
+int io_buffer_send_iobuffer(IOBuffer *outbuf, IOBuffer *inbuf,
+			    unsigned int size);
 /* Flush the output buffer, blocks until all is sent. If
    io_buffer_set_send_blocking() is called, it's timeout settings are used. */
 void io_buffer_send_flush(IOBuffer *buf);