diff options
author | Jeremy Allison <jra@samba.org> | 2011-12-30 20:45:10 -0800 |
---|---|---|
committer | Jeremy Allison <jra@samba.org> | 2011-12-30 20:45:10 -0800 |
commit | 5e6263960aaf1a5f9993cb7bb5646d36ff92b9cc (patch) | |
tree | 1cb1ca464ce0b656769855bf51f13f2443e31551 /source3 | |
parent | a5715420e37b98038fe8f2c3028e4c6938400eed (diff) | |
download | samba-5e6263960aaf1a5f9993cb7bb5646d36ff92b9cc.tar.gz samba-5e6263960aaf1a5f9993cb7bb5646d36ff92b9cc.tar.bz2 samba-5e6263960aaf1a5f9993cb7bb5646d36ff92b9cc.zip |
Third part of fix for bug #8679 - recvfile code path using splice() on Linux leaves data in the pipe on short write.
Fix default_sys_recvfile() to correctly cope with
short writes. Return the amount written. Return
-1 and set errno if no data could be written.
Diffstat (limited to 'source3')
-rw-r--r-- | source3/lib/recvfile.c | 39 |
1 files changed, 18 insertions, 21 deletions
diff --git a/source3/lib/recvfile.c b/source3/lib/recvfile.c index 31d9311498..c74cdd5a67 100644 --- a/source3/lib/recvfile.c +++ b/source3/lib/recvfile.c @@ -30,16 +30,10 @@ * It's safe to make direct syscalls to lseek/write here * as we're below the Samba vfs layer. * - * If tofd is -1 we just drain the incoming socket of count - * bytes without writing to the outgoing fd. - * If a write fails we do the same (to cope with disk full) - * errors. - * * Returns -1 on short reads from fromfd (read error) * and sets errno. * * Returns number of bytes written to 'tofd' - * or thrown away if 'tofd == -1'. * return != count then sets errno. * Returns count if complete success. */ @@ -96,23 +90,26 @@ static ssize_t default_sys_recvfile(int fromfd, num_written = 0; - while (num_written < read_ret) { + /* Don't write any more after a write error. */ + while (tofd != -1 && (num_written < read_ret)) { ssize_t write_ret; - if (tofd == -1) { - write_ret = read_ret; - } else { - /* Write to file - ignore EINTR. */ - write_ret = sys_write(tofd, - buffer + num_written, - read_ret - num_written); - - if (write_ret <= 0) { - /* write error - stop writing. */ - tofd = -1; - saved_errno = errno; - continue; - } + /* Write to file - ignore EINTR. */ + write_ret = sys_write(tofd, + buffer + num_written, + read_ret - num_written); + + if (write_ret <= 0) { + /* write error - stop writing. */ + tofd = -1; + if (total_written == 0) { + /* Ensure we return + -1 if the first + write failed. */ + total_written = -1; + } + saved_errno = errno; + break; } num_written += (size_t)write_ret; |