diff options
| author | Paul Eggert | 2011-04-13 12:54:09 -0700 |
|---|---|---|
| committer | Paul Eggert | 2011-04-13 12:54:09 -0700 |
| commit | 1963a2e0bb07cc8dee6d27f972f93d9cfd7c6b2d (patch) | |
| tree | c6760a6aef71252e16af9ad463f6126631d0dc39 | |
| parent | 086e8c477d4342c8e718f9bb811da0b1a6e1e946 (diff) | |
| download | emacs-1963a2e0bb07cc8dee6d27f972f93d9cfd7c6b2d.tar.gz emacs-1963a2e0bb07cc8dee6d27f972f93d9cfd7c6b2d.zip | |
* sysdep.c (MAX_RW_COUNT): New macro, to work around kernel bugs.
(emacs_read, emacs_write): Use it.
| -rw-r--r-- | src/ChangeLog | 3 | ||||
| -rw-r--r-- | 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 @@ | |||
| 1 | 2011-04-13 Paul Eggert <eggert@cs.ucla.edu> | 1 | 2011-04-13 Paul Eggert <eggert@cs.ucla.edu> |
| 2 | 2 | ||
| 3 | * sysdep.c (MAX_RW_COUNT): New macro, to work around kernel bugs. | ||
| 4 | (emacs_read, emacs_write): Use it. | ||
| 5 | |||
| 3 | * process.c (send_process): Count partial writes as successes. | 6 | * process.c (send_process): Count partial writes as successes. |
| 4 | See http://lists.gnu.org/archive/html/emacs-devel/2011-04/msg00483.html | 7 | See http://lists.gnu.org/archive/html/emacs-devel/2011-04/msg00483.html |
| 5 | 8 | ||
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) | |||
| 1825 | return rtnval; | 1825 | return rtnval; |
| 1826 | } | 1826 | } |
| 1827 | 1827 | ||
| 1828 | /* Maximum number of bytes to read or write in a single system call. | ||
| 1829 | This works around a serious bug in Linux kernels before 2.6.16; see | ||
| 1830 | <https://bugzilla.redhat.com/show_bug.cgi?format=multiple&id=612839>. | ||
| 1831 | It's likely to work around similar bugs in other operating systems, so do it | ||
| 1832 | on all platforms. Round INT_MAX down to a page size, with the conservative | ||
| 1833 | assumption that page sizes are at most 2**18 bytes (any kernel with a | ||
| 1834 | page size larger than that shouldn't have the bug). */ | ||
| 1835 | #ifndef MAX_RW_COUNT | ||
| 1836 | #define MAX_RW_COUNT (INT_MAX >> 18 << 18) | ||
| 1837 | #endif | ||
| 1838 | |||
| 1828 | /* Read from FILEDESC to a buffer BUF with size NBYTE, retrying if interrupted. | 1839 | /* Read from FILEDESC to a buffer BUF with size NBYTE, retrying if interrupted. |
| 1829 | Return the number of bytes read, which might be less than NBYTE. | 1840 | Return the number of bytes read, which might be less than NBYTE. |
| 1830 | On error, set errno and return -1. */ | 1841 | On error, set errno and return -1. */ |
| @@ -1833,7 +1844,7 @@ emacs_read (int fildes, char *buf, size_t nbyte) | |||
| 1833 | { | 1844 | { |
| 1834 | register ssize_t rtnval; | 1845 | register ssize_t rtnval; |
| 1835 | 1846 | ||
| 1836 | while ((rtnval = read (fildes, buf, nbyte)) == -1 | 1847 | while ((rtnval = read (fildes, buf, min (nbyte, MAX_RW_COUNT))) == -1 |
| 1837 | && (errno == EINTR)) | 1848 | && (errno == EINTR)) |
| 1838 | QUIT; | 1849 | QUIT; |
| 1839 | return (rtnval); | 1850 | return (rtnval); |
| @@ -1852,7 +1863,7 @@ emacs_write (int fildes, const char *buf, size_t nbyte) | |||
| 1852 | 1863 | ||
| 1853 | while (nbyte > 0) | 1864 | while (nbyte > 0) |
| 1854 | { | 1865 | { |
| 1855 | rtnval = write (fildes, buf, nbyte); | 1866 | rtnval = write (fildes, buf, min (nbyte, MAX_RW_COUNT)); |
| 1856 | 1867 | ||
| 1857 | if (rtnval < 0) | 1868 | if (rtnval < 0) |
| 1858 | { | 1869 | { |