mirror of
git://git.sv.gnu.org/emacs.git
synced 2025-12-27 15:52:00 -08:00
* src/lread.c (infile): Set/reset it like a dynamically scoped variable
I've seen segfaults where `infile` is nil when we get to readbyte_from_file, presumably because Fload set it to NULL (via close_infile_unwind) just before returning to its caller which was probably itself within another read/load and for some reason readevalloop didn't get to re-set `infile` like it used to do at every iteration. I was not able to really track down the bug, but the way `infile` was set/reset seemed fragile and managing it like a standard dynamically-scoped var seems both safer (and more efficient since we don't need readevalloop to constantly re-set it). (readchar): Assert that `infile` is set if using a function the depends on it. (readbyte_from_file): Assert that `infile` is set. (close_infile_unwind): Reset `infile` to its previous value rather than to NULL. (Fload): Remember the previous value of `infile` before chaning it. (readevalloop): Don't set `infile` any more.
This commit is contained in:
parent
495d0667fc
commit
bedcc2d87b
1 changed files with 11 additions and 6 deletions
17
src/lread.c
17
src/lread.c
|
|
@ -287,6 +287,7 @@ readchar (Lisp_Object readcharfun, bool *multibyte)
|
|||
|
||||
if (EQ (readcharfun, Qget_file_char))
|
||||
{
|
||||
eassert (infile);
|
||||
readbyte = readbyte_from_file;
|
||||
goto read_multibyte;
|
||||
}
|
||||
|
|
@ -320,6 +321,7 @@ readchar (Lisp_Object readcharfun, bool *multibyte)
|
|||
string, and the cdr part is a value of readcharfun given to
|
||||
read_vector. */
|
||||
readbyte = readbyte_from_string;
|
||||
eassert (infile);
|
||||
if (EQ (XCDR (readcharfun), Qget_emacs_mule_file_char))
|
||||
emacs_mule_encoding = 1;
|
||||
goto read_multibyte;
|
||||
|
|
@ -328,6 +330,7 @@ readchar (Lisp_Object readcharfun, bool *multibyte)
|
|||
if (EQ (readcharfun, Qget_emacs_mule_file_char))
|
||||
{
|
||||
readbyte = readbyte_from_file;
|
||||
eassert (infile);
|
||||
emacs_mule_encoding = 1;
|
||||
goto read_multibyte;
|
||||
}
|
||||
|
|
@ -506,6 +509,7 @@ readbyte_from_stdio (void)
|
|||
static int
|
||||
readbyte_from_file (int c, Lisp_Object readcharfun)
|
||||
{
|
||||
eassert (infile);
|
||||
if (c >= 0)
|
||||
{
|
||||
eassert (infile->lookahead < sizeof infile->buf);
|
||||
|
|
@ -1078,10 +1082,11 @@ suffix_p (Lisp_Object string, const char *suffix)
|
|||
static void
|
||||
close_infile_unwind (void *arg)
|
||||
{
|
||||
FILE *stream = arg;
|
||||
eassert (infile == NULL || infile->stream == stream);
|
||||
infile = NULL;
|
||||
fclose (stream);
|
||||
struct infile *prev_infile = arg;
|
||||
fprintf (stderr, "Closing infile: back to %x!\n", prev_infile);
|
||||
eassert (infile);
|
||||
fclose (infile->stream);
|
||||
infile = prev_infile;
|
||||
}
|
||||
|
||||
DEFUN ("load", Fload, Sload, 1, 5, 0,
|
||||
|
|
@ -1413,7 +1418,7 @@ Return t if the file exists and loads successfully. */)
|
|||
{
|
||||
if (! stream)
|
||||
report_file_error ("Opening stdio stream", file);
|
||||
set_unwind_protect_ptr (fd_index, close_infile_unwind, stream);
|
||||
set_unwind_protect_ptr (fd_index, close_infile_unwind, infile);
|
||||
}
|
||||
|
||||
if (! NILP (Vpurify_flag))
|
||||
|
|
@ -2019,7 +2024,7 @@ readevalloop (Lisp_Object readcharfun,
|
|||
if (b && first_sexp)
|
||||
whole_buffer = (BUF_PT (b) == BUF_BEG (b) && BUF_ZV (b) == BUF_Z (b));
|
||||
|
||||
infile = infile0;
|
||||
eassert (!infile0 || infile == infile0);
|
||||
read_next:
|
||||
c = READCHAR;
|
||||
if (c == ';')
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue