class

TermBuf::Input::Signals

Inherits Reference < Object

What the operating system has to say, on the same queue as the bytes.

A signal handler runs in a fibre of Crystal's own, with the terminal in whatever state the last frame left it and no idea what the application was in the middle of. That is the wrong place to decide anything, so almost nothing is decided there: a delivery is counted, a marker goes on the reader's inbound channel, and the dispatcher turns it into an event in order with everything the terminal had already said.

The exception is leaving. A process being killed is not going to drain a channel, so Mode::Exit runs its hooks — restoring the terminal, above all — in the handler itself, resets the signal, and re-raises it so the process dies of what it was sent rather than of exit.

Signal.trap is process-global. One Signals per process is the shape this expects; a second #install replaces the first's handlers, and #uninstall puts every signal it traps back to the default. Anything installing traps must uninstall them, specs included.

Constants

DEFAULT_MODES = {::Signal::TERM => Mode::Exit, ::Signal::INT => Mode::Exit, ::Signal::HUP => Mode::Exit, ::Signal::WINCH => Mode::Event}

What a signal does when nothing has said otherwise.

The three that mean "stop" restore the terminal on the way out. WINCH is an event because it is not a shutdown at all, and because the application — or, in this shard, the terminal driver — is the only one who knows what to do about a window that changed size.

DEFAULT_THRESHOLD = 2

How many deliveries Mode::WarnThenExit takes before it exits, when nothing has said otherwise.

Constructors

new(inbound : Channel(Reader::Inbound))
Source

Instance methods

before_exit

Registers something to run before the process dies of a signal.

Hooks run in the order they were registered, in the signal handler itself, and each is rescued: one that raises does not stop the ones after it, which is the whole point of a stack of them. This shard registers the terminal's restore.

Source
count(signal : Signal) : Int32

How many of signal have been delivered since the count was last cleared.

Source
install

Traps every signal that has a mode or a hook.

Source
installed?

Whether the handlers are installed.

Source
mode(signal : Signal, mode : Mode) : Mode

Says what signal should do when it arrives.

A signal named here is trapped, now if the handlers are already installed and by #install if they are not. Crystal has no setter taking two arguments, so this is signals.mode Signal::INT, Mode::WarnThenExit rather than an assignment.

Source
mode(signal : Signal) : Mode

What signal does when it arrives.

Source
on(signal : Signal, &hook : -> ) : Nil

Registers a handler for signal that runs instead of the modes.

For the signals whose answer is neither an event nor an exit — TSTP gives the terminal back and stops, CONT takes it again and redraws. The hook runs in the signal handler, and the trap is put back afterwards, so a hook that resets its own signal to raise it at the default handler still has a trap when the process comes back.

Source
reset

Puts every signal this traps back to the default.

Process-global state is being handed back, so anything that installs has to get here however it ends.

Source
reset_count(signal : Signal) : Nil

Forgets how many of signal have arrived.

Repeats need not be contiguous: input arriving between two interrupts does not clear the count, because a person pressing the key twice with a keystroke in between still means it. An application that treats one press as answered — it put up a confirmation and the person dismissed it — says so here.

Source
terminate

The last thing Mode::Exit does, once every #before_exit hook has run: reset the signal and send it again, so the process dies of what it was sent rather than of exit.

Replaceable so that a spec can watch an exit happen without being killed by it. Nothing else has a reason to.

Source
terminate=(terminate : Proc(Signal, Nil))

The last thing Mode::Exit does, once every #before_exit hook has run: reset the signal and send it again, so the process dies of what it was sent rather than of exit.

Replaceable so that a spec can watch an exit happen without being killed by it. Nothing else has a reason to.

Source
threshold(signal : Signal, deliveries : Int32) : Int32

Sets how many deliveries of signal Mode::WarnThenExit waits for.

Source
threshold(signal : Signal) : Int32

How many deliveries of signal Mode::WarnThenExit waits for.

Source
uninstall

Puts every signal this traps back to the default.

Process-global state is being handed back, so anything that installs has to get here however it ends.

Source

Nested types