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 <ni...@tsipinakis.com>
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

Reply via email to