A small correction that I noticed a bit too late to fix in the previous
message: We
should also reset errno at the beginning of the call to ensure it's actually an
error.
>From 2aaeac922507d24820e38a4b6959cfa38d9da0c3 Mon Sep 17 00:00:00 2001
From: Nikos Tsipinakis <[email protected]>
Date: Sat, 26 Sep 2020 16:41:54 +0300
Subject: [PATCH] Use full_read to avoid errors due to short reads
In networked filesystems such as 9p, read() can return short reads even
for regular files.
---
gnulib.modules | 1 +
src/common.h | 1 +
src/misc.c | 10 ++++++++--
3 files changed, 10 insertions(+), 2 deletions(-)
diff --git a/gnulib.modules b/gnulib.modules
index 82f5e1c..9ded7da 100644
--- a/gnulib.modules
+++ b/gnulib.modules
@@ -44,6 +44,7 @@ fprintftime
fseeko
fstatat
full-write
+full-read
futimens
getline
getopt-gnu
diff --git a/src/common.h b/src/common.h
index a451999..7f696c5 100644
--- a/src/common.h
+++ b/src/common.h
@@ -57,6 +57,7 @@
#include "arith.h"
#include <backupfile.h>
#include <exclude.h>
+#include <full-read.h>
#include <full-write.h>
#include <modechange.h>
#include <quote.h>
diff --git a/src/misc.c b/src/misc.c
index d833b8d..10074a2 100644
--- a/src/misc.c
+++ b/src/misc.c
@@ -804,7 +804,9 @@ deref_stat (char const *name, struct stat *buf)
size_t
blocking_read (int fd, void *buf, size_t count)
{
- size_t bytes = safe_read (fd, buf, count);
+ errno = 0;
+
+ size_t bytes = full_read (fd, buf, count);
#if defined F_SETFL && O_NONBLOCK
if (bytes == SAFE_READ_ERROR && errno == EAGAIN)
@@ -812,10 +814,14 @@ blocking_read (int fd, void *buf, size_t count)
int flags = fcntl (fd, F_GETFL);
if (0 <= flags && flags & O_NONBLOCK
&& fcntl (fd, F_SETFL, flags & ~O_NONBLOCK) != -1)
- bytes = safe_read (fd, buf, count);
+ bytes = full_read (fd, buf, count);
}
#endif
+ if (bytes < count && errno != 0) {
+ return SAFE_READ_ERROR;
+ }
+
return bytes;
}
--
2.28.0