diff options
author | B. Watson <urchlay@slackware.uk> | 2024-12-26 17:08:34 -0500 |
---|---|---|
committer | B. Watson <urchlay@slackware.uk> | 2024-12-26 17:08:34 -0500 |
commit | 9eed830f296dab257759f5276d0963467007aa6b (patch) | |
tree | 83d6225d248ec8d4026b514d8b9b248e6c0fce32 /trap_stdin.pl | |
download | stupid-irssi-tricks-9eed830f296dab257759f5276d0963467007aa6b.tar.gz |
initial commit
Diffstat (limited to 'trap_stdin.pl')
-rw-r--r-- | trap_stdin.pl | 114 |
1 files changed, 114 insertions, 0 deletions
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<STDIN> (or from B<ARGV> via the B<E<lt>E<gt>> 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<kill> from another terminal), and probably also have to +blindly type C<reset> 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 B<E<lt>E<gt>>. Example: + + open my $fh, "<", $filename; + my $content = <>; + +The second line was I<intended> to be: + + my $content = <$fh>; + +...but due to PEBKAC, the C<$fh> was left out (passive voice sucks: +I<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<trap_stdin.pl> 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<trap_stdin.pl> doesn't actually B<use Irssi>. 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. |