]> git.eshelyaron.com Git - emacs.git/commitdiff
* sysdep.c (MAX_RW_COUNT): New macro, to work around kernel bugs.
authorPaul Eggert <eggert@cs.ucla.edu>
Wed, 13 Apr 2011 19:54:09 +0000 (12:54 -0700)
committerPaul Eggert <eggert@cs.ucla.edu>
Wed, 13 Apr 2011 19:54:09 +0000 (12:54 -0700)
(emacs_read, emacs_write): Use it.

src/ChangeLog
src/sysdep.c

index 9aa58fb088445cc9421f09a4e365af7a20a18924..db387750b16994d88622d7e07266ff7b4cec10fd 100644 (file)
@@ -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
 
index 84c8d4ec0eaadde63e981cc37be1a61b2052e0d9..8d0bd3df9cc472bf4ded6191cf3db42a86440800 100644 (file)
@@ -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)
        {