aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorKaroly Lorentey <[email protected]>2005-09-11 06:42:03 +0000
committerKaroly Lorentey <[email protected]>2005-09-11 06:42:03 +0000
commit256c9c3a61a5a2c5d394277f5b0f25adb453771d (patch)
tree897024a7092e469356b80c07dae3dbeb045d7e7c /src
parentee0bcfbce6e8f7055f483976a68b33a2bdd46d14 (diff)
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: [email protected]/emacs--multi-tty--0--patch-414
Diffstat (limited to 'src')
-rw-r--r--src/Makefile.in4
-rw-r--r--src/callint.c6
-rw-r--r--src/data.c9
-rw-r--r--src/fns.c3
-rw-r--r--src/keyboard.c85
-rw-r--r--src/keyboard.h6
-rw-r--r--src/minibuf.c3
-rw-r--r--src/xdisp.c4
8 files changed, 76 insertions, 44 deletions
diff --git a/src/Makefile.in b/src/Makefile.in
index 2e4b4f6ad7..fdeeb544b1 100644
--- a/src/Makefile.in
+++ b/src/Makefile.in
@@ -1213,13 +1213,13 @@ alloc.o: alloc.c process.h frame.h window.h buffer.h puresize.h syssignal.h key
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 --git a/src/callint.c b/src/callint.c
index 5979e495ac..d44d2f20ca 100644
--- a/src/callint.c
+++ b/src/callint.c
@@ -408,8 +408,8 @@ If KEYS is omitted or nil, the return value of `this-command-keys' is used. */)
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 @@ If KEYS is omitted or nil, the return value of `this-command-keys' is used. */)
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 --git a/src/data.c b/src/data.c
index b187a3e748..b024511d77 100644
--- a/src/data.c
+++ b/src/data.c
@@ -30,6 +30,7 @@ Boston, MA 02110-1301, USA. */
#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 <float.h>
@@ -1891,9 +1892,9 @@ selected frame's display device). */)
{
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 @@ selected frame's display device). */)
{
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 --git a/src/fns.c b/src/fns.c
index 987762a1f4..2e2e575911 100644
--- a/src/fns.c
+++ b/src/fns.c
@@ -48,6 +48,7 @@ Boston, MA 02110-1301, USA. */
#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 @@ is nil and `use-dialog-box' is non-nil. */)
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 --git a/src/keyboard.c b/src/keyboard.c
index 74f8d7d51e..14dd4e33c8 100644
--- a/src/keyboard.c
+++ b/src/keyboard.c
@@ -1034,24 +1034,19 @@ This function is called by the editor initialization to begin editing. */)
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;
+recursive_edit_unwind (buffer)
+ Lisp_Object buffer;
{
- if (BUFFERP (XCAR (info)))
- Fset_buffer (XCAR (info));
-
- if (NILP (XCDR (info)))
- any_kboard_state ();
- else
- single_kboard_state ();
+ if (BUFFERP (buffer))
+ Fset_buffer (buffer);
command_loop_level--;
update_mode_lines = 1;
@@ -1116,8 +1111,8 @@ struct kboard_stack
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 @@ push_device_kboard (d)
p->kboard = current_kboard;
kboard_stack = p;
- current_kboard = d->kboard;
+ current_kboard = k;
#endif
}
@@ -1135,20 +1130,11 @@ void
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 @@ pop_frame_kboard ()
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 @@ timer_check (do_it_now)
{
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 @@ timer_check (do_it_now)
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 --git a/src/keyboard.h b/src/keyboard.h
index 0063922787..690cb9cb17 100644
--- a/src/keyboard.h
+++ b/src/keyboard.h
@@ -319,9 +319,11 @@ extern void init_kboard P_ ((KBOARD *));
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 --git a/src/minibuf.c b/src/minibuf.c
index 8f07a4603c..a66d0f8f5c 100644
--- a/src/minibuf.c
+++ b/src/minibuf.c
@@ -467,7 +467,6 @@ read_minibuf (map, initial, prompt, backup_n, expflag,
specbind (Qminibuffer_default, defalt);
- single_kboard_state ();
#ifdef HAVE_X_WINDOWS
if (display_hourglass_p)
cancel_hourglass ();
@@ -551,6 +550,8 @@ read_minibuf (map, initial, prompt, backup_n, expflag,
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 --git a/src/xdisp.c b/src/xdisp.c
index bc016fb7c7..c8ca187f3d 100644
--- a/src/xdisp.c
+++ b/src/xdisp.c
@@ -15888,7 +15888,7 @@ display_mode_line (w, face_id, format)
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 @@ are the selected window and the window's buffer). */)
push_frame_kboard (it.f);
display_mode_element (&it, 0, 0, 0, format, Qnil, 0);
- pop_frame_kboard ();
+ pop_kboard ();
if (no_props)
{