175584Sru# Copyright 1994-2023 Free Software Foundation, Inc.
2151497Sru
3151497Sru# This program is free software; you can redistribute it and/or modify
475584Sru# it under the terms of the GNU General Public License as published by
5114402Sru# the Free Software Foundation; either version 3 of the License, or
675584Sru# (at your option) any later version.
775584Sru#
875584Sru# This program is distributed in the hope that it will be useful,
975584Sru# but WITHOUT ANY WARRANTY; without even the implied warranty of
1075584Sru# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
1175584Sru# GNU General Public License for more details.
1275584Sru#
1375584Sru# You should have received a copy of the GNU General Public License
1475584Sru# along with this program.  If not, see <http://www.gnu.org/licenses/>.
1575584Sru
1675584Sruif [target_info exists gdb,nointerrupts] {
1775584Sru    verbose "Skipping interrupt.exp because of nointerrupts."
1875584Sru    return
1975584Sru}
2075584Sru
2175584Sruif [target_info exists gdb,noinferiorio] {
2275584Sru    verbose "Skipping interrupt.exp because of noinferiorio."
2375584Sru    return
2475584Sru}
2575584Sru
2675584Srustandard_testfile
27151497Sru
2875584Sruset options { debug }
2975584Sruif { ! [target_info exists gdb,nosignals] } {
30104862Sru    lappend options "additional_flags=-DSIGNALS"
3175584Sru}
32151497Sru
33151497Sruif {[build_executable $testfile.exp $testfile $srcfile $options] == -1} {
3475584Sru    untested "failed to compile"
3575584Sru    return -1
3675584Sru}
3775584Sru
3875584Srugdb_start
39104862Sru
40104862Sru
4175584Sruif {![file exists $binfile]} {
4275584Sru    return 0
4375584Sru} else {
44104862Sru    gdb_reinitialize_dir $srcdir/$subdir
4575584Sru    gdb_load $binfile
46104862Sru    # Hope this is unix :-)
47104862Sru    gdb_test "shell stty intr '^C'" ".*" \
4875584Sru	"set interrupt character"
4975584Sru    if {[runto_main]} {
5075584Sru	global inferior_spawn_id gdb_spawn_id
5175584Sru
5275584Sru	set msg "process is alive"
53114402Sru	gdb_test_multiple "continue" $msg {
5475584Sru	    -i "$inferior_spawn_id" -re "talk to me baby\r\n" {
5575584Sru		pass $msg
5675584Sru	    }
5775584Sru	}
5875584Sru
59104862Sru	# This should appear twice, once for the echo and once for the
60104862Sru	# program's output.
61104862Sru
62104862Sru	set msg "child process ate our char"
63104862Sru	send_inferior "a\n"
64104862Sru	gdb_test_multiple "" $msg {
65104862Sru	    -i "$inferior_spawn_id" -re "^a\r\na\r\n$" {
66104862Sru		pass $msg
67104862Sru	    }
68104862Sru	}
69104862Sru
70151497Sru	# Wait until the program is in the read system call again.
71104862Sru	sleep 2
72151497Sru
73151497Sru	# Cntrl-c may fail for simulator targets running on a BSD host.
74104862Sru	# This is the result of a combination of the read syscall
75104862Sru	# being restarted and gdb capturing the cntrl-c signal.
76104862Sru
77104862Sru	# Cntrl-c may fail for simulator targets on slow hosts.
78104862Sru	# This is because there is a race condition between entering
79104862Sru	# the read and delivering the cntrl-c.
80104862Sru
81104862Sru	send_gdb "\003"
82104862Sru	set msg "send_gdb control C"
83104862Sru	gdb_test_multiple "" $msg {
84104862Sru	    -re "Program received signal SIGINT.*$gdb_prompt $" {
85104862Sru		pass $msg
86104862Sru	    }
87104862Sru	}
88104862Sru
89104862Sru	set msg "call function when asleep"
90104862Sru	send_gdb "p func1 ()\n"
91104862Sru	gdb_test_multiple "" $msg {
92104862Sru	    -re " = 4.*$gdb_prompt $" {
93104862Sru		pass $msg
94151497Sru	    }
95104862Sru	    -re ".*Program received signal SIG(SEGV|ILL).*$gdb_prompt $" {
96104862Sru		setup_xfail "i*86-pc-linux*-gnu*"
97151497Sru		fail "child died when we called func1, skipped rest of tests"
98104862Sru		return
99104862Sru	    }
100104862Sru	    -re "$gdb_prompt $" {
101151497Sru		fail "call function when asleep (wrong output)"
102151497Sru	    }
10375584Sru	    default {
10475584Sru
10575584Sru		# This fail probably happens whenever we use /proc (we
10675584Sru		# don't use PRSABORT), but apparently also happens on
10775584Sru		# other machines as well.
108104862Sru
109104862Sru		setup_xfail "sparc*-*-solaris2*"
110104862Sru		setup_xfail "i*86-*-solaris2*"
111104862Sru		setup_xfail "*-*-sysv4*"
112104862Sru		setup_xfail "vax-*-*"
113104862Sru		setup_xfail "alpha-*-*"
114104862Sru		setup_xfail "*-*-*bsd*"
11575584Sru		setup_xfail "*-*-*lynx*"
116104862Sru		fail "$msg (stays asleep)"
117104862Sru		# Send the inferior a newline to wake it up.
118104862Sru		send_inferior "\n"
119151497Sru		gdb_test "" " = 4" "call function after waking it"
120104862Sru	    }
121104862Sru	}
122104862Sru
123104862Sru	# Now try calling the function again.
124104862Sru	gdb_test "p func1 ()" " = 4" "call function a second time"
125104862Sru
126104862Sru	# And the program should still be doing the same thing.
127151497Sru	# The optional trailing \r\n is in case we sent a newline above
128104862Sru	# to wake the program, in which case the program now sends it
129104862Sru	# back.  We check for it either here or in the next gdb_expect
130104862Sru	# command, because which one it ends up in is timing dependent.
131104862Sru	send_gdb "continue\n"
132104862Sru	# For some reason, i386-*-sysv4 gdb fails to issue the Continuing
13375584Sru	# message, but otherwise appears normal (FIXME).
134
135	set msg "continue"
136	gdb_test_multiple "" "$msg" {
137	    -re "^continue\r\nContinuing.\r\n(\r\n|)$" {
138		pass $msg
139	    }
140	    -re "^continue\r\n\r\n" {
141		fail "$msg (missing Continuing.)"
142	    }
143	}
144
145	send_inferior "data\n"
146	# The optional leading \r\n is in case we sent a newline above
147	# to wake the program, in which case the program now sends it
148	# back.
149
150	set msg "echo data"
151	gdb_test_multiple "" $msg {
152	    -i "$inferior_spawn_id" -re "^(\r\n|)data\r\ndata\r\n$" {
153		pass $msg
154	    }
155	    -i "$gdb_spawn_id" -re "Undefined command.*$gdb_prompt " {
156		fail $msg
157	    }
158	}
159
160 	if { ! [target_info exists gdb,nosignals] } {
161	    # Wait until the program is in the read system call again.
162	    sleep 2
163
164	    # Stop the program for another test.
165	    set msg "Send Control-C, second time"
166	    send_gdb "\003"
167	    gdb_test_multiple "" "$msg" {
168		-re "Program received signal SIGINT.*$gdb_prompt $" {
169		    pass "$msg"
170		}
171	    }
172
173	    # The "signal" command should deliver the correct signal and
174	    # return to the loop.
175	    set msg "signal SIGINT"
176	    gdb_test_multiple "signal SIGINT" "$msg" {
177		-re "^signal SIGINT\r\nContinuing with signal SIGINT.\r\n(\r\n|)$" {
178		    pass "$msg"
179		}
180	    }
181
182	    # We should be back in the loop.
183	    send_inferior "more data\n"
184
185	    set msg "echo more data"
186	    gdb_test_multiple "" $msg {
187		-i "$inferior_spawn_id" -re "^(\r\n|)more data\r\nmore data\r\n$" {
188		    pass $msg
189		}
190	    }
191	}
192
193	set saw_end_of_file 0
194	set saw_inferior_exit 0
195
196	set msg "send end of file"
197	send_inferior "\004"
198
199	set spawn_list "$inferior_spawn_id"
200
201	gdb_test_multiple "" $msg {
202	    -i spawn_list -re "end of file" {
203		set saw_end_of_file 1
204		verbose -log "saw \"end of file\""
205		if {!$saw_inferior_exit} {
206		    # When $inferior_spawn_id != $gdb_spawn_id, such
207		    # as when testing with gdbserver, we may see the
208		    # eof (the process exit, not the string just
209		    # matched) for $inferior_spawn_id before the
210		    # expected gdb output.  Clear this so we no longer
211		    # expect anything out of $inferior_spawn_id.
212		    set spawn_list ""
213		    exp_continue
214		}
215	    }
216	    -i "$gdb_spawn_id" -re "$inferior_exited_re normally.*$gdb_prompt " {
217		set saw_inferior_exit 1
218		verbose -log "saw inferior exit"
219		if {!$saw_end_of_file} {
220		    exp_continue
221		}
222	    }
223	}
224
225	gdb_assert { $saw_end_of_file && $saw_inferior_exit } $msg
226    }
227}
228return 0
229