FuguLib::Signal(3p) Perl Library Manual FuguLib::Signal(3p)

FuguLib::Signalsignal handlers for graceful shutdown

use FuguLib::Signal;

my $sig = FuguLib::Signal->new;
$sig->add_cleanup(sub ($signal) { unlink $tempfile });
$sig->setup_graceful_exit('INT', 'TERM');

# or, to decide when to stop:
$sig->setup_interrupt_flag('INT', 'TERM');
until (FuguLib::Signal::check_interrupted()) {
    do_some_work();
}

FuguLib::Signal installs signal handlers so that a program can be interrupted without leaving temporary files, child processes or half-written state behind.

There are two shapes. () runs the cleanup handlers and exits from inside the signal handler, which suits a program whose work can be abandoned at any point. setup_interrupt_flag() only raises a flag, leaving the program to notice it and stop where stopping is safe.

Either way the previous handlers are remembered and put back by (), which the destructor calls, so a scoped object leaves the process as it found it.

new() creates a signal handler manager. It installs nothing on its own.

setup_graceful_exit(@signals) installs a handler for each named signal that sets the interrupt flag, runs the cleanup handlers, and exits with status 130.

setup_interrupt_flag(@signals) installs a handler for each named signal that sets the interrupt flag and returns. Nothing else happens until the program looks at the flag.

add_cleanup($handler) adds a code reference to be called, with the signal name as its argument, before setup_graceful_exit() exits. Handlers run in the order they were added, each inside an eval, so one that dies does not stop the rest.

restore() puts back the handlers that were in place before this object installed its own.

check_interrupted() reports whether a handled signal has arrived. It is a plain function, not a method.

reset_interrupted() clears the interrupt flag. It is a plain function, not a method.

new() returns a signal handler manager. setup_graceful_exit(), setup_interrupt_flag(), add_cleanup() and restore() return the object, so they chain.

check_interrupted() returns true if a handled signal has arrived.

Stop between items rather than in the middle of one:

my $sig = FuguLib::Signal->new;
$sig->setup_interrupt_flag('INT', 'TERM');

for my $item (@items) {
    last if FuguLib::Signal::check_interrupted();
    process($item);
}

No method dies. A cleanup handler that dies is caught and ignored.

perlipc(1), kill(2), sigaction(2), FuguLib::Process(3p)

Dick Olsson <hi@senzilla.io>

The interrupt flag and the list of cleanup handlers are package globals, not per-object. Two managers in one process share both: a cleanup handler added through one runs for a signal caught by the other, and reset_interrupted() clears the flag for both.

The cleanup list is emptied once it has run, so a second signal after a graceful exit has begun finds nothing left to clean up.

Handlers are ordinary Perl signal handlers and run between opcodes, not immediately. A program blocked in a system call notices the signal when the call returns.

July 27, 2026 OpenBSD