diff options
author | Pedro Alves <palves@redhat.com> | 2014-10-17 13:31:25 +0100 |
---|---|---|
committer | Pedro Alves <palves@redhat.com> | 2014-10-17 13:31:25 +0100 |
commit | 5842f62aad5c20dbb3511208efbc40a8d638b6d3 (patch) | |
tree | 913c379ec3d1e4b50bd7c21916ba2af98574f707 /gdb/target.c | |
parent | 3f7308212cefe5cd958b29e0b9e92d92c4dbe941 (diff) | |
download | gdb-5842f62aad5c20dbb3511208efbc40a8d638b6d3.zip gdb-5842f62aad5c20dbb3511208efbc40a8d638b6d3.tar.gz gdb-5842f62aad5c20dbb3511208efbc40a8d638b6d3.tar.bz2 |
Make common code handle target_terminal_* idempotency
I found a place that should be giving back the terminal to the target,
but only if the target was already owning it. So I need to add a
getter for who owns the terminal.
The trouble is that several places/target have their own globals to
track this state:
- inflow.c:terminal_is_ours
- remote.c:remote_async_terminal_ours_p
- linux-nat.c:async_terminal_is_ours
- go32-nat.c:terminal_is_ours
While one might think of adding a new target_ops method to query this,
conceptually, this state isn't really part of a particular target_ops.
Considering multi-target, the core shouldn't have to ask all targets
to know whether it's GDB that owns the terminal. There's only one GDB
(or rather, only one top level interpreter).
So what this comment does is add a new global that is tracked by the
core instead. A subsequent pass may later remove the other globals.
Tested on x86_64 Fedora 20, native and gdbserver.
gdb/
2014-10-17 Pedro Alves <palves@redhat.com>
* target.c (enum terminal_state): New enum.
(terminal_state): New global.
(target_terminal_init): New function.
(target_terminal_inferior): Skip if inferior already owns the
terminal.
(target_terminal_ours, target_terminal_ours_for_output): New
functions.
* target.h (target_terminal_init): Convert to function prototype.
(target_terminal_ours_for_output): Convert to function prototype
and tweak comment.
(target_terminal_ours): Convert to function prototype and tweak
comment.
* windows-nat.c (do_initial_windows_stuff): Call
target_terminal_init instead of child_terminal_init_with_pgrp.
Diffstat (limited to 'gdb/target.c')
-rw-r--r-- | gdb/target.c | 56 |
1 files changed, 56 insertions, 0 deletions
diff --git a/gdb/target.c b/gdb/target.c index fcd877c..7feaa35 100644 --- a/gdb/target.c +++ b/gdb/target.c @@ -432,6 +432,35 @@ target_load (const char *arg, int from_tty) (*current_target.to_load) (¤t_target, arg, from_tty); } +/* Possible terminal states. */ + +enum terminal_state + { + /* The inferior's terminal settings are in effect. */ + terminal_is_inferior = 0, + + /* Some of our terminal settings are in effect, enough to get + proper output. */ + terminal_is_ours_for_output = 1, + + /* Our terminal settings are in effect, for output and input. */ + terminal_is_ours = 2 + }; + +static enum terminal_state terminal_state; + +/* See target.h. */ + +void +target_terminal_init (void) +{ + (*current_target.to_terminal_init) (¤t_target); + + terminal_state = terminal_is_ours; +} + +/* See target.h. */ + void target_terminal_inferior (void) { @@ -442,9 +471,36 @@ target_terminal_inferior (void) if (target_can_async_p () && !sync_execution) return; + if (terminal_state == terminal_is_inferior) + return; + /* If GDB is resuming the inferior in the foreground, install inferior's terminal modes. */ (*current_target.to_terminal_inferior) (¤t_target); + terminal_state = terminal_is_inferior; +} + +/* See target.h. */ + +void +target_terminal_ours (void) +{ + if (terminal_state == terminal_is_ours) + return; + + (*current_target.to_terminal_ours) (¤t_target); + terminal_state = terminal_is_ours; +} + +/* See target.h. */ + +void +target_terminal_ours_for_output (void) +{ + if (terminal_state != terminal_is_inferior) + return; + (*current_target.to_terminal_ours_for_output) (¤t_target); + terminal_state = terminal_is_ours_for_output; } /* See target.h. */ |