File Coverage

blib/lib/Signal/Unsafe.pm
Criterion Covered Total %
statement 37 74 50.0
branch 1 12 8.3
condition n/a
subroutine 12 23 52.1
pod 0 1 0.0
total 50 110 45.4


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