mirror of
git://git.sv.gnu.org/emacs.git
synced 2026-06-14 12:31:25 +00:00
Merge from origin/emacs-31
df2508a8f6Remove from CC Mode code that modifies 'major-mode-remap-...3106dc7766Assert we don't double-free timers (bug#81108)90314895ddDon't cancel random timers in x_get_foreign_selection (bu...5cd7785b0aFix use-after-free in Ffuncall_with_delayed_message (bug#...
This commit is contained in:
commit
8636e39abb
5 changed files with 52 additions and 32 deletions
|
|
@ -3401,22 +3401,6 @@ Key bindings:
|
|||
(insert (format "Buffer Style: %s\nc-emacs-features: %s\n"
|
||||
style c-features)))))))
|
||||
|
||||
|
||||
;; Make entries in `major-mode-remap-defaults' to ensure that when CC
|
||||
;; Mode has been loaded, the symbols `c-mode' etc., will call CC Mode's
|
||||
;; modes rather than c-ts-mode etc..
|
||||
(when (boundp 'major-mode-remap-defaults)
|
||||
(add-to-list 'major-mode-remap-defaults '(c++-mode . c++-ts-mode))
|
||||
(add-to-list 'major-mode-remap-defaults '(c-mode . c-ts-mode))
|
||||
(add-to-list 'major-mode-remap-defaults '(c-or-c++-mode . c-or-c++-ts-mode))
|
||||
(let (entry)
|
||||
(dolist (mode '(c-mode c++-mode c-or-c++-mode))
|
||||
(if (and (setq entry (assq mode major-mode-remap-defaults))
|
||||
(null (cdr entry)))
|
||||
(setq major-mode-remap-defaults
|
||||
(delq entry major-mode-remap-defaults)))
|
||||
(push (cons mode nil) major-mode-remap-defaults))))
|
||||
|
||||
|
||||
(cc-provide 'cc-mode)
|
||||
|
||||
|
|
|
|||
|
|
@ -201,6 +201,9 @@ cancel_atimer (struct atimer *timer)
|
|||
}
|
||||
}
|
||||
|
||||
/* We shouldn't be called with timers which aren't on either list. */
|
||||
eassert (i != 2);
|
||||
|
||||
unblock_atimers (&oldset);
|
||||
}
|
||||
|
||||
|
|
|
|||
35
src/eval.c
35
src/eval.c
|
|
@ -1220,17 +1220,34 @@ usage: (while TEST BODY...) */)
|
|||
return Qnil;
|
||||
}
|
||||
|
||||
struct funcall_with_delayed_message_data
|
||||
{
|
||||
Lisp_Object *message;
|
||||
struct atimer *timer;
|
||||
};
|
||||
|
||||
static void
|
||||
with_delayed_message_display (struct atimer *timer)
|
||||
{
|
||||
message3 (build_string (timer->client_data));
|
||||
struct funcall_with_delayed_message_data *data
|
||||
= timer->client_data;
|
||||
if (data->timer)
|
||||
{
|
||||
message3 (*data->message);
|
||||
data->timer = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
with_delayed_message_cancel (void *timer)
|
||||
with_delayed_message_cancel (void *datap)
|
||||
{
|
||||
xfree (((struct atimer *) timer)->client_data);
|
||||
cancel_atimer (timer);
|
||||
struct funcall_with_delayed_message_data *data
|
||||
= datap;
|
||||
if (data->timer)
|
||||
{
|
||||
cancel_atimer (data->timer);
|
||||
data->timer = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
DEFUN ("funcall-with-delayed-message",
|
||||
|
|
@ -1251,10 +1268,12 @@ is not displayed. */)
|
|||
|
||||
/* Set up the atimer. */
|
||||
struct timespec interval = dtotimespec (XFLOATINT (timeout));
|
||||
struct atimer *timer = start_atimer (ATIMER_RELATIVE, interval,
|
||||
with_delayed_message_display,
|
||||
xstrdup (SSDATA (message)));
|
||||
record_unwind_protect_ptr (with_delayed_message_cancel, timer);
|
||||
struct funcall_with_delayed_message_data data
|
||||
= { .message = &message };
|
||||
data.timer = start_atimer (ATIMER_RELATIVE, interval,
|
||||
with_delayed_message_display,
|
||||
&data);
|
||||
record_unwind_protect_ptr (with_delayed_message_cancel, &data);
|
||||
|
||||
Lisp_Object result = calln (function);
|
||||
|
||||
|
|
|
|||
|
|
@ -981,15 +981,22 @@ static void
|
|||
pgtk_display_selection_waiting_message (struct atimer *timer)
|
||||
{
|
||||
Lisp_Object val;
|
||||
struct atimer **atimerp = timer->client_data;
|
||||
|
||||
val = build_string ("Waiting for reply from selection owner...");
|
||||
message3_nolog (val);
|
||||
*atimerp = NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
pgtk_cancel_atimer (void *atimer)
|
||||
pgtk_cancel_atimer (void *atimerp)
|
||||
{
|
||||
cancel_atimer (atimer);
|
||||
struct atimer **atimer = atimerp;
|
||||
if (*atimer)
|
||||
{
|
||||
cancel_atimer (*atimer);
|
||||
*atimer = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -1044,8 +1051,8 @@ pgtk_get_foreign_selection (Lisp_Object selection_symbol, Lisp_Object target_typ
|
|||
message_interval = make_timespec (1, 0);
|
||||
delayed_message = start_atimer (ATIMER_RELATIVE, message_interval,
|
||||
pgtk_display_selection_waiting_message,
|
||||
NULL);
|
||||
record_unwind_protect_ptr (pgtk_cancel_atimer, delayed_message);
|
||||
&delayed_message);
|
||||
record_unwind_protect_ptr (pgtk_cancel_atimer, &delayed_message);
|
||||
|
||||
/* This allows quits. Also, don't wait forever. */
|
||||
intmax_t timeout = max (0, pgtk_selection_timeout);
|
||||
|
|
|
|||
|
|
@ -1631,15 +1631,22 @@ static void
|
|||
x_display_selection_waiting_message (struct atimer *timer)
|
||||
{
|
||||
Lisp_Object val;
|
||||
struct atimer **atimerp = timer->client_data;
|
||||
|
||||
val = build_string ("Waiting for reply from selection owner...");
|
||||
message3_nolog (val);
|
||||
*atimerp = NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
x_cancel_atimer (void *atimer)
|
||||
x_cancel_atimer (void *atimerp)
|
||||
{
|
||||
cancel_atimer (atimer);
|
||||
struct atimer **atimer = atimerp;
|
||||
if (*atimer)
|
||||
{
|
||||
cancel_atimer (*atimer);
|
||||
*atimer = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -1708,8 +1715,8 @@ x_get_foreign_selection (Lisp_Object selection_symbol, Lisp_Object target_type,
|
|||
message_interval = make_timespec (1, 0);
|
||||
delayed_message = start_atimer (ATIMER_RELATIVE, message_interval,
|
||||
x_display_selection_waiting_message,
|
||||
NULL);
|
||||
record_unwind_protect_ptr (x_cancel_atimer, delayed_message);
|
||||
&delayed_message);
|
||||
record_unwind_protect_ptr (x_cancel_atimer, &delayed_message);
|
||||
|
||||
/* This allows quits. Also, don't wait forever. */
|
||||
intmax_t timeout = max (0, x_selection_timeout);
|
||||
|
|
|
|||
Loading…
Reference in a new issue