File Coverage

blib/lib/Signal/Unsafe.pm
Criterion Covered Total %
statement 42 79 53.1
branch 2 14 14.2
condition 1 3 33.3
subroutine 14 25 56.0
pod 0 1 0.0
total 59 122 48.3


line stmt bran cond sub pod time code
1             package Signal::Unsafe;
2             $Signal::Unsafe::VERSION = '0.007';
3 1     1   139342 use strict;
  1         3  
  1         44  
4 1     1   14 use warnings;
  1         2  
  1         63  
5              
6 1     1   5 use XSLoader;
  1         2  
  1         100  
7             XSLoader::load(__PACKAGE__, Signal::Unsafe->VERSION);
8              
9 1     1   8 use Exporter 5.57 'import';
  1         19  
  1         69  
10             our @EXPORT_OK = qw/sigaction/;
11              
12 1     1   7 use Config;
  1         2  
  1         59  
13 1     1   614 use IPC::Signal qw/sig_num sig_name/;
  1         840  
  1         91  
14 1     1   8 use Scalar::Util 'blessed';
  1         2  
  1         52  
15 1     1   7 use List::Util 'reduce';
  1         6  
  1         63  
16 1     1   618 use POSIX ();
  1         10881  
  1         41  
17 1     1   693 use Signal::Info;
  1         934  
  1         68  
18              
19             {
20 1     1   9 no warnings 'once';
  1         2  
  1         1341  
21             tie %Signal::Unsafe, __PACKAGE__;
22             }
23             our $Flags = POSIX::SA_SIGINFO;
24             our $Mask = POSIX::SigSet->new;
25              
26             my $sig_max = $Config{sig_count} - 1;
27              
28             sub TIEHASH {
29 1     1   2 my $class = shift;
30 1         3 my $self = { iterator => 1, };
31 1         5 return bless $self, $class;
32             }
33              
34             sub _get_status {
35 0     0   0 my ($self, $num) = @_;
36 0         0 my $ret = POSIX::SigAction->new;
37 0         0 sigaction($num, undef, $ret);
38 0         0 return [ $ret->handler, $ret->flags, $ret->mask ];
39             }
40              
41             sub FETCH {
42 0     0   0 my ($self, $key) = @_;
43 0         0 return $self->_get_status(sig_num($key));
44             }
45              
46             my %flag_values = (
47             siginfo => POSIX::SA_SIGINFO,
48             nodefer => POSIX::SA_NODEFER,
49             restart => POSIX::SA_RESTART,
50             onstack => POSIX::SA_ONSTACK,
51             resethand => POSIX::SA_RESETHAND,
52             nocldstop => POSIX::SA_NOCLDSTOP,
53             nocldwait => POSIX::SA_NOCLDWAIT,
54             );
55              
56             sub make_action {
57 2     2 0 547 my $value = shift;
58 2 50 33     34 if (blessed($value) && $value->isa('POSIX::SigAction')) {
    50          
59 0         0 return $value;
60             } elsif (ref $value eq 'ARRAY') {
61 0         0 my ($handler, $flags, $mask) = @{$value};
  0         0  
62 0 0       0 $mask = $Mask if not defined $mask;
63 0 0   0   0 $flags = not defined $flags ? $Flags : ref($flags) ne 'ARRAY' ? $flags : reduce { $a | $b } map { $flag_values{$_} } @{$flags};
  0 0       0  
  0         0  
  0         0  
64 0         0 return POSIX::SigAction->new($handler, $mask, $flags);
65             }
66             else {
67 2         18 return POSIX::SigAction->new($value, $Mask, $Flags);
68             }
69             }
70              
71             sub STORE {
72 2     2   194920 my ($self, $key, $value) = @_;
73 2         15 sigaction(sig_num($key), make_action($value));
74 2         90 return;
75             }
76              
77             sub DELETE {
78 0     0     my ($self, $key) = @_;
79 0           my $old = POSIX::SigAction->new("DEFAULT", $Mask, $Flags);
80 0           sigaction(sig_num($key), POSIX::SigAction->new("DEFAULT", $Mask, $Flags), $old);
81 0           return ($old->handler, $old->mask, $old->flags);
82             }
83              
84             sub CLEAR {
85 0     0     my ($self) = @_;
86 0           for my $sig_no (1 .. $sig_max) {
87 0           sigaction($sig_no, POSIX::SigAction->new("DEFAULT", $Mask, $Flags));
88             }
89 0           return;
90             }
91              
92             sub EXISTS {
93 0     0     my ($self, $key) = @_;
94 0           return defined sig_num($key);
95             }
96              
97             sub FIRSTKEY {
98 0     0     my $self = shift;
99 0           $self->{iterator} = 1;
100 0           return $self->NEXTKEY;
101             }
102              
103             sub NEXTKEY {
104 0     0     my $self = shift;
105 0 0         if ($self->{iterator} <= $sig_max) {
106 0           my $num = $self->{iterator}++;
107 0 0         return wantarray ? (sig_name($num) => $self->_get_status($num)) : sig_name($num);
108             }
109             else {
110 0           return;
111             }
112             }
113              
114             sub SCALAR {
115 0     0     return 1;
116             }
117              
118             sub UNTIE {
119 0     0     my $self = shift;
120 0           $self->CLEAR;
121 0           return;
122             }
123              
124       0     sub DESTROY {
125             }
126              
127             1;
128              
129             #ABSTRACT: Unsafe signal handlers made convenient
130              
131             __END__