показывает то, что процессу должен быть передан сигнал alrm по истечении промежутка времени $seconds. Результат, возвращаемый функцией, представляет собой число секунд, оставшихся после предыдущей установки таймера. Это значение не равно нулю, если ожидание было прервано. Значение параметра, равное нулю, отменяет установку таймера.
Недостатком этого кода является то, что интерпретатор Perl автоматически перезапускает продолжительные системные вызовы, включая оператор <>. Даже по истечении времени, установленного функцией alarm, вызов <> продолжает выполняться, ожидая ввода данных пользователем с клавиатуры. Решение этой проблемы состоит в использовании оператора eval{} и локального обработчика ALRM для отмены операции чтения. Ниже показан общий принцип реализации этого решения.
print STDERR "type your passwotd: "; my $password = eval { local $SIG{ALRM} = sub { die "timeout" }; alarm (5); return ; } alarm (0); print STDERR "you timed out" if $@ =~ /timeout/;
Вместо размещения обработчика ALRM в главной части программы, он локализуется в блоке eval {}. Блок eval {}, как и прежде, предусматривает установку выдержки времени функции alarm, после чего выполняется попытка чтения из дескриптора файла STDIN. Если оператор <> выполняет возврат до истечения выдержки времени, то из блока eval {} возвращается строка ввода и присваивается переменной $password.
Однако если установленный период времени истекает до выполнения ввода, активизируется обработчик ALRM и вызывает аварийное завершение работы с сообщением об ошибке “timeout”. Поскольку аварийное завершение происходит внутри блока eval {}, в результате оператор eval {} просто возвращает значение undef и устанавливает значение переменной $@ равным последнему сообщению об ошибке. Выполняется сопоставление переменной $@ с образцом для поиска сообщения о таймауте и, в случае его обнаружения, выводится предупреждающее сообщение.