summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJeremy Allison <jra@samba.org>2013-04-08 10:16:48 -0700
committerKarolin Seeger <kseeger@samba.org>2013-04-25 12:50:59 +0200
commit160a9f3b5ab5ca4e040bbffc172bfcc6b07c556f (patch)
treef3d1a1af5dd8901e550e054bd257e91265eb8890
parent1758eaa1c3d41199077b410691e556ef4f512d34 (diff)
downloadsamba-160a9f3b5ab5ca4e040bbffc172bfcc6b07c556f.tar.gz
Ensure drain_socket() operates on a blocking socket.
Signed-off-by: Jeremy Allison <jra@samba.org> Reviewed-by: Stefan (metze) Metzmacher <metze@samba.org> (cherry picked from commit 1b46db7b24a4f064706c2c7e712452135a3fed34)
-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 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;
}