summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorPaul Eggert <eggert@cs.ucla.edu>2011-04-13 12:54:09 -0700
committerPaul Eggert <eggert@cs.ucla.edu>2011-04-13 12:54:09 -0700
commit1963a2e0bb07cc8dee6d27f972f93d9cfd7c6b2d (patch)
treec6760a6aef71252e16af9ad463f6126631d0dc39 /src
parent086e8c477d4342c8e718f9bb811da0b1a6e1e946 (diff)
* sysdep.c (MAX_RW_COUNT): New macro, to work around kernel bugs.
(emacs_read, emacs_write): Use it.
Diffstat (limited to 'src')
-rw-r--r--src/ChangeLog3
-rw-r--r--src/sysdep.c15
2 files changed, 16 insertions, 2 deletions
diff --git a/src/ChangeLog b/src/ChangeLog
index 9aa58fb0884..db387750b16 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,5 +1,8 @@
2011-04-13 Paul Eggert <eggert@cs.ucla.edu>
+ * sysdep.c (MAX_RW_COUNT): New macro, to work around kernel bugs.
+ (emacs_read, emacs_write): Use it.
+
* process.c (send_process): Count partial writes as successes.
See http://lists.gnu.org/archive/html/emacs-devel/2011-04/msg00483.html
diff --git a/src/sysdep.c b/src/sysdep.c
index 84c8d4ec0ea..8d0bd3df9cc 100644
--- a/src/sysdep.c
+++ b/src/sysdep.c
@@ -1825,6 +1825,17 @@ emacs_close (int fd)
return rtnval;
}
+/* Maximum number of bytes to read or write in a single system call.
+ This works around a serious bug in Linux kernels before 2.6.16; see
+ <https://bugzilla.redhat.com/show_bug.cgi?format=multiple&id=612839>.
+ It's likely to work around similar bugs in other operating systems, so do it
+ on all platforms. Round INT_MAX down to a page size, with the conservative
+ assumption that page sizes are at most 2**18 bytes (any kernel with a
+ page size larger than that shouldn't have the bug). */
+#ifndef MAX_RW_COUNT
+#define MAX_RW_COUNT (INT_MAX >> 18 << 18)
+#endif
+
/* Read from FILEDESC to a buffer BUF with size NBYTE, retrying if interrupted.
Return the number of bytes read, which might be less than NBYTE.
On error, set errno and return -1. */
@@ -1833,7 +1844,7 @@ emacs_read (int fildes, char *buf, size_t nbyte)
{
register ssize_t rtnval;
- while ((rtnval = read (fildes, buf, nbyte)) == -1
+ while ((rtnval = read (fildes, buf, min (nbyte, MAX_RW_COUNT))) == -1
&& (errno == EINTR))
QUIT;
return (rtnval);
@@ -1852,7 +1863,7 @@ emacs_write (int fildes, const char *buf, size_t nbyte)
while (nbyte > 0)
{
- rtnval = write (fildes, buf, nbyte);
+ rtnval = write (fildes, buf, min (nbyte, MAX_RW_COUNT));
if (rtnval < 0)
{