summaryrefslogtreecommitdiff
path: root/util.c
diff options
context:
space:
mode:
authorPaul Eggert <eggert@cs.ucla.edu>2013-02-25 11:24:14 -0800
committerPaul Eggert <eggert@cs.ucla.edu>2013-02-25 11:25:55 -0800
commit6ea2e1bf864059de97981ab34e7f2331b5aad218 (patch)
treec5a9b08825b05dbb1c2be07d3d8ace5be0220b77 /util.c
parente40a9b65ae95ed6face7ce1336905f0ab0a4992b (diff)
downloadgzip-6ea2e1bf864059de97981ab34e7f2331b5aad218.tar.gz
gzip: port to DMF file systems
* util.c (read_buffer): When reading a file with O_NONBLOCK, if the read fails with errno==EAGAIN, clear O_NONBLOCK and try again. Problem reported by Vitezslav Cizek in <http://lists.gnu.org/archive/html/bug-gzip/2013-02/msg00030.html>.
Diffstat (limited to 'util.c')
-rw-r--r--util.c23
1 files changed, 21 insertions, 2 deletions
diff --git a/util.c b/util.c
index cfd4e6c..c4c7f70 100644
--- a/util.c
+++ b/util.c
@@ -132,16 +132,35 @@ int fill_inbuf(eof_ok)
}
/* Like the standard read function, except do not attempt to read more
- than SSIZE_MAX bytes at a time. */
+ than INT_MAX bytes at a time. */
int
read_buffer (fd, buf, cnt)
int fd;
voidp buf;
unsigned int cnt;
{
+ int len;
if (INT_MAX < cnt)
cnt = INT_MAX;
- return read (fd, buf, cnt);
+ len = read (fd, buf, cnt);
+
+#if defined F_SETFL && O_NONBLOCK && defined EAGAIN
+ /* Input files are opened O_NONBLOCK for security reasons. On some
+ file systems this can cause read to fail with errno == EAGAIN. */
+ if (len < 0 && errno == EAGAIN)
+ {
+ int flags = fcntl (fd, F_GETFL);
+ if (0 <= flags)
+ {
+ if (! (flags & O_NONBLOCK))
+ errno = EAGAIN;
+ else if (fcntl (fd, F_SETFL, flags & ~O_NONBLOCK) != -1)
+ len = read (fd, buf, cnt);
+ }
+ }
+#endif
+
+ return len;
}
/* Likewise for 'write'. */