mirror of
git://git.sv.gnu.org/emacs.git
synced 2026-01-02 02:10:46 -08:00
emacs_write: Accept and return EMACS_INT for sizes.
This commit is contained in:
commit
9c3c56a747
7 changed files with 95 additions and 60 deletions
|
|
@ -1,3 +1,30 @@
|
|||
2011-04-15 Paul Eggert <eggert@cs.ucla.edu>
|
||||
|
||||
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 <bkey76@gmail.com>
|
||||
|
||||
* keyboard.c (Qundefined): Don't declare static since it is
|
||||
|
|
|
|||
14
src/gnutls.c
14
src/gnutls.c
|
|
@ -70,12 +70,12 @@ emacs_gnutls_handshake (struct Lisp_Process *proc)
|
|||
}
|
||||
}
|
||||
|
||||
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 @@ emacs_gnutls_write (int fildes, struct Lisp_Process *proc, const char *buf,
|
|||
#ifdef EAGAIN
|
||||
errno = EAGAIN;
|
||||
#endif
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
bytes_written = 0;
|
||||
|
|
@ -99,7 +99,7 @@ emacs_gnutls_write (int fildes, struct Lisp_Process *proc, const char *buf,
|
|||
if (rtnval == GNUTLS_E_AGAIN || rtnval == GNUTLS_E_INTERRUPTED)
|
||||
continue;
|
||||
else
|
||||
return (bytes_written ? bytes_written : -1);
|
||||
break;
|
||||
}
|
||||
|
||||
buf += rtnval;
|
||||
|
|
@ -110,9 +110,9 @@ emacs_gnutls_write (int fildes, struct Lisp_Process *proc, const char *buf,
|
|||
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;
|
||||
|
|
|
|||
|
|
@ -50,12 +50,12 @@ typedef enum
|
|||
|
||||
#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);
|
||||
|
||||
|
|
|
|||
|
|
@ -3317,8 +3317,8 @@ extern long get_random (void);
|
|||
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
|
||||
|
|
|
|||
|
|
@ -5368,6 +5368,7 @@ send_process (volatile Lisp_Object proc, const char *volatile buf,
|
|||
/* 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 @@ send_process (volatile Lisp_Object proc, const char *volatile buf,
|
|||
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 @@ send_process (volatile Lisp_Object proc, const char *volatile buf,
|
|||
{
|
||||
#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 @@ send_process (volatile Lisp_Object proc, const char *volatile buf,
|
|||
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 @@ send_process (volatile Lisp_Object proc, const char *volatile buf,
|
|||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
27
src/sound.c
27
src/sound.c
|
|
@ -235,11 +235,11 @@ struct sound_device
|
|||
|
||||
/* 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_configure (struct sound_device *);
|
|||
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 @@ wav_play (struct sound *s, struct sound_device *sd)
|
|||
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 @@ au_play (struct sound *s, struct sound_device *sd)
|
|||
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 @@ vox_init (struct sound_device *sd)
|
|||
/* 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_open (struct sound_device *sd)
|
|||
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 @@ alsa_choose_format (struct sound_device *sd, struct sound *s)
|
|||
/* 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)
|
||||
|
|
|
|||
51
src/sysdep.c
51
src/sysdep.c
|
|
@ -1825,41 +1825,47 @@ emacs_close (int fd)
|
|||
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 @@ emacs_write (int fildes, const char *buf, size_t nbyte)
|
|||
continue;
|
||||
}
|
||||
else
|
||||
return (bytes_written ? bytes_written : -1);
|
||||
break;
|
||||
}
|
||||
|
||||
buf += rtnval;
|
||||
nbyte -= rtnval;
|
||||
bytes_written += rtnval;
|
||||
}
|
||||
|
||||
return (bytes_written);
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue