From a5715420e37b98038fe8f2c3028e4c6938400eed Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 30 Dec 2011 20:23:00 -0800 Subject: [PATCH] Second part of fix for bug #8679 - recvfile code path using splice() on Linux leaves data in the pipe on short write. Split out the functionality of drain_socket() into a separate function from default_sys_recvfile(). --- source3/lib/recvfile.c | 31 ++++++++++++++++++++++++++++++- 1 file changed, 30 insertions(+), 1 deletion(-) diff --git a/source3/lib/recvfile.c b/source3/lib/recvfile.c index 5d1c0b2c55f..31d9311498d 100644 --- a/source3/lib/recvfile.c +++ b/source3/lib/recvfile.c @@ -242,9 +242,38 @@ ssize_t sys_recvfile(int fromfd, /***************************************************************** Throw away "count" bytes from the client socket. + Returns count or -1 on error. *****************************************************************/ ssize_t drain_socket(int sockfd, size_t count) { - return default_sys_recvfile(sockfd, -1, (SMB_OFF_T)-1, count); + size_t total = 0; + size_t bufsize = MIN(TRANSFER_BUF_SIZE,count); + char *buffer = NULL; + + if (count == 0) { + return 0; + } + + buffer = SMB_MALLOC_ARRAY(char, bufsize); + if (buffer == NULL) { + return -1; + } + + while (total < count) { + ssize_t read_ret; + size_t toread = MIN(bufsize,count - total); + + /* Read from socket - ignore EINTR. */ + read_ret = sys_read(sockfd, buffer, toread); + if (read_ret <= 0) { + /* EOF or socket error. */ + free(buffer); + return -1; + } + total += read_ret; + } + + free(buffer); + return count; } -- 2.34.1