File Coverage

blib/lib/Proc/Exists.pm
Criterion Covered Total %
statement 24 24 100.0
branch 10 10 100.0
condition 7 7 100.0
subroutine 6 6 100.0
pod n/a
total 47 47 100.0


line stmt bran cond sub pod time code
1             package Proc::Exists;
2              
3 2     2   58469 use strict;
  2         4  
  2         100  
4 2     2   4026 use Proc::Exists::Configuration;
  2         176  
  2         409  
5 2     2   11 use vars qw (@ISA @EXPORT_OK $VERSION);
  2         4  
  2         182  
6             eval { require warnings; }; #it's ok if we can't load warnings
7              
8             require Exporter;
9 2     2   11 use base 'Exporter';
  2         3  
  2         2053  
10             @EXPORT_OK = qw( pexists );
11             @ISA = qw( Exporter );
12              
13             $VERSION = '1.01';
14              
15             my $use_pureperl = $Proc::Exists::Configuration::want_pureperl;
16             if(!$use_pureperl) {
17             eval {
18             require XSLoader;
19             XSLoader::load('Proc::Exists', $VERSION);
20             $Proc::Exists::_loader = 'XSLoader';
21             1;
22             } or eval {
23             require DynaLoader;
24             push @ISA, 'DynaLoader';
25             bootstrap Proc::Exists $VERSION;
26             $Proc::Exists::_loader = 'DynaLoader';
27             1;
28             } or do {
29             #NOTE: don't need to worry about i18n, DynaLoader complains in english.
30             # (and XSLoader passes thru DynaLoader's complaints)
31             if($@ =~ /Proc::Exists\s+object\s+version\s+\S+\s+does\s+not\s+match\s+bootstrap\s+parameter/ ) {
32             warn "WARNING: it looks like you have a previous Proc::Exists ".
33             "version's object file(s) somewhere in \@INC! you will have ".
34             "to remove these and reinstall Proc::Exists. for now, we are ".
35             "falling back to pureperl, expect degraded performance: $@\n";
36             } else {
37             warn "WARNING: can't load XS. falling back to pureperl, ".
38             "expect degraded performance: $@\n";
39             }
40             $use_pureperl = 1;
41             }
42             }
43              
44             if($use_pureperl) {
45             #warn "using pure perl mode, expect degraded performance\n";
46             my $pp_pexists = sub {
47             my @pids = @_;
48             my %args = ref($pids[-1]) ? %{pop(@pids)} : ();
49              
50             die "can't specify both 'any' and 'all' arg" if($args{all} && $args{any});
51             if(wantarray) {
52             die "can't specify 'all' argument in list context" if($args{all});
53             die "can't specify 'any' argument in list context" if($args{any});
54             }
55              
56             my @results;
57             foreach my $pid (@pids) {
58             #ASSUMPTION: no systems allow a negative int as a PID
59             if($pid !~ /^\d+$/) {
60             if($pid =~ /^-\d+$/) {
61             die "got negative pid: '$pid'";
62             } elsif($pid =~ /^-?\d+\./) {
63             die "got non-integer pid: '$pid'";
64             } else {
65             die "got non-number pid: '$pid'";
66             }
67             }
68              
69             my $ret;
70             if (kill 0, $pid) {
71             $ret = 1;
72             } else {
73             if($^O eq "MSWin32") {
74             die "can't do pure perl on MSWin32 - \$!: (".(0+$!)."): $!";
75             }
76 1     1   1155 if($!{EPERM}) {
  1         1854  
  1         450  
77             $ret = 1;
78             } elsif($!{ESRCH}) {
79             $ret = 0;
80             } else {
81             die "unknown numeric \$!: (".(0+$!)."): $!, pureperl, OS: $^O";
82             }
83             }
84              
85             if($ret) {
86             return $pid if($args{any});
87             push @results, $pid;
88             } elsif($args{all}) {
89             return 0;
90             }
91             }
92             #NOTE: as documented in the pod, any returns undef for false,
93             # because some systems use pid==0
94             return if($args{any});
95             return wantarray ? @results : scalar @results;
96             };
97             *pexists = \&$pp_pexists;
98             $Proc::Exists::pureperl = 1;
99              
100             } else {
101              
102             my $xs_pexists = sub {
103 27     27   50156 my @pids = @_;
104 27 100       109 my %args = ref($pids[-1]) ? %{pop(@pids)} : ();
  9         46  
105              
106 27 100       64 if(wantarray) {
107 8 100       36 die "can't specify 'all' argument in list context" if($args{all});
108 7 100       26 die "can't specify 'any' argument in list context" if($args{any});
109 6         183289 return _list_pexists([@pids]);
110             } else {
111 19 100 100     95 die "can't specify both 'any' and 'all' arg" if($args{all} && $args{any});
112 18   100     176842 return _scalar_pexists([@pids], $args{any} || 0, $args{all} || 0);
      100        
113             }
114             };
115             *pexists = \&$xs_pexists;
116             $Proc::Exists::pureperl = 0;
117              
118             }
119              
120             # !wantarray : return number of matches
121             # !wantarray && any : return pid of first match if any match, else undef
122             # !wantarray && all : return a true value if all match, else a false value
123             # wantarray : return list of matching pids
124             # wantarray && any : undefined, makes no sense
125             # ALTERNATELY: could return list of size one with first matching pid,
126             # else bare return
127             # wantarray && all : undefined, makes no sense
128             # ALTERNATELY: could return list of all pids on true, else bare return
129              
130             1;
131             __END__