# HG changeset patch # User Karoly Lorentey # Date 1126420923 0 # Node ID 0b75ace4f7adca8964f690ae7a116c0b979d1787 # Parent 35ba943c83997badc8770c30a0f3a5deb45f0907 Fix crash after y-or-n-p prompt triggered by emacsclient. (Reported by Han Boetes, analysis by Kalle Olavi Niemitalo.) * src/keyboard.c (temporarily_switch_to_single_kboard) (record_single_kboard_state, restore_kboard_configuration): New functions. (timer_check): Use record_single_kboard_state instead of naive single_kboard state management. * src/fns.c: Include termhooks.h. (Fy_or_n_p): Use temporarily_switch_to_single_kboard to prevent crashes caused by bogus longjmps in read_char. * src/callint.c (Fcall_interactively): Use temporarily_switch_to_single_kboard instead of single_kboard_state. Make sure it is correctly unwinded. * src/keyboard.c (recursive_edit_unwind): Remove single_kboard stuff. (Frecursive_edit): Use temporarily_switch_to_single_kboard for single_kboard state management. * src/minibuf.c (read_minibuf): Use temporarily_switch_to_single_kboard instead of simply calling single_kboard_state. * src/keyboard.c (push_device_kboard): Remove function. (push_kboard): New function. (push_frame_kboard): Use it. (pop_frame_kboard): Rename to pop_kboard. * src/xdisp.c (display_mode_line, Fformat_mode_line): Update uses. * src/data.c: Include termhooks.h. (Fterminal_local_value, Fset_terminal_local_value): Update. * src/Makefile.in (data.o, fns.o): Add termhooks.h dependency. * src/keyboard.h (push_device_kboard, pop_frame_kboard): Remove declarations. (push_kboard, pop_kboard, temporarily_switch_to_single_kboard) (record_single_kboard_state): New declarations. git-archimport-id: lorentey@elte.hu--2004/emacs--multi-tty--0--patch-414 diff -r 35ba943c8399 -r 0b75ace4f7ad README.multi-tty --- a/README.multi-tty Sun Sep 11 04:10:45 2005 +0000 +++ b/README.multi-tty Sun Sep 11 06:42:03 2005 +0000 @@ -31,27 +31,28 @@ contributed to the project by testing, submitting patches, bug reports, and suggestions. Thanks! -ARISAWA Akihiro -Vincent Bernat -Han Boetes -Robert J. Chassell -Romain Francoise -Ami Fischman -Friedrich Delgado Friedrichs -IRIE Tetsuya -Yoshiaki Kasahara -Bas Kok -Jurej Kubelka -David Lichteblau -Xavier Mallard -Istvan Marko -Ted Morse -Dan Nicolaescu -Gergely Nagy -Mark Plaksin -Francisco Borges -Frank Ruell -Dan Waber +ARISAWA Akihiro +Vincent Bernat +Han Boetes +Robert J. Chassell +Romain Francoise +Ami Fischman +Friedrich Delgado Friedrichs +IRIE Tetsuya +Yoshiaki Kasahara +Bas Kok +Jurej Kubelka +David Lichteblau +Xavier Mallard +Istvan Marko +Ted Morse +Gergely Nagy +Dan Nicolaescu +Kalle Olavi Niemitalo +Mark Plaksin +Francisco Borges +Frank Ruell +Dan Waber and many others. Richard Stallman was kind enough to review an earlier version of my @@ -387,17 +388,8 @@ THINGS TO DO ------------ -** This long-standing bug (first reported by Han Boetes) seems to come - and go all the time. It is time to track it down and fix it. - - emacs - M-x server-start - - # From another xterm: - emacsclient -e '(y-or-n-p "Do you want me to crash? ")' - # Notice how the answer ends up in the *scratch* buffer - M-x garbage-collect - SIGSEGV +** Report GTK multi-display problems to GTK maintainers. For extra + credit, fix them. ** frames-on-display-list should also accept frames. @@ -1239,5 +1231,19 @@ (I think patch-370 fixed this.) +-- This long-standing bug (first reported by Han Boetes) seems to come + and go all the time. It is time to track it down and fix it. + + emacs + M-x server-start + + # From another xterm: + emacsclient -e '(y-or-n-p "Do you want me to crash? ")' + # Notice how the answer ends up in the *scratch* buffer + M-x garbage-collect + SIGSEGV + + (Fixed in patch-414 after detailed analysis by Kalle Olavi Niemitalo.) + ;;; arch-tag: 8da1619e-2e79-41a8-9ac9-a0485daad17d diff -r 35ba943c8399 -r 0b75ace4f7ad src/Makefile.in --- a/src/Makefile.in Sun Sep 11 04:10:45 2005 +0000 +++ b/src/Makefile.in Sun Sep 11 06:42:03 2005 +0000 @@ -1213,13 +1213,13 @@ blockinput.h atimer.h systime.h charset.h dispextern.h $(config_h) $(INTERVAL_SRC) bytecode.o: bytecode.c buffer.h syntax.h charset.h window.h dispextern.h \ frame.h xterm.h $(config_h) -data.o: data.c buffer.h puresize.h charset.h syssignal.h keyboard.h frame.h $(config_h) +data.o: data.c buffer.h puresize.h charset.h syssignal.h keyboard.h frame.h termhooks.h $(config_h) eval.o: eval.c commands.h keyboard.h blockinput.h atimer.h systime.h \ dispextern.h $(config_h) floatfns.o: floatfns.c $(config_h) fns.o: fns.c commands.h $(config_h) frame.h buffer.h charset.h keyboard.h \ keymap.h frame.h window.h dispextern.h $(INTERVAL_SRC) coding.h md5.h \ - blockinput.h xterm.h + blockinput.h xterm.h termhooks.h print.o: print.c process.h frame.h window.h buffer.h keyboard.h charset.h \ $(config_h) dispextern.h termchar.h $(INTERVAL_SRC) msdos.h composite.h \ termchar.h diff -r 35ba943c8399 -r 0b75ace4f7ad src/callint.c --- a/src/callint.c Sun Sep 11 04:10:45 2005 +0000 +++ b/src/callint.c Sun Sep 11 06:42:03 2005 +0000 @@ -408,8 +408,8 @@ real_this_command= save_real_this_command; current_kboard->Vlast_command = save_last_command; - single_kboard_state (); - return apply1 (function, specs); + temporarily_switch_to_single_kboard (NULL); + return unbind_to (speccount, apply1 (function, specs)); } /* Here if function specifies a string to control parsing the defaults */ @@ -875,7 +875,7 @@ real_this_command= save_real_this_command; current_kboard->Vlast_command = save_last_command; - single_kboard_state (); + temporarily_switch_to_single_kboard (NULL); { Lisp_Object val; diff -r 35ba943c8399 -r 0b75ace4f7ad src/data.c --- a/src/data.c Sun Sep 11 04:10:45 2005 +0000 +++ b/src/data.c Sun Sep 11 06:42:03 2005 +0000 @@ -30,6 +30,7 @@ #include "keyboard.h" #include "frame.h" #include "syssignal.h" +#include "termhooks.h" /* For FRAME_KBOARD reference in y-or-n-p. */ #ifdef STDC_HEADERS #include @@ -1891,9 +1892,9 @@ { Lisp_Object result; struct device *d = get_device (device, 1); - push_device_kboard (d); + push_kboard (d->kboard); result = Fsymbol_value (symbol); - pop_frame_kboard (); + pop_kboard (); return result; } @@ -1911,9 +1912,9 @@ { Lisp_Object result; struct device *d = get_device (device, 1); - push_device_kboard (d); + push_kboard (d->kboard); result = Fset (symbol, value); - pop_frame_kboard (); + pop_kboard (); return result; } diff -r 35ba943c8399 -r 0b75ace4f7ad src/fns.c --- a/src/fns.c Sun Sep 11 04:10:45 2005 +0000 +++ b/src/fns.c Sun Sep 11 06:42:03 2005 +0000 @@ -48,6 +48,7 @@ #include "frame.h" #include "window.h" #include "blockinput.h" +#include "termhooks.h" /* For display->kboard reference in terminal-local-value. */ #if defined (HAVE_MENUS) && defined (HAVE_X_WINDOWS) #include "xterm.h" #endif @@ -3307,7 +3308,9 @@ Fraise_frame (mini_frame); } + temporarily_switch_to_single_kboard (FRAME_KBOARD (SELECTED_FRAME ())); obj = read_filtered_event (1, 0, 0, 0); + cursor_in_echo_area = 0; /* If we need to quit, quit with cursor_in_echo_area = 0. */ QUIT; diff -r 35ba943c8399 -r 0b75ace4f7ad src/keyboard.c --- a/src/keyboard.c Sun Sep 11 04:10:45 2005 +0000 +++ b/src/keyboard.c Sun Sep 11 06:42:03 2005 +0000 @@ -1034,24 +1034,19 @@ like it is done in the splash screen display, we have to make sure that we restore single_kboard as command_loop_1 would have done if it were left normally. */ - record_unwind_protect (recursive_edit_unwind, - Fcons (buffer, single_kboard ? Qt : Qnil)); + temporarily_switch_to_single_kboard (FRAME_KBOARD (SELECTED_FRAME ())); + record_unwind_protect (recursive_edit_unwind, buffer); recursive_edit_1 (); return unbind_to (count, Qnil); } Lisp_Object -recursive_edit_unwind (info) - Lisp_Object info; -{ - if (BUFFERP (XCAR (info))) - Fset_buffer (XCAR (info)); - - if (NILP (XCDR (info))) - any_kboard_state (); - else - single_kboard_state (); +recursive_edit_unwind (buffer) + Lisp_Object buffer; +{ + if (BUFFERP (buffer)) + Fset_buffer (buffer); command_loop_level--; update_mode_lines = 1; @@ -1116,8 +1111,8 @@ static struct kboard_stack *kboard_stack; void -push_device_kboard (d) - struct device *d; +push_kboard (k) + struct kboard *k; { #ifdef MULTI_KBOARD struct kboard_stack *p @@ -1127,7 +1122,7 @@ p->kboard = current_kboard; kboard_stack = p; - current_kboard = d->kboard; + current_kboard = k; #endif } @@ -1135,20 +1130,11 @@ push_frame_kboard (f) FRAME_PTR f; { -#ifdef MULTI_KBOARD - struct kboard_stack *p - = (struct kboard_stack *) xmalloc (sizeof (struct kboard_stack)); - - p->next = kboard_stack; - p->kboard = current_kboard; - kboard_stack = p; - - current_kboard = FRAME_KBOARD (f); -#endif + push_kboard (f->device->kboard); } void -pop_frame_kboard () +pop_kboard () { #ifdef MULTI_KBOARD struct kboard_stack *p = kboard_stack; @@ -1157,6 +1143,46 @@ xfree (p); #endif } + +/* Switch to single_kboard mode. If K is non-nil, set it as the + current keyboard. Use record_unwind_protect to return to the + previous state later. */ + +void +temporarily_switch_to_single_kboard (k) + struct kboard *k; +{ +#ifdef MULTI_KBOARD + int was_locked = single_kboard; + if (k != NULL) + push_kboard (k); + else + push_kboard (current_kboard); + single_kboard_state (); + record_unwind_protect (restore_kboard_configuration, + (was_locked ? Qt : Qnil)); +#endif +} + +void +record_single_kboard_state () +{ + push_kboard (current_kboard); + record_unwind_protect (restore_kboard_configuration, + (single_kboard ? Qt : Qnil)); +} + +static Lisp_Object +restore_kboard_configuration (was_locked) + Lisp_Object was_locked; +{ + pop_kboard (); + if (NILP (was_locked)) + any_kboard_state (); + else + single_kboard_state (); + return Qnil; +} /* Handle errors that are not handled at inner levels by printing an error message and returning to the editor command loop. */ @@ -4472,10 +4498,13 @@ { if (NILP (vector[0])) { - int was_locked = single_kboard; int count = SPECPDL_INDEX (); Lisp_Object old_deactivate_mark = Vdeactivate_mark; + /* On unbind_to, resume allowing input from any kboard, if that + was true before. */ + record_single_kboard_state (); + /* Mark the timer as triggered to prevent problems if the lisp code fails to reschedule it right. */ vector[0] = Qt; @@ -4487,10 +4516,6 @@ timers_run++; unbind_to (count, Qnil); - /* Resume allowing input from any kboard, if that was true before. */ - if (!was_locked) - any_kboard_state (); - /* Since we have handled the event, we don't need to tell the caller to wake up and do it. */ } diff -r 35ba943c8399 -r 0b75ace4f7ad src/keyboard.h --- a/src/keyboard.h Sun Sep 11 04:10:45 2005 +0000 +++ b/src/keyboard.h Sun Sep 11 06:42:03 2005 +0000 @@ -319,9 +319,11 @@ extern void delete_kboard P_ ((KBOARD *)); extern void single_kboard_state P_ ((void)); extern void not_single_kboard_state P_ ((KBOARD *)); -extern void push_device_kboard P_ ((struct device *)); +extern void push_kboard P_ ((struct kboard *)); extern void push_frame_kboard P_ ((struct frame *)); -extern void pop_frame_kboard P_ ((void)); +extern void pop_kboard P_ ((void)); +extern void temporarily_switch_to_single_kboard P_ ((struct kboard *)); +extern void record_single_kboard_state P_ ((void)); extern void record_asynch_buffer_change P_ ((void)); extern SIGTYPE input_poll_signal P_ ((int)); extern void start_polling P_ ((void)); diff -r 35ba943c8399 -r 0b75ace4f7ad src/minibuf.c --- a/src/minibuf.c Sun Sep 11 04:10:45 2005 +0000 +++ b/src/minibuf.c Sun Sep 11 06:42:03 2005 +0000 @@ -467,7 +467,6 @@ specbind (Qminibuffer_default, defalt); - single_kboard_state (); #ifdef HAVE_X_WINDOWS if (display_hourglass_p) cancel_hourglass (); @@ -551,6 +550,8 @@ if (minibuffer_auto_raise) Fraise_frame (mini_frame); + temporarily_switch_to_single_kboard (XFRAME (mini_frame)->device->kboard); + /* We have to do this after saving the window configuration since that is what restores the current buffer. */ diff -r 35ba943c8399 -r 0b75ace4f7ad src/xdisp.c --- a/src/xdisp.c Sun Sep 11 04:10:45 2005 +0000 +++ b/src/xdisp.c Sun Sep 11 06:42:03 2005 +0000 @@ -15888,7 +15888,7 @@ values. */ push_frame_kboard (it.f); display_mode_element (&it, 0, 0, 0, format, Qnil, 0); - pop_frame_kboard (); + pop_kboard (); unbind_to (count, Qnil); @@ -16551,7 +16551,7 @@ push_frame_kboard (it.f); display_mode_element (&it, 0, 0, 0, format, Qnil, 0); - pop_frame_kboard (); + pop_kboard (); if (no_props) {