From 9eed830f296dab257759f5276d0963467007aa6b Mon Sep 17 00:00:00 2001 From: "B. Watson" Date: Thu, 26 Dec 2024 17:08:34 -0500 Subject: initial commit --- trap_stdin.pl | 114 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 114 insertions(+) create mode 100644 trap_stdin.pl (limited to 'trap_stdin.pl') diff --git a/trap_stdin.pl b/trap_stdin.pl new file mode 100644 index 0000000..61e5c8e --- /dev/null +++ b/trap_stdin.pl @@ -0,0 +1,114 @@ +#!/usr/bin/perl -w + +package TrapStdin; + +sub TIEHANDLE { + my $class = shift; + my $fh; + bless \$fh, $class +} + +sub READLINE { + my (undef, $file, $line) = caller; + warn "Irssi scripts can't read from STDIN or ARGV at $file line $line.\n"; + return undef; +} + +sub READ { + goto &READLINE; +} + +package main; + +tie *TRAP, 'TrapStdin'; +*ARGV = *STDIN = *TRAP; + +#### rest of this file is documentation. the doc is a lot longer than +#### the code, sorry about that. + +=pod + +=encoding utf8 + +=head1 NAME + +trap_stdin.pl - catch attempts to read from standard input in an irssi perl script. + +=head1 SYNOPSIS + +# from shell: + + cp trap_stdin.pl ~/.irssi/scripts/autorun/ + +# if irssi was already running, load manually: + + /script load trap_stdin + +=head1 DESCRIPTION + +This script is intended for script developers. + +The Perl scripting interface to irssi doesn't support reading from +B (or from B via the BE> operator). Attempts +to do so cause irssi to freeze: it stops responding to either +the keyboard or incoming IRC traffic. Eventually, the IRC server +will disconnect the client, since it's no longer responding to +PING messages, but the user will have to kill the client manually +(e.g. using C from another terminal), and probably also have to +blindly type C to fix the terminal afterwards. + +The problem is, the script is trying to read from the terminal, but +the terminal has already been "taken over" by irssi itself. The read +blocks, waiting for input it will never receive. + +It's easy to avoid this: just don't try to read from standard input in +your scripts. Problem solved? Well, it would be, but... + +The author of this script has an unfortunate tendency to forget the +filehandle when using BE>. Example: + + open my $fh, "<", $filename; + my $content = <>; + +The second line was I to be: + + my $content = <$fh>; + +...but due to PEBKAC, the C<$fh> was left out (passive voice sucks: +I screwed up and left it out). Attempting to run the broken code +causes irssi to lock up, with no indication what the problem is. +Although the code is wrong, the penalty for this trivial mistake is +harsh. + +With B loaded, the erroneous code will instead cause a +warning, and irssi will continue executing normally. The warning looks +like: + + Irssi scripts can't read from STDIN or ARGV at *FILE* line *LINE*. + +=head1 NOTES + +All loaded scripts are affected by this. It shouldn't have any effect +on scripts that already work correctly, since they already don't try +to read from standard input (or else they wouldn't work correctly). + +B doesn't actually B. It also doesn't stay +isolated to its own package namespace: it works by reassigning the +global C<*STDIN> and C<*ARGV> globs to a tied filehandle. + +Unlike a normal irssi script, the changes made by this one will stay +active even if the script is unloaded. + +If we didn't care about getting an irssi-specific warning, the script +could have just been: + + undef *ARGV; + undef *STDIN; + +=head1 AUTHOR + +B. Watson (urchlay@slackware.uk), aka Urchlay on Libera. + +=head1 LICENSE + +Licensed under the WTFPL. See http://www.wtfpl.net/txt/copying/ for details. -- cgit v1.2.3