File Coverage

blib/lib/SigAction/SetCallBack.pm
Criterion Covered Total %
statement 50 62 80.6
branch 6 14 42.8
condition 1 3 33.3
subroutine 12 14 85.7
pod 2 2 100.0
total 71 95 74.7


line stmt bran cond sub pod time code
1             package SigAction::SetCallBack;
2              
3 1     1   64589 use strict;
  1         2  
  1         38  
4 1     1   6 use warnings;
  1         1  
  1         52  
5              
6             our $VERSION = '0.01';
7              
8 1     1   1507 use POSIX qw();
  1         9968  
  1         64  
9            
10             # sa_mask manager
11             $SigAction::SetCallBack::SA_MASK = 'SA_NODEFER';
12             sub set_sa_mask {
13 0     0 1 0 my ($class,$new_sa_mask) = @_;
14 0         0 my $change = 0;
15 1     1   9 no strict 'refs';
  1         3  
  1         74  
16 0 0       0 if (defined "POSIX::${new_sa_mask}") {
17 0         0 $SigAction::SetCallBack::SA_MASK = $new_sa_mask;
18 0         0 $change++;
19             }
20 1     1   5 use strict 'refs';
  1         1  
  1         190  
21 0         0 $change;
22             }
23              
24             # stack callbacks storage
25             my $sig_action_table = {};
26            
27             # registry callback for signal
28             sub sig_registry {
29 2     2 1 15 my ($class,$sig,$func) = @_;
30 2 50 33     13 return 0 unless ($sig and $func);
31 2         7 my ($package) = caller;
32 2 50       7 if (ref $func ne 'CODE') {
33             # only exists method for callback
34 2 50       21 return 0 unless $package->can($func);
35 1     1   5 no strict 'refs';
  1         2  
  1         70  
36 2         3 $func = \&{$package.'::'.$func};
  2         8  
37 1     1   5 use strict 'refs';
  1         2  
  1         68  
38             };
39            
40 2         5 ($sig = uc($sig)) =~ s/^SIG//;
41 2         3 my $bad_sig = 0;
42 1     1   5 no strict 'refs';
  1         1  
  1         36  
43 2 50       18 $bad_sig++ unless defined "POSIX::SIG$sig"->();
44 1     1   5 use strict 'refs';
  1         2  
  1         48  
45 2 50       5 return 0 if $bad_sig;
46            
47 2 50       5 unless (exists $sig_action_table->{$sig}) {
48 1     1   9 no strict 'refs';
  1         2  
  1         76  
49 2         38 my $action = POSIX::SigAction->new(
50             \&_sigaction,
51             POSIX::SigSet->new(),
52             "POSIX::${SigAction::SetCallBack::SA_MASK}"->()
53             );
54 2         95 POSIX::sigaction("POSIX::SIG$sig"->(), $action);
55 1     1   4 use strict 'refs';
  1         2  
  1         154  
56             }
57            
58 2         3 push @{$sig_action_table->{$sig}->{$package}},$func;
  2         9  
59            
60 2         12 return 1;
61             }
62              
63             # action for any signal
64             sub _sigaction {
65 0     0     my ($sig) = @_;
66 0           foreach my $pckg (keys %{$sig_action_table->{$sig}}) {
  0            
67 0           map {
68 0           $_->($pckg);
69 0           } @{$sig_action_table->{$sig}->{$pckg}}
70             };
71             }
72              
73             1;
74             __END__