From: Jeremy Allison Date: Sat, 31 Dec 2011 04:23:00 +0000 (-0800) Subject: Second part of fix for bug #8679 - recvfile code path using splice() on Linux leaves... X-Git-Tag: tevent-0.9.15~571 X-Git-Url: http://git.samba.org/?p=ddiss%2Fsamba.git;a=commitdiff_plain;h=a5715420e37b98038fe8f2c3028e4c6938400eed 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(). --- 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; }