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