aboutsummaryrefslogtreecommitdiffstats
path: root/src/sysdep.c
diff options
context:
space:
mode:
authorPaul Eggert2011-04-15 01:51:02 -0700
committerPaul Eggert2011-04-15 01:51:02 -0700
commit9c3c56a7475d2ee8c834cbcc46e615b99bd6fced (patch)
treee874f0e4728422cf6b6a63e96418dc14d3f2eccc /src/sysdep.c
parent49093f601b69d91126aefd328ee8f6bfeb797407 (diff)
parenta0238ccadcb6bf4eaf5caaced7d3904458a698db (diff)
downloademacs-9c3c56a7475d2ee8c834cbcc46e615b99bd6fced.tar.gz
emacs-9c3c56a7475d2ee8c834cbcc46e615b99bd6fced.zip
emacs_write: Accept and return EMACS_INT for sizes.
Diffstat (limited to 'src/sysdep.c')
-rw-r--r--src/sysdep.c51
1 files changed, 29 insertions, 22 deletions
diff --git a/src/sysdep.c b/src/sysdep.c
index 0d9b31f35cd..6b6e3e9e791 100644
--- a/src/sysdep.c
+++ b/src/sysdep.c
@@ -1825,41 +1825,47 @@ emacs_close (int fd)
1825 return rtnval; 1825 return rtnval;
1826} 1826}
1827 1827
1828ssize_t 1828/* Maximum number of bytes to read or write in a single system call.
1829emacs_read (int fildes, char *buf, size_t nbyte) 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
1839/* Read from FILEDESC to a buffer BUF with size NBYTE, retrying if interrupted.
1840 Return the number of bytes read, which might be less than NBYTE.
1841 On error, set errno and return -1. */
1842EMACS_INT
1843emacs_read (int fildes, char *buf, EMACS_INT nbyte)
1830{ 1844{
1831 register ssize_t rtnval; 1845 register ssize_t rtnval;
1832 1846
1833 /* Defend against the possibility that a buggy caller passes a negative NBYTE 1847 while ((rtnval = read (fildes, buf, min (nbyte, MAX_RW_COUNT))) == -1
1834 argument, which would be converted to a large unsigned size_t NBYTE. This
1835 defense prevents callers from doing large writes, unfortunately. This
1836 size restriction can be removed once we have carefully checked that there
1837 are no such callers. */
1838 if ((ssize_t) nbyte < 0)
1839 abort ();
1840
1841 while ((rtnval = read (fildes, buf, nbyte)) == -1
1842 && (errno == EINTR)) 1848 && (errno == EINTR))
1843 QUIT; 1849 QUIT;
1844 return (rtnval); 1850 return (rtnval);
1845} 1851}
1846 1852
1847ssize_t 1853/* Write to FILEDES from a buffer BUF with size NBYTE, retrying if interrupted
1848emacs_write (int fildes, const char *buf, size_t nbyte) 1854 or if a partial write occurs. Return the number of bytes written, setting
1855 errno if this is less than NBYTE. */
1856EMACS_INT
1857emacs_write (int fildes, const char *buf, EMACS_INT nbyte)
1849{ 1858{
1850 register ssize_t rtnval, bytes_written; 1859 ssize_t rtnval;
1851 1860 EMACS_INT bytes_written;
1852 /* Defend against negative NBYTE, as in emacs_read. */
1853 if ((ssize_t) nbyte < 0)
1854 abort ();
1855 1861
1856 bytes_written = 0; 1862 bytes_written = 0;
1857 1863
1858 while (nbyte != 0) 1864 while (nbyte > 0)
1859 { 1865 {
1860 rtnval = write (fildes, buf, nbyte); 1866 rtnval = write (fildes, buf, min (nbyte, MAX_RW_COUNT));
1861 1867
1862 if (rtnval == -1) 1868 if (rtnval < 0)
1863 { 1869 {
1864 if (errno == EINTR) 1870 if (errno == EINTR)
1865 { 1871 {
@@ -1871,13 +1877,14 @@ emacs_write (int fildes, const char *buf, size_t nbyte)
1871 continue; 1877 continue;
1872 } 1878 }
1873 else 1879 else
1874 return (bytes_written ? bytes_written : -1); 1880 break;
1875 } 1881 }
1876 1882
1877 buf += rtnval; 1883 buf += rtnval;
1878 nbyte -= rtnval; 1884 nbyte -= rtnval;
1879 bytes_written += rtnval; 1885 bytes_written += rtnval;
1880 } 1886 }
1887
1881 return (bytes_written); 1888 return (bytes_written);
1882} 1889}
1883 1890