[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: oops? read/write vs type of length parameter
From: |
Paul Eggert |
Subject: |
Re: oops? read/write vs type of length parameter |
Date: |
Wed, 13 Apr 2011 13:02:18 -0700 |
User-agent: |
Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.2.15) Gecko/20110307 Fedora/3.1.9-0.39.b3pre.fc14 Thunderbird/3.1.9 |
On 04/12/2011 11:37 PM, Eli Zaretskii wrote:
> We cannot assume that a given hardware device is 64-bit- and
> signedness-clean as it should be.
That's true, and it's independent of the other issues that we're
discussing. And it comes up with all I/O, not just writes
to sound devices, so it should be fixed in emacs_write (and
emacs_read), independently of the other changes. This is
the MAX_RW_COUNT issue I mentioned in
<http://lists.gnu.org/archive/html/emacs-devel/2011-04/msg00462.html>.
Here's a simple patch which fixes the problem. A platform that is
known not to have the bug can "#define MAX_RW_COUNT SIZE_MAX".
* sysdep.c (MAX_RW_COUNT): New macro, to work around kernel bugs.
(emacs_read, emacs_write): Use it.
=== modified file 'src/sysdep.c'
--- src/sysdep.c 2011-04-13 05:02:54 +0000
+++ src/sysdep.c 2011-04-13 19:52:07 +0000
@@ -1825,6 +1825,17 @@
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 @@
{
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 @@
while (nbyte > 0)
{
- rtnval = write (fildes, buf, nbyte);
+ rtnval = write (fildes, buf, min (nbyte, MAX_RW_COUNT));
if (rtnval < 0)
{
- Re: oops? read/write vs type of length parameter, (continued)
- Re: oops? read/write vs type of length parameter, Paul Eggert, 2011/04/13
- Re: oops? read/write vs type of length parameter, Jim Meyering, 2011/04/13
- Re: oops? read/write vs type of length parameter, Eli Zaretskii, 2011/04/13
- Re: oops? read/write vs type of length parameter, Paul Eggert, 2011/04/13
- Re: oops? read/write vs type of length parameter, Eli Zaretskii, 2011/04/13
- Re: oops? read/write vs type of length parameter, Paul Eggert, 2011/04/13
- Re: oops? read/write vs type of length parameter, Eli Zaretskii, 2011/04/13
- Re: oops? read/write vs type of length parameter, Paul Eggert, 2011/04/13
- Re: oops? read/write vs type of length parameter, PJ Weisberg, 2011/04/13
- Re: oops? read/write vs type of length parameter, Eli Zaretskii, 2011/04/14
- Re: oops? read/write vs type of length parameter,
Paul Eggert <=
- Re: oops? read/write vs type of length parameter, Eli Zaretskii, 2011/04/13
- Re: oops? read/write vs type of length parameter, Ted Zlatanov, 2011/04/13
- Re: oops? read/write vs type of length parameter, Ted Zlatanov, 2011/04/15
- Re: oops? read/write vs type of length parameter, Paul Eggert, 2011/04/15
- Re: oops? read/write vs type of length parameter, Ted Zlatanov, 2011/04/15
- Re: oops? read/write vs type of length parameter, Stefan Monnier, 2011/04/14
- Re: oops? read/write vs type of length parameter, Paul Eggert, 2011/04/15
- Re: oops? read/write vs type of length parameter, Eli Zaretskii, 2011/04/15
- Re: oops? read/write vs type of length parameter, Paul Eggert, 2011/04/15
- Re: oops? read/write vs type of length parameter, Davis Herring, 2011/04/12