From 1b46db7b24a4f064706c2c7e712452135a3fed34 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Mon, 8 Apr 2013 10:16:48 -0700 Subject: [PATCH] Ensure drain_socket() operates on a blocking socket. Signed-off-by: Jeremy Allison Reviewed-by: Stefan (metze) Metzmacher --- source3/lib/recvfile.c | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/source3/lib/recvfile.c b/source3/lib/recvfile.c index c53ba77e5c4..72f4257fc5c 100644 --- a/source3/lib/recvfile.c +++ b/source3/lib/recvfile.c @@ -240,6 +240,7 @@ ssize_t sys_recvfile(int fromfd, /***************************************************************** Throw away "count" bytes from the client socket. Returns count or -1 on error. + Must only operate on a blocking socket. *****************************************************************/ ssize_t drain_socket(int sockfd, size_t count) @@ -247,6 +248,7 @@ ssize_t drain_socket(int sockfd, size_t count) size_t total = 0; size_t bufsize = MIN(TRANSFER_BUF_SIZE,count); char *buffer = NULL; + int old_flags = 0; if (count == 0) { return 0; @@ -257,6 +259,12 @@ ssize_t drain_socket(int sockfd, size_t count) return -1; } + old_flags = fcntl(sockfd, F_GETFL, 0); + if (set_blocking(sockfd, true) == -1) { + free(buffer); + return -1; + } + while (total < count) { ssize_t read_ret; size_t toread = MIN(bufsize,count - total); @@ -265,12 +273,17 @@ ssize_t drain_socket(int sockfd, size_t count) read_ret = sys_read(sockfd, buffer, toread); if (read_ret <= 0) { /* EOF or socket error. */ - free(buffer); - return -1; + count = (size_t)-1; + goto out; } total += read_ret; } + out: + free(buffer); + if (fcntl(sockfd, F_SETFL, old_flags) == -1) { + return -1; + } return count; } -- 2.34.1