Someone asked me this question offline and directed my attention here, so I thought I would post a reply here too. This exact problem came up in Julia’s base test/runtests.jl driver script. I’ve extracted the relevant code, and modified it some for clarity. Modify this to meet your needs, if this is applicable to you.
The key pieces are:
raw!
– tells the OS to send the ^C keypresses synchronously instead of interrupting the currently running task with a signal
user_close_function
– whatever you want it to be
using REPL
...
monitor = @async begin
term = REPL.Terminals.TTYTerminal("xterm", stdin, stdout, stderr)
try
REPL.Terminals.raw!(term, true)
while !eof(term)
c = read(term, Char)
if c == '\x3' # ^C
print("^C\n")
break
elseif c == '\x4' # ^D
break
else
Base.escape_string(stdout, string(c))
end
end
finally
REPL.Terminals.raw!(term, false)
end
user_close_function()
end
...
wait(monitor)