diff --git a/gdb/ChangeLog b/gdb/ChangeLog index ad845a7527..4aeb0cc8a9 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,11 @@ +2014-12-10 Simon Marchi + + PR gdb/17627 + * target.c (cleanup_restore_target_terminal): New function. + (make_cleanup_restore_target_terminal): New function. + * target.h (make_cleanup_restore_target_terminal): New declaration. + * mi/mi-interp.c (mi_thread_exit): Use the new cleanup. + 2014-12-08 Doug Evans * python/py-objfile.c (objfpy_get_owner): Increment refcount of result. diff --git a/gdb/mi/mi-interp.c b/gdb/mi/mi-interp.c index df2b558291..60f066660a 100644 --- a/gdb/mi/mi-interp.c +++ b/gdb/mi/mi-interp.c @@ -386,6 +386,7 @@ mi_thread_exit (struct thread_info *t, int silent) { struct mi_interp *mi; struct inferior *inf; + struct cleanup *old_chain; if (silent) return; @@ -393,11 +394,14 @@ mi_thread_exit (struct thread_info *t, int silent) inf = find_inferior_pid (ptid_get_pid (t->ptid)); mi = top_level_interpreter_data (); + old_chain = make_cleanup_restore_target_terminal (); target_terminal_ours (); fprintf_unfiltered (mi->event_channel, "thread-exited,id=\"%d\",group-id=\"i%d\"", t->num, inf->num); gdb_flush (mi->event_channel); + + do_cleanups (old_chain); } /* Emit notification on changing the state of record. */ diff --git a/gdb/target.c b/gdb/target.c index ab5f2b9f36..7161e62acc 100644 --- a/gdb/target.c +++ b/gdb/target.c @@ -528,6 +528,40 @@ target_supports_terminal_ours (void) return 0; } +/* Restore the terminal to its previous state (helper for + make_cleanup_restore_target_terminal). */ + +static void +cleanup_restore_target_terminal (void *arg) +{ + enum terminal_state *previous_state = arg; + + switch (*previous_state) + { + case terminal_is_ours: + target_terminal_ours (); + break; + case terminal_is_ours_for_output: + target_terminal_ours_for_output (); + break; + case terminal_is_inferior: + target_terminal_inferior (); + break; + } +} + +/* See target.h. */ + +struct cleanup * +make_cleanup_restore_target_terminal (void) +{ + enum terminal_state *ts = xmalloc (sizeof (*ts)); + + *ts = terminal_state; + + return make_cleanup_dtor (cleanup_restore_target_terminal, ts, xfree); +} + static void tcomplain (void) { diff --git a/gdb/target.h b/gdb/target.h index d363b61bc3..cff146afc4 100644 --- a/gdb/target.h +++ b/gdb/target.h @@ -1413,6 +1413,10 @@ extern void target_terminal_ours (void); extern int target_supports_terminal_ours (void); +/* Make a cleanup that restores the state of the terminal to the current + state. */ +extern struct cleanup *make_cleanup_restore_target_terminal (void); + /* Print useful information about our terminal status, if such a thing exists. */