File Coverage

blib/lib/File/Open.pm
Criterion Covered Total %
statement 71 71 100.0
branch 70 84 83.3
condition 4 22 18.1
subroutine 19 19 100.0
pod 5 6 83.3
total 169 202 83.6


line stmt bran cond sub pod time code
1             package File::Open;
2              
3 7     7   279554 use strict;
  7         13  
  7         254  
4 7     7   40 use warnings;
  7         14  
  7         400  
5 7 50   7   556 BEGIN { warnings->import(FATAL => 'layer') if $] >= 5.008; }
6              
7             our $VERSION = '1.0102';
8              
9 7     7   54 use File::Basename qw(basename);
  7         13  
  7         668  
10 7     7   44 use Carp qw(croak);
  7         21  
  7         500  
11 7     7   43 use Fcntl ();
  7         10  
  7         136  
12 7     7   2654 use Errno ();
  7         5634  
  7         173  
13 7     7   41 use Exporter (); BEGIN { our @ISA = 'Exporter'; }
  7     7   12  
  7         234  
  7         9037  
14              
15             our @EXPORT_OK = qw(
16             fopen fopen_nothrow
17             fsysopen fsysopen_nothrow
18             fopendir fopendir_nothrow
19             );
20              
21             sub _mode {
22 42     42   51 map { $_ => $_[0] } @_
  84         308  
23             }
24              
25             my %modemap = (
26             _mode(qw[< r ]),
27             _mode(qw[> w ]),
28             _mode(qw[>> a ]),
29             _mode(qw[+< r+]),
30             _mode(qw[+> w+]),
31             _mode(qw[+>> a+]),
32             );
33              
34             sub _open {
35 112     112   228 my ($func, $file, $mode, $layers) = @_;
36 112 100       622 @_ < 2 and croak "Not enough arguments for $func";
37 110 100       558 @_ > 4 and croak "Too many arguments for $func";
38 108 100       218 $mode = '<' if !defined $mode;
39              
40 108         372 my $binary = $mode =~ s/(?<=.)b//;
41 108 100       3701 my $emode = $modemap{$mode} or croak "Unknown $func() mode '$mode'";
42              
43 80 100       177 if ($file =~ /\0/) {
44 2 50       10 $! = Errno::ENOENT() if exists &Errno::ENOENT;
45 2         31 return undef;
46             }
47              
48 78 100       150 unless (defined $layers) {
49             # grab our caller's 'use open' settings
50 76         506 my $hints = (caller 1)[10];
51 76 100       253 my $key = $emode =~ />/ ? 'open>' : 'open<';
52 76         187 $layers = $hints->{$key};
53             }
54              
55 78 100       3664 open my $fh, $emode . (defined $layers ? " $layers" : ''), $file or return undef;
    100          
56 42 100       382 binmode $fh if $binary;
57 42         224 $fh
58             }
59              
60             sub fopen_nothrow {
61 51     51 1 40706 _open('fopen_nothrow', @_)
62             }
63              
64             my $prog = basename $0;
65              
66             sub fopen {
67 61 100   61 1 49482 _open('fopen', @_) || die "$prog: $_[0]: $!\n"
68             }
69              
70             sub _sysopen {
71 84     84   162 my ($func, $file, $mode, $flags) = @_;
72 84 100       654 @_ < 3 and croak "Not enough arguments for $func";
73 80 100       409 @_ > 4 and croak "Too many arguments for $func";
74              
75 78 100       2905 my $emode =
    100          
    100          
76             $mode eq 'r' ? Fcntl::O_RDONLY() :
77             $mode eq 'w' ? Fcntl::O_WRONLY() :
78             $mode eq 'rw' ? Fcntl::O_RDWR() :
79             croak "Unknown $func() mode '$mode'"
80             ;
81 56 100       134 $flags = {} if !defined $flags;
82              
83 56         58 my $perms = 0;
84              
85 56         173 for my $k (keys %$flags) {
86 62         188 my $v = !!$flags->{$k};
87             $emode |=
88             $k eq 'creat' ?
89 62 50 50     2893 defined $flags->{$k} ? do {
    100 0        
    50 0        
    50 0        
    50 100        
    50 0        
    50 0        
    100 0        
    50 0        
    50 0        
    50 50        
    100          
    100          
90 16         23 $perms = $flags->{$k};
91 16         37 Fcntl::O_CREAT()
92             } :
93             0
94             :
95             $k eq 'append' ? $v && Fcntl::O_APPEND() :
96             $k eq 'async' ? $v && Fcntl::O_ASYNC() :
97             $k eq 'direct' ? $v && Fcntl::O_DIRECT() :
98             $k eq 'directory' ? $v && Fcntl::O_DIRECTORY() :
99             $k eq 'excl' ? $v && Fcntl::O_EXCL() :
100             $k eq 'noatime' ? $v && Fcntl::O_NOATIME() :
101             $k eq 'noctty' ? $v && Fcntl::O_NOCTTY() :
102             $k eq 'nofollow' ? $v && Fcntl::O_NOFOLLOW() :
103             $k eq 'nonblock' ? $v && Fcntl::O_NONBLOCK() :
104             $k eq 'sync' ? $v && Fcntl::O_SYNC() :
105             $k eq 'trunc' ? $v && Fcntl::O_TRUNC() :
106             croak "Unknown $func() flag '$k'"
107             ;
108             }
109              
110 38 100       116 if ($file =~ /\0/) {
111 2 50       7 $! = Errno::ENOENT() if exists &Errno::ENOENT;
112 2         23 return undef;
113             }
114              
115 36 100       1640 sysopen my $fh, $file, $emode, $perms or return undef;
116 20         113 $fh
117             }
118              
119             sub fsysopen_nothrow {
120 42     42 1 25242 _sysopen('fsysopen_nothrow', @_)
121             }
122              
123             sub fsysopen {
124 42 100   42 1 25786 _sysopen('fsysopen', @_) || die "$prog: $_[0]: $!\n"
125             }
126              
127             sub _opendir {
128 8     8   38 my ($func, $dir) = @_;
129 8 100       223 @_ < 2 and croak "Not enough arguments for $func";
130 6 100       225 @_ > 2 and croak "Too many arguments for $func";
131              
132 4 100       23 if ($dir =~ /\0/) {
133 2 50       6 $! = Errno::ENOENT() if exists &Errno::ENOENT;
134 2         21 return undef;
135             }
136              
137 2 50       40 opendir my $dh, $dir or return undef;
138 2         187 $dh
139             }
140              
141             sub fopendir_nothrow {
142 3     3 0 102 _opendir('fopendir_nothrow', @_)
143             }
144              
145             sub fopendir {
146 5 100   5 1 4314 _opendir('fopendir', @_) || die "$prog: $_[0]: $!\n"
147             }
148              
149             'ok'
150              
151             __END__