File Coverage

blib/lib/Proc/WaitStat.pm
Criterion Covered Total %
statement 37 41 90.2
branch 13 20 65.0
condition 2 3 66.6
subroutine 11 11 100.0
pod 4 4 100.0
total 67 79 84.8


line stmt bran cond sub pod time code
1             # $Id: WaitStat.pm,v 1.3 1999-10-21 12:39:43-04 roderick Exp $
2             #
3             # Copyright (c) 1997 Roderick Schertler. All rights reserved. This
4             # program is free software; you can redistribute it and/or modify it
5             # under the same terms as Perl itself.
6              
7             =head1 NAME
8              
9             Proc::WaitStat - Interpret and act on wait() status values
10              
11             =head1 SYNOPSIS
12              
13             $description = waitstat $?;
14             exit waitstat_reuse $?;
15             waitstat_die $?, 'program-name';
16             close_die COMMAND, 'program-name';
17              
18             =head1 DESCRIPTION
19              
20             This module contains functions for interpreting and acting on wait
21             status values.
22              
23             Nothing is exported by default.
24              
25             =over
26              
27             =cut
28              
29             package Proc::WaitStat;
30              
31 1     1   691 use 5.003_98; # piped close errno resetting
  1         3  
  1         38  
32 1     1   4 use strict;
  1         2  
  1         30  
33 1     1   5 use vars qw($VERSION @ISA @EXPORT_OK);
  1         4  
  1         75  
34              
35 1     1   4 use Carp qw(croak);
  1         2  
  1         53  
36 1     1   4 use Exporter ();
  1         1  
  1         25  
37 1     1   780 use IPC::Signal qw(sig_name);
  1         661  
  1         58  
38 1     1   926 use POSIX qw(:sys_wait_h);
  1         8193  
  1         7  
39              
40             $VERSION = '1.00';
41             @ISA = qw(Exporter);
42             @EXPORT_OK = qw(waitstat waitstat_reuse waitstat_die close_die);
43              
44             =item B I
45              
46             Returns a string representation of wait() status value I.
47             Values returned are like C<"0"> and C<"64"> and C<"killed (SIGHUP)">.
48              
49             This function is prototyped to take a single scalar argument.
50              
51             =cut
52              
53             sub waitstat ($) {
54 7     7 1 8215 my $status = shift;
55              
56 7 100       37 if (WIFEXITED $status) {
    50          
    0          
57 5         414 WEXITSTATUS $status
58             }
59             elsif (WIFSIGNALED $status) {
60             # XXX WCOREDUMP
61 2         10 'killed (SIG' . sig_name(WTERMSIG $status) . ')'
62             }
63             elsif (WIFSTOPPED $status) {
64 0         0 'stopped (SIG' . sig_name(WSTOPSIG $status) . ')'
65             }
66             # XXX WIFCONTINUED
67             else {
68 0         0 "invalid wait status $status"
69             }
70             }
71              
72             =item B I
73              
74             Turn I into a value which can be passed to B, converted
75             in the same manner the shell uses. If I indicates a normal
76             exit, return the exit value. If I instead indicates death by
77             signal, return 128 plus the signal number.
78              
79             This function is prototyped to take a single scalar argument.
80              
81             =cut
82              
83             sub waitstat_reuse ($) {
84 5     5 1 73 my $status = shift;
85              
86 5 100       19 if (WIFEXITED $status) {
    50          
    0          
87 4         9 WEXITSTATUS $status
88             }
89             elsif (WIFSIGNALED $status) {
90 1         4 128 + WTERMSIG $status
91             }
92             elsif (WIFSTOPPED $status) {
93 0         0 128 + WSTOPSIG $status
94             }
95             else {
96 0         0 croak "Invalid wait status $status";
97             }
98             }
99              
100             =item B I I
101              
102             die() if I is non-zero (mentioning I as the
103             source of the error).
104              
105             This function is prototyped to take two scalar arguments.
106              
107             =cut
108              
109             sub waitstat_die ($$) {
110 2     2 1 32 my ($status, $program) = @_;
111 2 100       9 croak "Non-zero exit (" . waitstat($status) .
112             ") from $program"
113             if $status;
114             }
115              
116             =item B I I
117              
118             Close I, if that fails die() with an appropriate message
119             which refers to I. This handles failed closings of both programs
120             and files properly.
121              
122             This function is prototyped to take a filehandle (actually, a glob ref)
123             and a scalar.
124              
125             =cut
126              
127             sub close_die (*$) {
128 2     2 1 9610 my ($fh, $name) = @_;
129              
130 2 100 66     66 unless (ref $fh || ref \$fh eq 'GLOB') {
131 1         1223 require Symbol;
132 1         1052 $fh = Symbol::qualify_to_ref($fh, caller);
133             }
134              
135 2 100       420 unless (close $fh) {
136 1 50       71 croak "Error closing $name: ",
137             $!+0 ? "$!" : 'non-zero exit (' . waitstat($?) . ')';
138             }
139             }
140              
141             1
142              
143             __END__