[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Emacs-diffs] /srv/bzr/emacs/trunk r103919: emacs_write: Accept and retu
From: |
Paul Eggert |
Subject: |
[Emacs-diffs] /srv/bzr/emacs/trunk r103919: emacs_write: Accept and return EMACS_INT for sizes. |
Date: |
Fri, 15 Apr 2011 01:51:02 -0700 |
User-agent: |
Bazaar (2.3.1) |
------------------------------------------------------------
revno: 103919 [merge]
committer: Paul Eggert <address@hidden>
branch nick: trunk
timestamp: Fri 2011-04-15 01:51:02 -0700
message:
emacs_write: Accept and return EMACS_INT for sizes.
modified:
src/ChangeLog
src/gnutls.c
src/gnutls.h
src/lisp.h
src/process.c
src/sound.c
src/sysdep.c
=== modified file 'src/ChangeLog'
--- a/src/ChangeLog 2011-04-15 02:03:43 +0000
+++ b/src/ChangeLog 2011-04-15 08:51:02 +0000
@@ -1,3 +1,30 @@
+2011-04-15 Paul Eggert <address@hidden>
+
+ emacs_write: Accept and return EMACS_INT for sizes.
+ See http://lists.gnu.org/archive/html/emacs-devel/2011-04/msg00514.html
+ et seq.
+ * gnutls.c, gnutls.h (emacs_gnutls_read, emacs_gnutls_write):
+ Accept and return EMACS_INT.
+ (emacs_gnutls_write): Return the number of bytes written on
+ partial writes.
+ * sysdep.c, lisp.h (emacs_read, emacs_write): Likewise.
+ (emacs_read, emacs_write): Remove check for negative size, as the
+ Emacs source code has been audited now.
+ * sysdep.c (MAX_RW_COUNT): New macro, to work around kernel bugs.
+ (emacs_read, emacs_write): Use it.
+ * process.c (send_process): Adjust to the new signatures of
+ emacs_write and emacs_gnutls_write. Do not attempt to store
+ a byte offset into an 'int'; it might overflow.
+ See http://lists.gnu.org/archive/html/emacs-devel/2011-04/msg00483.html
+
+ * sound.c: Don't assume sizes fit in 'int'.
+ (struct sound_device.period_size, alsa_period_size):
+ Return EMACS_INT, not int.
+ (struct sound_device.write, vox_write, alsa_write):
+ Accept EMACS_INT, not int.
+ (wav_play, au_play): Use EMACS_INT to store sizes and to
+ record read return values.
+
2011-04-15 Ben Key <address@hidden>
* keyboard.c (Qundefined): Don't declare static since it is
=== modified file 'src/gnutls.c'
--- a/src/gnutls.c 2011-04-10 14:00:13 +0000
+++ b/src/gnutls.c 2011-04-15 08:22:34 +0000
@@ -70,12 +70,12 @@
}
}
-ssize_t
+EMACS_INT
emacs_gnutls_write (int fildes, struct Lisp_Process *proc, const char *buf,
- size_t nbyte)
+ EMACS_INT nbyte)
{
ssize_t rtnval;
- size_t bytes_written;
+ EMACS_INT bytes_written;
gnutls_session_t state = proc->gnutls_state;
if (proc->gnutls_initstage != GNUTLS_STAGE_READY) {
@@ -85,7 +85,7 @@
#ifdef EAGAIN
errno = EAGAIN;
#endif
- return -1;
+ return 0;
}
bytes_written = 0;
@@ -99,7 +99,7 @@
if (rtnval == GNUTLS_E_AGAIN || rtnval == GNUTLS_E_INTERRUPTED)
continue;
else
- return (bytes_written ? bytes_written : -1);
+ break;
}
buf += rtnval;
@@ -110,9 +110,9 @@
return (bytes_written);
}
-ssize_t
+EMACS_INT
emacs_gnutls_read (int fildes, struct Lisp_Process *proc, char *buf,
- size_t nbyte)
+ EMACS_INT nbyte)
{
ssize_t rtnval;
gnutls_session_t state = proc->gnutls_state;
=== modified file 'src/gnutls.h'
--- a/src/gnutls.h 2011-04-10 14:00:13 +0000
+++ b/src/gnutls.h 2011-04-15 08:22:34 +0000
@@ -50,12 +50,12 @@
#define GNUTLS_LOG2(level, max, string, extra) if (level <= max) {
gnutls_log_function2 (level, "(Emacs) " string, extra); }
-ssize_t
+EMACS_INT
emacs_gnutls_write (int fildes, struct Lisp_Process *proc, const char *buf,
- size_t nbyte);
-ssize_t
+ EMACS_INT nbyte);
+EMACS_INT
emacs_gnutls_read (int fildes, struct Lisp_Process *proc, char *buf,
- size_t nbyte);
+ EMACS_INT nbyte);
extern void syms_of_gnutls (void);
=== modified file 'src/lisp.h'
--- a/src/lisp.h 2011-04-15 00:58:49 +0000
+++ b/src/lisp.h 2011-04-15 08:22:34 +0000
@@ -3317,8 +3317,8 @@
extern void seed_random (long);
extern int emacs_open (const char *, int, int);
extern int emacs_close (int);
-extern ssize_t emacs_read (int, char *, size_t);
-extern ssize_t emacs_write (int, const char *, size_t);
+extern EMACS_INT emacs_read (int, char *, EMACS_INT);
+extern EMACS_INT emacs_write (int, const char *, EMACS_INT);
enum { READLINK_BUFSIZE = 1024 };
extern char *emacs_readlink (const char *, char [READLINK_BUFSIZE]);
#ifndef HAVE_MEMSET
=== modified file 'src/process.c'
--- a/src/process.c 2011-04-15 00:58:49 +0000
+++ b/src/process.c 2011-04-15 08:35:53 +0000
@@ -5368,6 +5368,7 @@
/* Send this batch, using one or more write calls. */
while (this > 0)
{
+ EMACS_INT written = 0;
int outfd = p->outfd;
old_sigpipe = (void (*) (int)) signal (SIGPIPE,
send_process_trap);
#ifdef DATAGRAM_SOCKETS
@@ -5376,7 +5377,9 @@
rv = sendto (outfd, buf, this,
0, datagram_address[outfd].sa,
datagram_address[outfd].len);
- if (rv < 0 && errno == EMSGSIZE)
+ if (0 <= rv)
+ written = rv;
+ else if (errno == EMSGSIZE)
{
signal (SIGPIPE, old_sigpipe);
report_file_error ("sending datagram",
@@ -5388,12 +5391,13 @@
{
#ifdef HAVE_GNUTLS
if (XPROCESS (proc)->gnutls_p)
- rv = emacs_gnutls_write (outfd,
- XPROCESS (proc),
- buf, this);
+ written = emacs_gnutls_write (outfd,
+ XPROCESS (proc),
+ buf, this);
else
#endif
- rv = emacs_write (outfd, buf, this);
+ written = emacs_write (outfd, buf, this);
+ rv = (written ? 0 : -1);
#ifdef ADAPTIVE_READ_BUFFERING
if (p->read_output_delay > 0
&& p->adaptive_read_buffering == 1)
@@ -5420,7 +5424,7 @@
that may allow the program
to finish doing output and read more. */
{
- int offset = 0;
+ EMACS_INT offset = 0;
#ifdef BROKEN_PTY_READ_AFTER_EAGAIN
/* A gross hack to work around a bug in FreeBSD.
@@ -5466,16 +5470,14 @@
offset);
else if (STRINGP (object))
buf = offset + SSDATA (object);
-
- rv = 0;
}
else
/* This is a real error. */
report_file_error ("writing to process", Fcons (proc,
Qnil));
}
- buf += rv;
- len -= rv;
- this -= rv;
+ buf += written;
+ len -= written;
+ this -= written;
}
}
}
=== modified file 'src/sound.c'
--- a/src/sound.c 2011-04-14 20:16:48 +0000
+++ b/src/sound.c 2011-04-15 08:47:25 +0000
@@ -235,11 +235,11 @@
/* Return a preferred data size in bytes to be sent to write (below)
each time. 2048 is used if this is NULL. */
- int (* period_size) (struct sound_device *sd);
+ EMACS_INT (* period_size) (struct sound_device *sd);
/* Write NYBTES bytes from BUFFER to device SD. */
void (* write) (struct sound_device *sd, const char *buffer,
- int nbytes);
+ EMACS_INT nbytes);
/* A place for devices to store additional data. */
void *data;
@@ -291,7 +291,7 @@
static void vox_close (struct sound_device *sd);
static void vox_choose_format (struct sound_device *, struct sound *);
static int vox_init (struct sound_device *);
-static void vox_write (struct sound_device *, const char *, int);
+static void vox_write (struct sound_device *, const char *, EMACS_INT);
static void find_sound_type (struct sound *);
static u_int32_t le2hl (u_int32_t);
static u_int16_t le2hs (u_int16_t);
@@ -600,9 +600,9 @@
else
{
char *buffer;
- int nbytes = 0;
- int blksize = sd->period_size ? sd->period_size (sd) : 2048;
- int data_left = header->data_length;
+ EMACS_INT nbytes = 0;
+ EMACS_INT blksize = sd->period_size ? sd->period_size (sd) : 2048;
+ EMACS_INT data_left = header->data_length;
buffer = (char *) alloca (blksize);
lseek (s->fd, sizeof *header, SEEK_SET);
@@ -690,9 +690,9 @@
SBYTES (s->data) - header->data_offset);
else
{
- int blksize = sd->period_size ? sd->period_size (sd) : 2048;
+ EMACS_INT blksize = sd->period_size ? sd->period_size (sd) : 2048;
char *buffer;
- int nbytes;
+ EMACS_INT nbytes;
/* Seek */
lseek (s->fd, header->data_offset, SEEK_SET);
@@ -895,10 +895,9 @@
/* Write NBYTES bytes from BUFFER to device SD. */
static void
-vox_write (struct sound_device *sd, const char *buffer, int nbytes)
+vox_write (struct sound_device *sd, const char *buffer, EMACS_INT nbytes)
{
- ssize_t nwritten = emacs_write (sd->fd, buffer, nbytes);
- if (nwritten < 0)
+ if (emacs_write (sd->fd, buffer, nbytes) != nbytes)
sound_perror ("Error writing to sound device");
}
@@ -953,7 +952,7 @@
alsa_sound_perror (file, err);
}
-static int
+static EMACS_INT
alsa_period_size (struct sound_device *sd)
{
struct alsa_params *p = (struct alsa_params *) sd->data;
@@ -1156,13 +1155,13 @@
/* Write NBYTES bytes from BUFFER to device SD. */
static void
-alsa_write (struct sound_device *sd, const char *buffer, int nbytes)
+alsa_write (struct sound_device *sd, const char *buffer, EMACS_INT nbytes)
{
struct alsa_params *p = (struct alsa_params *) sd->data;
/* The the third parameter to snd_pcm_writei is frames, not bytes. */
int fact = snd_pcm_format_size (sd->format, 1) * sd->channels;
- int nwritten = 0;
+ EMACS_INT nwritten = 0;
int err;
while (nwritten < nbytes)
=== modified file 'src/sysdep.c'
--- a/src/sysdep.c 2011-04-14 20:16:48 +0000
+++ b/src/sysdep.c 2011-04-15 08:22:34 +0000
@@ -1825,41 +1825,47 @@
return rtnval;
}
-ssize_t
-emacs_read (int fildes, char *buf, size_t nbyte)
+/* 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. */
+EMACS_INT
+emacs_read (int fildes, char *buf, EMACS_INT nbyte)
{
register ssize_t rtnval;
- /* Defend against the possibility that a buggy caller passes a negative NBYTE
- argument, which would be converted to a large unsigned size_t NBYTE. This
- defense prevents callers from doing large writes, unfortunately. This
- size restriction can be removed once we have carefully checked that there
- are no such callers. */
- if ((ssize_t) nbyte < 0)
- abort ();
-
- while ((rtnval = read (fildes, buf, nbyte)) == -1
+ while ((rtnval = read (fildes, buf, min (nbyte, MAX_RW_COUNT))) == -1
&& (errno == EINTR))
QUIT;
return (rtnval);
}
-ssize_t
-emacs_write (int fildes, const char *buf, size_t nbyte)
+/* Write to FILEDES from a buffer BUF with size NBYTE, retrying if interrupted
+ or if a partial write occurs. Return the number of bytes written, setting
+ errno if this is less than NBYTE. */
+EMACS_INT
+emacs_write (int fildes, const char *buf, EMACS_INT nbyte)
{
- register ssize_t rtnval, bytes_written;
-
- /* Defend against negative NBYTE, as in emacs_read. */
- if ((ssize_t) nbyte < 0)
- abort ();
+ ssize_t rtnval;
+ EMACS_INT bytes_written;
bytes_written = 0;
- while (nbyte != 0)
+ while (nbyte > 0)
{
- rtnval = write (fildes, buf, nbyte);
+ rtnval = write (fildes, buf, min (nbyte, MAX_RW_COUNT));
- if (rtnval == -1)
+ if (rtnval < 0)
{
if (errno == EINTR)
{
@@ -1871,13 +1877,14 @@
continue;
}
else
- return (bytes_written ? bytes_written : -1);
+ break;
}
buf += rtnval;
nbyte -= rtnval;
bytes_written += rtnval;
}
+
return (bytes_written);
}
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [Emacs-diffs] /srv/bzr/emacs/trunk r103919: emacs_write: Accept and return EMACS_INT for sizes.,
Paul Eggert <=