0: # 1: # First of a three part post of modules that implement 2: # an extension of Perl's built-in alarm functionality. 3: # 4: # See [Alarm::Queued] and [Alarm::Concurrent] 5: # for the other two parts. 6: # 7: # Props to [tye] for explaining what I needed to know 8: # to get this to work. 9: # 10: package Alarm::_TieSIG; 11: 12: =head1 NAME 13: 14: Alarm::_TieSIG - Module handling tying of %SIG for alarm extensions. 15: 16: =head1 DESCRIPTION 17: 18: This is an internal utility module for use with the Alarm::* 19: alarm extensions, that handles tying of the Perl built-in 20: variable C<%SIG>. This is deep magic and you use this module 21: at your own risk. 22: 23: To use this class, simply C<use> it and then call the 24: C<Alarm::_TieSIG::tiesig()> function. This replaces C<%SIG> with a dummy tied hash. 25: 26: Whenever the new C<%SIG> is accessed, this class checks to see 27: if the requested key is ALRM. If so, it calls C<sethandler()> 28: for STORE's, and C<gethandler()> for FETCHes. You must provide 29: both of these methods in your package. 30: 31: All other operations are passed on to the original, magic C<%SIG>. 32: 33: Note: Do I<not> call C<tiesig()> more than once. Doing so 34: produces a warning and no other effects. 35: 36: =head1 EXAMPLE 37: 38: The following code will disable, with warnings, attempts to 39: set SIGALRM handlers in your program (although it's not 40: impossible to get past if someone really wanted to): 41: 42: use Alarm::_TieSIG; 43: Alarm::_TieSIG::tiesig(); 44: 45: sub sethandler { 46: warn "\$SIG{ALRM} has been disabled.\n"; 47: } 48: 49: sub gethandler { 50: warn "\$SIG{ALRM} has been disabled.\n"; 51: } 52: 53: =head1 DISCLAIMER 54: 55: This module is not guaranteed to work. In fact, it will probably 56: break at the most inconvient time. If this module breaks your 57: program, destroys your computer, ruins your life, or otherwise 58: makes you unhappy, do I<not> complain (especially not to me). 59: It's your own fault. 60: 61: =head1 AUTHOR 62: 63: Written by Cory Johns (c) 2001. 64: 65: =cut 66: 67: use strict; 68: use Carp; 69: 70: use vars qw($realSig); 71: 72: sub tiesig { 73: if($realSig) { 74: carp "Attempt to re-tie %SIG"; 75: return; 76: } 77: 78: $realSig = \%SIG; # Save old %SIG. 79: *SIG = {}; # Replace %SIG with a dummy. 80: 81: my $userPkg = caller; 82: return tie %SIG, __PACKAGE__, $userPkg, @_; 83: } 84: 85: sub _setAlrm { 86: $realSig->{ALRM} = shift; 87: } 88: 89: sub TIEHASH { 90: return bless {'userPkg'=>$_[1]}, shift; 91: } 92: 93: sub STORE { 94: my ($self, $key, $value) = @_; 95: 96: if($key eq 'ALRM') { 97: no strict 'refs'; 98: &{"$self->{userPkg}::sethandler"}($value); 99: } else { 100: $realSig->{$key} = $value; 101: } 102: } 103: 104: sub FETCH { 105: my ($self, $key) = @_; 106: 107: if($key eq 'ALRM') { 108: no strict 'refs'; 109: &{"$self->{userPkg}::gethandler"}(); 110: } else { 111: return $realSig->{$key}; 112: } 113: } 114: 115: sub EXISTS { 116: return exists $realSig->{$_[1]}; 117: } 118: 119: sub DELETE { 120: return delete $realSig->{$_[1]}; 121: } 122: 123: sub CLEAR { 124: return %$realSig = (); 125: } 126: 127: sub FIRSTKEY { 128: return each %$realSig; 129: } 130: 131: sub NEXTKEY { 132: return each %$realSig; 133: } 134: 135: sub DESTROY { 136: } 137: 138: 1;
In reply to Alarm::_TieSIG by bbfu
For: | Use: | ||
& | & | ||
< | < | ||
> | > | ||
[ | [ | ||
] | ] |