aboutsummaryrefslogtreecommitdiffstats
path: root/src
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
parent49093f601b69d91126aefd328ee8f6bfeb797407 (diff)
parenta0238ccadcb6bf4eaf5caaced7d3904458a698db (diff)
downloademacs-9c3c56a7475d2ee8c834cbcc46e615b99bd6fced.tar.gz
emacs-9c3c56a7475d2ee8c834cbcc46e615b99bd6fced.zip
emacs_write: Accept and return EMACS_INT for sizes.
Diffstat (limited to 'src')
-rw-r--r--src/ChangeLog27
-rw-r--r--src/gnutls.c14
-rw-r--r--src/gnutls.h8
-rw-r--r--src/lisp.h4
-rw-r--r--src/process.c24
-rw-r--r--src/sound.c27
-rw-r--r--src/sysdep.c51
7 files changed, 95 insertions, 60 deletions
diff --git a/src/ChangeLog b/src/ChangeLog
index 706751bbdfa..200c20fc3bf 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,30 @@
12011-04-15 Paul Eggert <eggert@cs.ucla.edu>
2
3 emacs_write: Accept and return EMACS_INT for sizes.
4 See http://lists.gnu.org/archive/html/emacs-devel/2011-04/msg00514.html
5 et seq.
6 * gnutls.c, gnutls.h (emacs_gnutls_read, emacs_gnutls_write):
7 Accept and return EMACS_INT.
8 (emacs_gnutls_write): Return the number of bytes written on
9 partial writes.
10 * sysdep.c, lisp.h (emacs_read, emacs_write): Likewise.
11 (emacs_read, emacs_write): Remove check for negative size, as the
12 Emacs source code has been audited now.
13 * sysdep.c (MAX_RW_COUNT): New macro, to work around kernel bugs.
14 (emacs_read, emacs_write): Use it.
15 * process.c (send_process): Adjust to the new signatures of
16 emacs_write and emacs_gnutls_write. Do not attempt to store
17 a byte offset into an 'int'; it might overflow.
18 See http://lists.gnu.org/archive/html/emacs-devel/2011-04/msg00483.html
19
20 * sound.c: Don't assume sizes fit in 'int'.
21 (struct sound_device.period_size, alsa_period_size):
22 Return EMACS_INT, not int.
23 (struct sound_device.write, vox_write, alsa_write):
24 Accept EMACS_INT, not int.
25 (wav_play, au_play): Use EMACS_INT to store sizes and to
26 record read return values.
27
12011-04-15 Ben Key <bkey76@gmail.com> 282011-04-15 Ben Key <bkey76@gmail.com>
2 29
3 * keyboard.c (Qundefined): Don't declare static since it is 30 * keyboard.c (Qundefined): Don't declare static since it is
diff --git a/src/gnutls.c b/src/gnutls.c
index d9e4dcec15a..d7328e114c7 100644
--- a/src/gnutls.c
+++ b/src/gnutls.c
@@ -70,12 +70,12 @@ emacs_gnutls_handshake (struct Lisp_Process *proc)
70 } 70 }
71} 71}
72 72
73ssize_t 73EMACS_INT
74emacs_gnutls_write (int fildes, struct Lisp_Process *proc, const char *buf, 74emacs_gnutls_write (int fildes, struct Lisp_Process *proc, const char *buf,
75 size_t nbyte) 75 EMACS_INT nbyte)
76{ 76{
77 ssize_t rtnval; 77 ssize_t rtnval;
78 size_t bytes_written; 78 EMACS_INT bytes_written;
79 gnutls_session_t state = proc->gnutls_state; 79 gnutls_session_t state = proc->gnutls_state;
80 80
81 if (proc->gnutls_initstage != GNUTLS_STAGE_READY) { 81 if (proc->gnutls_initstage != GNUTLS_STAGE_READY) {
@@ -85,7 +85,7 @@ emacs_gnutls_write (int fildes, struct Lisp_Process *proc, const char *buf,
85#ifdef EAGAIN 85#ifdef EAGAIN
86 errno = EAGAIN; 86 errno = EAGAIN;
87#endif 87#endif
88 return -1; 88 return 0;
89 } 89 }
90 90
91 bytes_written = 0; 91 bytes_written = 0;
@@ -99,7 +99,7 @@ emacs_gnutls_write (int fildes, struct Lisp_Process *proc, const char *buf,
99 if (rtnval == GNUTLS_E_AGAIN || rtnval == GNUTLS_E_INTERRUPTED) 99 if (rtnval == GNUTLS_E_AGAIN || rtnval == GNUTLS_E_INTERRUPTED)
100 continue; 100 continue;
101 else 101 else
102 return (bytes_written ? bytes_written : -1); 102 break;
103 } 103 }
104 104
105 buf += rtnval; 105 buf += rtnval;
@@ -110,9 +110,9 @@ emacs_gnutls_write (int fildes, struct Lisp_Process *proc, const char *buf,
110 return (bytes_written); 110 return (bytes_written);
111} 111}
112 112
113ssize_t 113EMACS_INT
114emacs_gnutls_read (int fildes, struct Lisp_Process *proc, char *buf, 114emacs_gnutls_read (int fildes, struct Lisp_Process *proc, char *buf,
115 size_t nbyte) 115 EMACS_INT nbyte)
116{ 116{
117 ssize_t rtnval; 117 ssize_t rtnval;
118 gnutls_session_t state = proc->gnutls_state; 118 gnutls_session_t state = proc->gnutls_state;
diff --git a/src/gnutls.h b/src/gnutls.h
index b39131b6236..5240d94c2ad 100644
--- a/src/gnutls.h
+++ b/src/gnutls.h
@@ -50,12 +50,12 @@ typedef enum
50 50
51#define GNUTLS_LOG2(level, max, string, extra) if (level <= max) { gnutls_log_function2 (level, "(Emacs) " string, extra); } 51#define GNUTLS_LOG2(level, max, string, extra) if (level <= max) { gnutls_log_function2 (level, "(Emacs) " string, extra); }
52 52
53ssize_t 53EMACS_INT
54emacs_gnutls_write (int fildes, struct Lisp_Process *proc, const char *buf, 54emacs_gnutls_write (int fildes, struct Lisp_Process *proc, const char *buf,
55 size_t nbyte); 55 EMACS_INT nbyte);
56ssize_t 56EMACS_INT
57emacs_gnutls_read (int fildes, struct Lisp_Process *proc, char *buf, 57emacs_gnutls_read (int fildes, struct Lisp_Process *proc, char *buf,
58 size_t nbyte); 58 EMACS_INT nbyte);
59 59
60extern void syms_of_gnutls (void); 60extern void syms_of_gnutls (void);
61 61
diff --git a/src/lisp.h b/src/lisp.h
index 96c8e42995b..581835dd32b 100644
--- a/src/lisp.h
+++ b/src/lisp.h
@@ -3317,8 +3317,8 @@ extern long get_random (void);
3317extern void seed_random (long); 3317extern void seed_random (long);
3318extern int emacs_open (const char *, int, int); 3318extern int emacs_open (const char *, int, int);
3319extern int emacs_close (int); 3319extern int emacs_close (int);
3320extern ssize_t emacs_read (int, char *, size_t); 3320extern EMACS_INT emacs_read (int, char *, EMACS_INT);
3321extern ssize_t emacs_write (int, const char *, size_t); 3321extern EMACS_INT emacs_write (int, const char *, EMACS_INT);
3322enum { READLINK_BUFSIZE = 1024 }; 3322enum { READLINK_BUFSIZE = 1024 };
3323extern char *emacs_readlink (const char *, char [READLINK_BUFSIZE]); 3323extern char *emacs_readlink (const char *, char [READLINK_BUFSIZE]);
3324#ifndef HAVE_MEMSET 3324#ifndef HAVE_MEMSET
diff --git a/src/process.c b/src/process.c
index e9ac324845b..c9c6ab6d4b3 100644
--- a/src/process.c
+++ b/src/process.c
@@ -5368,6 +5368,7 @@ send_process (volatile Lisp_Object proc, const char *volatile buf,
5368 /* Send this batch, using one or more write calls. */ 5368 /* Send this batch, using one or more write calls. */
5369 while (this > 0) 5369 while (this > 0)
5370 { 5370 {
5371 EMACS_INT written = 0;
5371 int outfd = p->outfd; 5372 int outfd = p->outfd;
5372 old_sigpipe = (void (*) (int)) signal (SIGPIPE, send_process_trap); 5373 old_sigpipe = (void (*) (int)) signal (SIGPIPE, send_process_trap);
5373#ifdef DATAGRAM_SOCKETS 5374#ifdef DATAGRAM_SOCKETS
@@ -5376,7 +5377,9 @@ send_process (volatile Lisp_Object proc, const char *volatile buf,
5376 rv = sendto (outfd, buf, this, 5377 rv = sendto (outfd, buf, this,
5377 0, datagram_address[outfd].sa, 5378 0, datagram_address[outfd].sa,
5378 datagram_address[outfd].len); 5379 datagram_address[outfd].len);
5379 if (rv < 0 && errno == EMSGSIZE) 5380 if (0 <= rv)
5381 written = rv;
5382 else if (errno == EMSGSIZE)
5380 { 5383 {
5381 signal (SIGPIPE, old_sigpipe); 5384 signal (SIGPIPE, old_sigpipe);
5382 report_file_error ("sending datagram", 5385 report_file_error ("sending datagram",
@@ -5388,12 +5391,13 @@ send_process (volatile Lisp_Object proc, const char *volatile buf,
5388 { 5391 {
5389#ifdef HAVE_GNUTLS 5392#ifdef HAVE_GNUTLS
5390 if (XPROCESS (proc)->gnutls_p) 5393 if (XPROCESS (proc)->gnutls_p)
5391 rv = emacs_gnutls_write (outfd, 5394 written = emacs_gnutls_write (outfd,
5392 XPROCESS (proc), 5395 XPROCESS (proc),
5393 buf, this); 5396 buf, this);
5394 else 5397 else
5395#endif 5398#endif
5396 rv = emacs_write (outfd, buf, this); 5399 written = emacs_write (outfd, buf, this);
5400 rv = (written ? 0 : -1);
5397#ifdef ADAPTIVE_READ_BUFFERING 5401#ifdef ADAPTIVE_READ_BUFFERING
5398 if (p->read_output_delay > 0 5402 if (p->read_output_delay > 0
5399 && p->adaptive_read_buffering == 1) 5403 && p->adaptive_read_buffering == 1)
@@ -5420,7 +5424,7 @@ send_process (volatile Lisp_Object proc, const char *volatile buf,
5420 that may allow the program 5424 that may allow the program
5421 to finish doing output and read more. */ 5425 to finish doing output and read more. */
5422 { 5426 {
5423 int offset = 0; 5427 EMACS_INT offset = 0;
5424 5428
5425#ifdef BROKEN_PTY_READ_AFTER_EAGAIN 5429#ifdef BROKEN_PTY_READ_AFTER_EAGAIN
5426 /* A gross hack to work around a bug in FreeBSD. 5430 /* A gross hack to work around a bug in FreeBSD.
@@ -5466,16 +5470,14 @@ send_process (volatile Lisp_Object proc, const char *volatile buf,
5466 offset); 5470 offset);
5467 else if (STRINGP (object)) 5471 else if (STRINGP (object))
5468 buf = offset + SSDATA (object); 5472 buf = offset + SSDATA (object);
5469
5470 rv = 0;
5471 } 5473 }
5472 else 5474 else
5473 /* This is a real error. */ 5475 /* This is a real error. */
5474 report_file_error ("writing to process", Fcons (proc, Qnil)); 5476 report_file_error ("writing to process", Fcons (proc, Qnil));
5475 } 5477 }
5476 buf += rv; 5478 buf += written;
5477 len -= rv; 5479 len -= written;
5478 this -= rv; 5480 this -= written;
5479 } 5481 }
5480 } 5482 }
5481 } 5483 }
diff --git a/src/sound.c b/src/sound.c
index 697e81c814b..794c8e64e54 100644
--- a/src/sound.c
+++ b/src/sound.c
@@ -235,11 +235,11 @@ struct sound_device
235 235
236 /* Return a preferred data size in bytes to be sent to write (below) 236 /* Return a preferred data size in bytes to be sent to write (below)
237 each time. 2048 is used if this is NULL. */ 237 each time. 2048 is used if this is NULL. */
238 int (* period_size) (struct sound_device *sd); 238 EMACS_INT (* period_size) (struct sound_device *sd);
239 239
240 /* Write NYBTES bytes from BUFFER to device SD. */ 240 /* Write NYBTES bytes from BUFFER to device SD. */
241 void (* write) (struct sound_device *sd, const char *buffer, 241 void (* write) (struct sound_device *sd, const char *buffer,
242 int nbytes); 242 EMACS_INT nbytes);
243 243
244 /* A place for devices to store additional data. */ 244 /* A place for devices to store additional data. */
245 void *data; 245 void *data;
@@ -291,7 +291,7 @@ static void vox_configure (struct sound_device *);
291static void vox_close (struct sound_device *sd); 291static void vox_close (struct sound_device *sd);
292static void vox_choose_format (struct sound_device *, struct sound *); 292static void vox_choose_format (struct sound_device *, struct sound *);
293static int vox_init (struct sound_device *); 293static int vox_init (struct sound_device *);
294static void vox_write (struct sound_device *, const char *, int); 294static void vox_write (struct sound_device *, const char *, EMACS_INT);
295static void find_sound_type (struct sound *); 295static void find_sound_type (struct sound *);
296static u_int32_t le2hl (u_int32_t); 296static u_int32_t le2hl (u_int32_t);
297static u_int16_t le2hs (u_int16_t); 297static u_int16_t le2hs (u_int16_t);
@@ -600,9 +600,9 @@ wav_play (struct sound *s, struct sound_device *sd)
600 else 600 else
601 { 601 {
602 char *buffer; 602 char *buffer;
603 int nbytes = 0; 603 EMACS_INT nbytes = 0;
604 int blksize = sd->period_size ? sd->period_size (sd) : 2048; 604 EMACS_INT blksize = sd->period_size ? sd->period_size (sd) : 2048;
605 int data_left = header->data_length; 605 EMACS_INT data_left = header->data_length;
606 606
607 buffer = (char *) alloca (blksize); 607 buffer = (char *) alloca (blksize);
608 lseek (s->fd, sizeof *header, SEEK_SET); 608 lseek (s->fd, sizeof *header, SEEK_SET);
@@ -690,9 +690,9 @@ au_play (struct sound *s, struct sound_device *sd)
690 SBYTES (s->data) - header->data_offset); 690 SBYTES (s->data) - header->data_offset);
691 else 691 else
692 { 692 {
693 int blksize = sd->period_size ? sd->period_size (sd) : 2048; 693 EMACS_INT blksize = sd->period_size ? sd->period_size (sd) : 2048;
694 char *buffer; 694 char *buffer;
695 int nbytes; 695 EMACS_INT nbytes;
696 696
697 /* Seek */ 697 /* Seek */
698 lseek (s->fd, header->data_offset, SEEK_SET); 698 lseek (s->fd, header->data_offset, SEEK_SET);
@@ -895,10 +895,9 @@ vox_init (struct sound_device *sd)
895/* Write NBYTES bytes from BUFFER to device SD. */ 895/* Write NBYTES bytes from BUFFER to device SD. */
896 896
897static void 897static void
898vox_write (struct sound_device *sd, const char *buffer, int nbytes) 898vox_write (struct sound_device *sd, const char *buffer, EMACS_INT nbytes)
899{ 899{
900 ssize_t nwritten = emacs_write (sd->fd, buffer, nbytes); 900 if (emacs_write (sd->fd, buffer, nbytes) != nbytes)
901 if (nwritten < 0)
902 sound_perror ("Error writing to sound device"); 901 sound_perror ("Error writing to sound device");
903} 902}
904 903
@@ -953,7 +952,7 @@ alsa_open (struct sound_device *sd)
953 alsa_sound_perror (file, err); 952 alsa_sound_perror (file, err);
954} 953}
955 954
956static int 955static EMACS_INT
957alsa_period_size (struct sound_device *sd) 956alsa_period_size (struct sound_device *sd)
958{ 957{
959 struct alsa_params *p = (struct alsa_params *) sd->data; 958 struct alsa_params *p = (struct alsa_params *) sd->data;
@@ -1156,13 +1155,13 @@ alsa_choose_format (struct sound_device *sd, struct sound *s)
1156/* Write NBYTES bytes from BUFFER to device SD. */ 1155/* Write NBYTES bytes from BUFFER to device SD. */
1157 1156
1158static void 1157static void
1159alsa_write (struct sound_device *sd, const char *buffer, int nbytes) 1158alsa_write (struct sound_device *sd, const char *buffer, EMACS_INT nbytes)
1160{ 1159{
1161 struct alsa_params *p = (struct alsa_params *) sd->data; 1160 struct alsa_params *p = (struct alsa_params *) sd->data;
1162 1161
1163 /* The the third parameter to snd_pcm_writei is frames, not bytes. */ 1162 /* The the third parameter to snd_pcm_writei is frames, not bytes. */
1164 int fact = snd_pcm_format_size (sd->format, 1) * sd->channels; 1163 int fact = snd_pcm_format_size (sd->format, 1) * sd->channels;
1165 int nwritten = 0; 1164 EMACS_INT nwritten = 0;
1166 int err; 1165 int err;
1167 1166
1168 while (nwritten < nbytes) 1167 while (nwritten < nbytes)
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