File Coverage

blib/lib/Sys/Signals/Block.pm
Criterion Covered Total %
statement 52 53 98.1
branch 13 20 65.0
condition n/a
subroutine 11 11 100.0
pod 3 3 100.0
total 79 87 90.8


line stmt bran cond sub pod time code
1             package Sys::Signals::Block;
2              
3 3     3   2813 use 5.008;
  3         11  
  3         122  
4 3     3   17 use strict;
  3         4  
  3         123  
5 3     3   41 use base qw(Class::Accessor::Fast);
  3         6  
  3         2809  
6              
7 3     3   18602 use Carp qw(croak);
  3         8  
  3         237  
8 3     3   998 use POSIX qw(sigprocmask SIG_BLOCK SIG_UNBLOCK);
  3         14510  
  3         29  
9              
10             our $VERSION = '0.10';
11              
12             __PACKAGE__->mk_accessors(qw(sigset is_blocked));
13              
14             # mapping of signame => number
15             my %SigNum = _get_signums();
16              
17             sub import {
18 7     7   2218 my $class = shift;
19              
20 7 100       64 if (@_) {
21 4 50       12 my @sigs = $class->_parse_signals(@_)
22             or croak "no signals listed on import line";
23              
24 4 50       72 my $sigset = POSIX::SigSet->new(@sigs)
25             or croak "Can't create SigSet: $!";
26              
27 4         13 $class->instance->sigset($sigset);
28             }
29             }
30              
31             # convert signal names to numbers
32             sub _get_signums {
33 3     3   23 require Config;
34              
35 3         3672 my @names = split /\s+/, $Config::Config{sig_name};
36 3         10496 my @nums = split /[\s,]+/, $Config::Config{sig_num};
37              
38 3         319 my %sigs;
39 3         155 @sigs{@names} = @nums;
40              
41 3         200 return %sigs;
42             }
43              
44             sub _parse_signals {
45 4     4   11 my ($class, @signals) = @_;
46              
47 4         8 my @nums;
48              
49 4         9 for my $signal (@signals) {
50 8 100       30 unless ($signal =~ /\D/) {
51 4         9 push @nums, $signal;
52             }
53             else {
54 4         12 $signal =~ s/^SIG//;
55 4         7 my $num = $SigNum{$signal};
56 4 50       11 unless (defined $num) {
57 0         0 croak "invalid signal name: 'SIG${signal}'";
58             }
59              
60 4         11 push @nums, $num;
61             }
62             }
63              
64 4         23 return @nums;
65             }
66              
67             my $Instance;
68              
69             sub instance {
70 7     7 1 401 my $class = shift;
71              
72 7 100       23 unless ( defined $Instance ) {
73 2         26 $Instance = $class->new({ is_blocked => 0 });
74             }
75              
76 7         45 return $Instance;
77             }
78              
79             sub block {
80 1     1 1 61 my $self = shift->instance;
81              
82 1 50       4 return if $self->is_blocked;
83              
84 1         10 my $retval = sigprocmask(SIG_BLOCK, $self->sigset);
85              
86 1 50       16 if ($retval) {
87 1         3 $self->is_blocked(1);
88             }
89              
90 1         7 return $retval;
91             }
92              
93             sub unblock {
94 1     1 1 582 my $self = shift->instance;
95              
96 1 50       4 return unless $self->is_blocked;
97              
98 1         9 my $retval = sigprocmask(SIG_UNBLOCK, $self->sigset);
99              
100 1 50       34 if ($retval) {
101 1         22 $self->is_blocked(0);
102             }
103              
104 1         8 return $retval;
105             }
106              
107             1;
108              
109             __END__