From 1963a2e0bb07cc8dee6d27f972f93d9cfd7c6b2d Mon Sep 17 00:00:00 2001 From: Paul Eggert Date: Wed, 13 Apr 2011 12:54:09 -0700 Subject: [PATCH] * sysdep.c (MAX_RW_COUNT): New macro, to work around kernel bugs. (emacs_read, emacs_write): Use it. --- src/ChangeLog | 3 +++ src/sysdep.c | 15 +++++++++++++-- 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 + * 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 + . + 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) { -- 2.39.2