This is the mail archive of the elfutils-devel@sourceware.org mailing list for the elfutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [PATCH] Handle partial read or write.


Hi Adam,

Thanks for finding this. I made the GNU format style changes suggested
by Roland, but did not change anything else. Does this look OK to you?

Thanks,

Mark
From 02d7f56c7d27a3a6db98c128ad9829ffe2a27413 Mon Sep 17 00:00:00 2001
From: Adam Markey <adam@etinternational.com>
Date: Tue, 9 Oct 2012 11:05:53 +0200
Subject: [PATCH] Handle partial read or write.

Ran into a situation where pread was returning less data than requested for
remote files on a networked filesystem. This patch modifies the IO wrappers
to request the remaining data as long as no real errors occured.

Signed-off-by: Adam Markey <adam@etinternational.com>
Signed-off-by: Mark Wielaard <mjw@redhat.com>
---
 lib/ChangeLog |  5 +++++
 lib/system.h  | 59 +++++++++++++++++++++++++++++++++++++++++++++++++++++------
 2 files changed, 58 insertions(+), 6 deletions(-)

diff --git a/lib/ChangeLog b/lib/ChangeLog
index 46eeeca..525528a 100644
--- a/lib/ChangeLog
+++ b/lib/ChangeLog
@@ -1,3 +1,8 @@
+2012-10-09  Adam Markey  <adam@etinternational.com>
+
+	* system.h: Changed pwrite_retry, write_retry, and pread_retry to
+	handle case where not all data was read/written.
+
 2012-10-08  Jan Kratochvil  <jan.kratochvil@redhat.com>
 
 	* system.h (eu_static_assert): New macro.
diff --git a/lib/system.h b/lib/system.h
index d9adee9..182b7be 100644
--- a/lib/system.h
+++ b/lib/system.h
@@ -34,6 +34,7 @@
 #include <stdint.h>
 #include <endian.h>
 #include <byteswap.h>
+#include <unistd.h>
 
 #if __BYTE_ORDER == __LITTLE_ENDIAN
 # define LE32(n)	(n)
@@ -64,12 +65,58 @@ extern int crc32_file (int fd, uint32_t *resp);
 #define gettext_noop(Str) Str
 
 
-#define pwrite_retry(fd, buf,  len, off) \
-  TEMP_FAILURE_RETRY (pwrite (fd, buf, len, off))
-#define write_retry(fd, buf, n) \
-     TEMP_FAILURE_RETRY (write (fd, buf, n))
-#define pread_retry(fd, buf,  len, off) \
-  TEMP_FAILURE_RETRY (pread (fd, buf, len, off))
+static inline ssize_t __attribute__ ((unused))
+pwrite_retry (int fd, const void *buf, size_t len, off_t off)
+{
+  ssize_t ret;
+  ssize_t recvd = 0;
+
+  do
+    {
+      ret = TEMP_FAILURE_RETRY (pwrite (fd, buf + recvd, len - recvd,
+					off + recvd));
+      if (ret > 0)
+	recvd += ret;
+    }
+  while (ret > 0 && (size_t) recvd < len);
+
+  return ret < 0 ? ret : recvd;
+}
+
+static inline ssize_t __attribute__ ((unused))
+write_retry (int fd, const void *buf, size_t len)
+{
+  ssize_t ret;
+  ssize_t recvd = 0;
+
+  do
+    {
+      ret = TEMP_FAILURE_RETRY (write (fd, buf + recvd, len - recvd));
+      if (ret > 0)
+	recvd += ret;
+    }
+  while (ret > 0 && (size_t)recvd < len);
+
+  return ret < 0 ? ret : recvd;
+}
+
+static inline ssize_t __attribute__ ((unused))
+pread_retry (int fd, void *buf, size_t len, off_t off)
+{
+  ssize_t ret;
+  ssize_t recvd = 0;
+
+  do
+    {
+      ret = TEMP_FAILURE_RETRY (pread (fd, buf + recvd, len - recvd,
+				       off + recvd));
+      if (ret > 0)
+	recvd += ret;
+    }
+  while (ret > 0 && (size_t) recvd < len);
+
+  return ret < 0 ? ret : recvd;
+}
 
 
 /* We need define two variables, argp_program_version_hook and
-- 
1.7.11.4


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]