Home | History | Annotate | Line # | Download | only in gdb.base
      1 #   Copyright 1988-2025 Free Software Foundation, Inc.
      2 
      3 # This program is free software; you can redistribute it and/or modify
      4 # it under the terms of the GNU General Public License as published by
      5 # the Free Software Foundation; either version 3 of the License, or
      6 # (at your option) any later version.
      7 #
      8 # This program is distributed in the hope that it will be useful,
      9 # but WITHOUT ANY WARRANTY; without even the implied warranty of
     10 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     11 # GNU General Public License for more details.
     12 #
     13 # You should have received a copy of the GNU General Public License
     14 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
     15 
     16 # Test that GDB saves and restores terminal settings correctly.  Also check
     17 # the output of the "info terminal" command.
     18 
     19 if { [prepare_for_testing "failed to prepare" term term.c] } {
     20     return -1
     21 }
     22 
     23 # Once before running the program.
     24 gdb_test "info terminal" \
     25     "No saved terminal information.*" \
     26     "test info terminal pre-execution"
     27 
     28 if {![runto break_here]} {
     29     return 0
     30 }
     31 
     32 # Read the inferior's terminal settings, saved in the T global variable.
     33 
     34 proc read_term_settings_from_inferior {} {
     35     set termios(c_iflag) [get_hexadecimal_valueof "t.c_iflag" oops]
     36     set termios(c_oflag) [get_hexadecimal_valueof "t.c_oflag" oops]
     37     set termios(c_cflag) [get_hexadecimal_valueof "t.c_cflag" oops]
     38     set termios(c_lflag) [get_hexadecimal_valueof "t.c_lflag" oops]
     39 
     40     return [array get termios]
     41 }
     42 
     43 # Validate that gdb's notion of the inferior's terminal settings are consistent
     44 # with the values read from the inferior.
     45 
     46 proc compare_gdb_and_inferior_settings { t } {
     47     global decimal
     48     array set termios $t
     49 
     50     gdb_test "info terminal" \
     51     [multi_line "Inferior's terminal status .currently saved by GDB.:" \
     52                 "File descriptor flags = .*" \
     53                 "Process group = $decimal" \
     54                 "c_iflag = ${termios(c_iflag)}, c_oflag = ${termios(c_oflag)}," \
     55                 "c_cflag = ${termios(c_cflag)}, c_lflag = ${termios(c_lflag)}.*" ]
     56 }
     57 
     58 if {[target_info gdb_protocol] == ""} {
     59     # Record the initial terminal settings.  Verify that GDB's version of the
     60     # inferior's terminal settings is right.
     61     with_test_prefix "initial" {
     62         array set termios1 [read_term_settings_from_inferior]
     63         compare_gdb_and_inferior_settings [array get termios1]
     64     }
     65 
     66     # Continue until after the inferior removes ECHO from its terminal settings.
     67     gdb_continue_to_breakpoint "continue until after tcsetattr"
     68 
     69     # After the inferior has changed its terminal settings, check that GDB's
     70     # saved version reflects the new settings correctly.
     71     with_test_prefix "post tcsetattr" {
     72         array set termios2 [read_term_settings_from_inferior]
     73         compare_gdb_and_inferior_settings [array get termios2]
     74 
     75         # Make sure that the current settings are different than the initial
     76         # settings... otherwise this test is meaningless.
     77         gdb_assert {${termios1(c_lflag)} != ${termios2(c_lflag)}}
     78     }
     79 
     80     # Continue again...
     81     gdb_continue_to_breakpoint "continue again"
     82 
     83     # ... and verify again, to validate that when resuming, GDB restored the
     84     # inferior's terminal settings correctly.
     85     with_test_prefix "after last resume" {
     86         array set termios3 [read_term_settings_from_inferior]
     87         compare_gdb_and_inferior_settings [array get termios3]
     88         gdb_assert {${termios2(c_iflag)} == ${termios3(c_iflag)}}
     89         gdb_assert {${termios2(c_oflag)} == ${termios3(c_oflag)}}
     90         gdb_assert {${termios2(c_cflag)} == ${termios3(c_cflag)}}
     91         gdb_assert {${termios2(c_lflag)} == ${termios3(c_lflag)}}
     92     }
     93 } else {
     94     # While only native targets save terminal status, we still test
     95     # that the command doesn't misbehave.
     96     gdb_test "info terminal" "No saved terminal information\\." "info terminal at breakpoint"
     97 }
     98 
     99 delete_breakpoints
    100 gdb_continue_to_end
    101 
    102 # One last time after the program having exited.
    103 gdb_test "info terminal" \
    104     "No saved terminal information.*" \
    105     "test info terminal post-execution"
    106