File Coverage

blib/lib/Stat/lsMode.pm
Criterion Covered Total %
statement 30 53 56.6
branch 9 40 22.5
condition n/a
subroutine 7 9 77.7
pod 2 4 50.0
total 48 106 45.2


line stmt bran cond sub pod time code
1 1     1   443 use strict; use warnings;
  1     1   2  
  1         25  
  1         4  
  1         1  
  1         38  
2              
3             package Stat::lsMode;
4             our $VERSION = '0.51';
5              
6 1     1   4 use Carp;
  1         2  
  1         95  
7 1     1   6 BEGIN { require Exporter; *import = \&Exporter::import }
  1         644  
8             our @EXPORT = qw(format_mode file_mode format_perms);
9              
10             our (@perms, @ftype);
11             @perms = qw(--- --x -w- -wx r-- r-x rw- rwx);
12             @ftype = qw(. p c ? d ? b ? - ? l ? s D ? ?);
13             $ftype[0] = '';
14              
15             our $NOVICE_MODE = 1; # Default on?
16             sub novice {
17 0     0 0 0 my $pack = shift;
18 0 0       0 croak "novice_mode requires one boolean argument" unless @_ == 1;
19 0         0 my $old = $NOVICE_MODE; # Should this be localized t $pack?
20 0         0 $NOVICE_MODE = $_[0];
21 0         0 $old;
22             }
23              
24             sub format_mode {
25 14 50   14 1 176 croak "format_mode requires a mode as an argument" unless @_ >= 1;
26 14         19 my $mode = shift;
27 14         16 my %opts = @_;
28              
29 14 50       22 unless (defined $mode) {
30 0 0       0 return wantarray() ? () : undef;
31             }
32              
33 14 50       29 _novice_warning($mode) if $NOVICE_MODE;
34              
35 14         20 my $setids = ($mode & 07000)>>9;
36 14         34 my @permstrs = @perms[($mode&0700)>>6, ($mode&0070)>>3, $mode&0007];
37 14         18 my $ftype = $ftype[($mode & 0170000)>>12];
38 14 50       23 my @ftype = $opts{no_ftype} ? () : ($ftype);
39              
40 14 50       21 if ($setids) {
41 0 0       0 if ($setids & 01) { # Sticky bit
42 0 0       0 $permstrs[2] =~ s/([-x])$/$1 eq 'x' ? 't' : 'T'/e;
  0         0  
43             }
44 0 0       0 if ($setids & 04) { # Setuid bit
45 0 0       0 $permstrs[0] =~ s/([-x])$/$1 eq 'x' ? 's' : 'S'/e;
  0         0  
46             }
47 0 0       0 if ($setids & 02) { # Setgid bit
48 0 0       0 $permstrs[1] =~ s/([-x])$/$1 eq 'x' ? 's' : 'S'/e;
  0         0  
49             }
50             }
51              
52 14 50       20 if (wantarray) {
53 0         0 (@ftype, @permstrs);
54             } else {
55 14         50 join '', @ftype, @permstrs;
56             }
57             }
58              
59             sub file_mode {
60 6 50   6 1 548 croak "file_mode requires one filename as an argument" unless @_ == 1;
61 6         10 my $file = shift;
62 6         60 my $mode = (lstat $file)[2];
63              
64 6 50       21 unless (defined $mode) {
65 0 0       0 if (wantarray) {
66 0         0 return ();
67             } else {
68 0 0       0 carp "Couldn't get mode for file `$file': $!" if $NOVICE_MODE;
69 0         0 return undef;
70             }
71             }
72              
73 6         13 format_mode($mode, @_);
74             }
75              
76             sub format_perms {
77 0 0   0 0 0 croak "format_perms requires a permission mode as an argument" unless @_ == 1;
78 0         0 format_mode($_[0], no_ftype => 1);
79             }
80              
81             # None of these are really plausible modes.
82             # They are all almost certain to have occurred
83             # when someone used decimal instead of octal to specify a mode.
84              
85             my %badmode = map +($_ => 1), (
86             777, 775, 755, 770, 700, 750,
87             751,
88             666, 664, 644, 660, 600, 640,
89             444, 440,
90             400, # 400 = rw--w---- which is just barely plausible.
91             # 000 *is* OK. It means just what you think.
92             711, 771, 751, 551, 111,
93             );
94              
95             # Novices like to ask for the bits for mode `666' instead of `0666'.
96             # Try to detect and diagnose that.
97             sub _novice_warning {
98 14     14   18 my $mode = shift;
99 14 50       29 if ($badmode{$mode}) {
100 0           carp "mode $mode is very surprising. Perhaps you meant 0$mode";
101             }
102             }
103              
104             1;
105              
106             __END__