# Copyright 1994-2021 Free Software Foundation, Inc.

# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.

if [target_info exists gdb,nointerrupts] {
    verbose "Skipping interrupt.exp because of nointerrupts."
    continue
}

if [target_info exists gdb,noinferiorio] {
    verbose "Skipping interrupt.exp because of noinferiorio."
    return
}

standard_testfile

set options { debug }
if { ! [target_info exists gdb,nosignals] } {
    lappend options "additional_flags=-DSIGNALS"
}

if {[build_executable $testfile.exp $testfile $srcfile $options] == -1} {
    untested "failed to compile"
    return -1
}

gdb_start


if ![file exists $binfile] then {
    perror "$binfile does not exist."
    return 0
} else {
    gdb_reinitialize_dir $srcdir/$subdir
    gdb_load $binfile
    # Hope this is unix :-)
    gdb_test "shell stty intr '^C'" ".*" \
	"set interrupt character in interrupt.exp"
    if [runto_main] then {
	global inferior_spawn_id gdb_spawn_id

	set msg "process is alive"
	gdb_test_multiple "continue" $msg {
	    -i "$inferior_spawn_id" -re "talk to me baby\r\n" {
		pass $msg
	    }
	}

	# This should appear twice, once for the echo and once for the
	# program's output.

	set msg "child process ate our char"
	send_inferior "a\n"
	gdb_test_multiple "" $msg {
	    -i "$inferior_spawn_id" -re "^a\r\na\r\n$" {
		pass $msg
	    }
	}

	# Wait until the program is in the read system call again.
	sleep 2

	# Cntrl-c may fail for simulator targets running on a BSD host.
	# This is the result of a combination of the read syscall
	# being restarted and gdb capturing the cntrl-c signal.

	# Cntrl-c may fail for simulator targets on slow hosts.
	# This is because there is a race condition between entering
	# the read and delivering the cntrl-c.

	send_gdb "\003"
	set msg "send_gdb control C"
	gdb_test_multiple "" $msg {
	    -re "Program received signal SIGINT.*$gdb_prompt $" {
		pass $msg
	    }
	}

	set msg "call function when asleep"
	send_gdb "p func1 ()\n"
	gdb_test_multiple "" $msg {
	    -re " = 4.*$gdb_prompt $" {
		pass $msg
	    }
	    -re ".*Program received signal SIG(SEGV|ILL).*$gdb_prompt $" {
		setup_xfail "i*86-pc-linux*-gnu*"
		fail "child died when we called func1, skipped rest of tests"
		return
	    }
	    -re "$gdb_prompt $" {
		fail "call function when asleep (wrong output)"
	    }
	    default {

		# This fail probably happens whenever we use /proc (we
		# don't use PRSABORT), but apparently also happens on
		# other machines as well.

		setup_xfail "sparc*-*-solaris2*"
		setup_xfail "i*86-*-solaris2*"
		setup_xfail "*-*-sysv4*"
		setup_xfail "vax-*-*"
		setup_xfail "alpha-*-*"
		setup_xfail "*-*-*bsd*"
		setup_xfail "*-*-*lynx*"
		fail "$msg (stays asleep)"
		# Send the inferior a newline to wake it up.
		send_inferior "\n"
		gdb_test "" " = 4" "call function after waking it"
	    }
	}

	# Now try calling the function again.
	gdb_test "p func1 ()" " = 4" "call function a second time"

	# And the program should still be doing the same thing.
	# The optional trailing \r\n is in case we sent a newline above
	# to wake the program, in which case the program now sends it
	# back.  We check for it either here or in the next gdb_expect
	# command, because which one it ends up in is timing dependent.
	send_gdb "continue\n"
	# For some reason, i386-*-sysv4 gdb fails to issue the Continuing
	# message, but otherwise appears normal (FIXME).

	set msg "continue"
	gdb_test_multiple "" "$msg" {
	    -re "^continue\r\nContinuing.\r\n(\r\n|)$" {
		pass $msg
	    }
	    -re "^continue\r\n\r\n" {
		fail "$msg (missing Continuing.)"
	    }
	}

	send_inferior "data\n"
	# The optional leading \r\n is in case we sent a newline above
	# to wake the program, in which case the program now sends it
	# back.

	set msg "echo data"
	gdb_test_multiple "" $msg {
	    -i "$inferior_spawn_id" -re "^(\r\n|)data\r\ndata\r\n$" {
		pass $msg
	    }
	    -i "$gdb_spawn_id" -re "Undefined command.*$gdb_prompt " {
		fail $msg
	    }
	}

 	if { ! [target_info exists gdb,nosignals] } {
	    # Wait until the program is in the read system call again.
	    sleep 2

	    # Stop the program for another test.
	    set msg "Send Control-C, second time"
	    send_gdb "\003"
	    gdb_test_multiple "" "$msg" {
		-re "Program received signal SIGINT.*$gdb_prompt $" {
		    pass "$msg"
		}
	    }

	    # The "signal" command should deliver the correct signal and
	    # return to the loop.
	    set msg "signal SIGINT"
	    gdb_test_multiple "signal SIGINT" "$msg" {
		-re "^signal SIGINT\r\nContinuing with signal SIGINT.\r\n(\r\n|)$" {
		    pass "$msg"
		}
	    }

	    # We should be back in the loop.
	    send_inferior "more data\n"

	    set msg "echo more data"
	    gdb_test_multiple "" $msg {
		-i "$inferior_spawn_id" -re "^(\r\n|)more data\r\nmore data\r\n$" {
		    pass $msg
		}
	    }
	}

	set saw_end_of_file 0
	set saw_inferior_exit 0

	set msg "send end of file"
	send_inferior "\004"

	set spawn_list "$inferior_spawn_id"

	gdb_test_multiple "" $msg {
	    -i spawn_list -re "end of file" {
		set saw_end_of_file 1
		verbose -log "saw \"end of file\""
		if {!$saw_inferior_exit} {
		    # When $inferior_spawn_id != $gdb_spawn_id, such
		    # as when testing with gdbserver, we may see the
		    # eof (the process exit, not the string just
		    # matched) for $inferior_spawn_id before the
		    # expected gdb output.  Clear this so we no longer
		    # expect anything out of $inferior_spawn_id.
		    set spawn_list ""
		    exp_continue
		}
	    }
	    -i "$gdb_spawn_id" -re "$inferior_exited_re normally.*$gdb_prompt " {
		set saw_inferior_exit 1
		verbose -log "saw inferior exit"
		if {!$saw_end_of_file} {
		    exp_continue
		}
	    }
	}

	gdb_assert { $saw_end_of_file && $saw_inferior_exit } $msg
    }
}
return 0
