diff options
author | Jeremy Allison <jra@samba.org> | 2011-12-30 20:23:00 -0800 |
---|---|---|
committer | Jeremy Allison <jra@samba.org> | 2011-12-30 20:23:00 -0800 |
commit | a5715420e37b98038fe8f2c3028e4c6938400eed (patch) | |
tree | 2f06da33a5bc0a9293d97a05e61bd9c6dc55ab32 | |
parent | a108eb4fdb565cc6580a15f3d9221f8b9f863fe6 (diff) | |
download | samba-a5715420e37b98038fe8f2c3028e4c6938400eed.tar.gz samba-a5715420e37b98038fe8f2c3028e4c6938400eed.tar.bz2 samba-a5715420e37b98038fe8f2c3028e4c6938400eed.zip |
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().
-rw-r--r-- | source3/lib/recvfile.c | 31 |
1 files changed, 30 insertions, 1 deletions
diff --git a/source3/lib/recvfile.c b/source3/lib/recvfile.c index 5d1c0b2c55..31d9311498 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; } |