summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source3/lib/recvfile.c17
1 files changed, 15 insertions, 2 deletions
diff --git a/source3/lib/recvfile.c b/source3/lib/recvfile.c
index c53ba77e5c..72f4257fc5 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;
}