diff options
Diffstat (limited to 'source3/lib/recvfile.c')
-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; |