]> git.ipfire.org Git - thirdparty/elfutils.git/commitdiff
Handle partial read or write.
authorAdam Markey <adam@etinternational.com>
Tue, 9 Oct 2012 09:05:53 +0000 (11:05 +0200)
committerMark Wielaard <mjw@redhat.com>
Wed, 10 Oct 2012 08:56:42 +0000 (10:56 +0200)
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
lib/system.h

index 46eeeca05803a984bd14d02b02e2b96393b073b1..525528a63de6ac2dcec8fb0f6ac420223e61aa64 100644 (file)
@@ -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.
index d9adee9c27e4bd997046f0db44db951cf1212504..8367f2bc01cedbace8ebe36d58659b5ce24887ae 100644 (file)
@@ -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,61 @@ 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 recvd = 0;
+
+  do
+    {
+      ssize_t ret = TEMP_FAILURE_RETRY (pwrite (fd, buf + recvd, len - recvd,
+                                               off + recvd));
+      if (ret <= 0)
+       return ret < 0 ? ret : recvd;
+
+      recvd += ret;
+    }
+  while ((size_t) recvd < len);
+
+  return recvd;
+}
+
+static inline ssize_t __attribute__ ((unused))
+write_retry (int fd, const void *buf, size_t len)
+{
+  ssize_t recvd = 0;
+
+  do
+    {
+      ssize_t ret = TEMP_FAILURE_RETRY (write (fd, buf + recvd, len - recvd));
+      if (ret <= 0)
+       return ret < 0 ? ret : recvd;
+
+      recvd += ret;
+    }
+  while ((size_t) recvd < len);
+
+  return recvd;
+}
+
+static inline ssize_t __attribute__ ((unused))
+pread_retry (int fd, void *buf, size_t len, off_t off)
+{
+  ssize_t recvd = 0;
+
+  do
+    {
+      ssize_t ret = TEMP_FAILURE_RETRY (pread (fd, buf + recvd, len - recvd,
+                                              off + recvd));
+      if (ret <= 0)
+       return ret < 0 ? ret : recvd;
+
+      recvd += ret;
+    }
+  while ((size_t) recvd < len);
+
+  return recvd;
+}
 
 
 /* We need define two variables, argp_program_version_hook and