File Coverage

blib/lib/Perl/Critic/Policy/InputOutput/RequireCheckedSyscalls.pm
Criterion Covered Total %
statement 43 44 97.7
branch 13 14 92.8
condition n/a
subroutine 12 12 100.0
pod 5 6 83.3
total 73 76 96.0


line stmt bran cond sub pod time code
1             package Perl::Critic::Policy::InputOutput::RequireCheckedSyscalls;
2              
3 40     40   27444 use 5.010001;
  40         167  
4 40     40   264 use strict;
  40         110  
  40         818  
5 40     40   219 use warnings;
  40         124  
  40         1066  
6 40     40   250 use Readonly;
  40         118  
  40         2313  
7              
8 40         2321 use Perl::Critic::Utils qw{ :booleans :characters :severities :classification
9 40     40   303 hashify is_perl_bareword };
  40         128  
10              
11 40     40   22476 use parent 'Perl::Critic::Policy';
  40         117  
  40         285  
12              
13             our $VERSION = '1.146';
14              
15             #-----------------------------------------------------------------------------
16              
17             Readonly::Scalar my $DESC => q{Return value of flagged function ignored};
18             Readonly::Scalar my $EXPL => [208, 278];
19              
20             Readonly::Array my @DEFAULT_FUNCTIONS => qw(
21             open close print say
22             );
23             # I created this list by searching for "return" in perlfunc
24             Readonly::Array my @BUILTIN_FUNCTIONS => qw(
25             accept bind binmode chdir chmod chown close closedir connect
26             dbmclose dbmopen exec fcntl flock fork ioctl kill link listen
27             mkdir msgctl msgget msgrcv msgsnd open opendir pipe print read
28             readdir readline readlink readpipe recv rename rmdir say seek seekdir
29             semctl semget semop send setpgrp setpriority setsockopt shmctl
30             shmget shmread shutdown sleep socket socketpair symlink syscall
31             sysopen sysread sysseek system syswrite tell telldir truncate
32             umask unlink utime wait waitpid
33             );
34              
35             #-----------------------------------------------------------------------------
36              
37             sub supported_parameters {
38             return (
39             {
40 132     132 0 2417 name => 'functions',
41             description =>
42             'The set of functions to require checking the return value of.',
43             default_string => join( $SPACE, @DEFAULT_FUNCTIONS ),
44             behavior => 'string list',
45             },
46             {
47             name => 'exclude_functions',
48             description =>
49             'The set of functions to not require checking the return value of.',
50             default_string => $EMPTY,
51             behavior => 'string list',
52             },
53             {
54             name => 'autodie_modules',
55             description => 'Modules which export autodie.',
56             default_string => 'autodie',
57             behavior => 'string list',
58             },
59             );
60             }
61              
62 91     91 1 375 sub default_severity { return $SEVERITY_LOWEST }
63 74     74 1 347 sub default_themes { return qw( core maintenance certrule ) }
64 70     70 1 218 sub applies_to { return 'PPI::Token::Word' }
65              
66             #-----------------------------------------------------------------------------
67              
68             sub initialize_if_enabled {
69 89     89 1 313 my ($self, $config) = @_;
70              
71 89         193 my @specified_functions = keys %{ $self->{_functions} };
  89         547  
72 89         224 my @resulting_functions;
73              
74 89         295 foreach my $function (@specified_functions) {
75 335 50       815 if ( $function eq ':defaults' ) {
    100          
76 0         0 push @resulting_functions, @DEFAULT_FUNCTIONS;
77             }
78             elsif ( $function eq ':builtins' ) {
79 3         14 push @resulting_functions, @BUILTIN_FUNCTIONS;
80             }
81             else {
82 332         707 push @resulting_functions, $function;
83             }
84             }
85              
86 89         1179 my %functions = hashify(@resulting_functions);
87              
88 89         256 foreach my $function ( keys %{ $self->{_exclude_functions} } ) {
  89         410  
89 3         9 delete $functions{$function};
90             }
91              
92 89         282 $self->{_functions} = \%functions;
93              
94 89         525 return $TRUE;
95             }
96              
97             #-----------------------------------------------------------------------------
98              
99             sub violates {
100 530     530 1 1042 my ( $self, $elem, undef ) = @_;
101              
102 530 100       1463 if ( $self->{_functions}->{':all'} ) {
    100          
103 11 100       31 return if is_perl_bareword($elem);
104 9 100       130 return if $self->{_exclude_functions}->{ $elem->content() };
105             }
106             elsif ( not $self->{_functions}->{ $elem->content() } ) {
107 446         2302 return;
108             }
109              
110 81 100       379 return if ! is_unchecked_call( $elem, [ keys %{ $self->{_autodie_modules} } ] );
  81         436  
111              
112 17         91 return $self->violation( "$DESC - " . $elem->content(), $EXPL, $elem );
113             }
114              
115              
116             1;
117              
118             __END__
119              
120             #-----------------------------------------------------------------------------
121              
122             =pod
123              
124             =for stopwords nyah autodie builtins
125              
126             =head1 NAME
127              
128             Perl::Critic::Policy::InputOutput::RequireCheckedSyscalls - Return value of flagged function ignored.
129              
130             =head1 AFFILIATION
131              
132             This Policy is part of the core L<Perl::Critic|Perl::Critic>
133             distribution.
134              
135              
136             =head1 DESCRIPTION
137              
138             This performs identically to InputOutput::RequireCheckedOpen/Close
139             except that this is configurable to apply to any function, whether
140             core or user-defined.
141              
142             If your module uses L<Fatal|Fatal>,
143             L<Fatal::Exception|Fatal::Exception>, or L<autodie|autodie> then any functions
144             wrapped by those modules will not trigger this policy. For example:
145              
146             use Fatal qw(open);
147             open my $fh, $filename; # no violation
148             close $fh; # yes violation
149              
150             use autodie;
151             open $filehandle, $mode, $filename; # no violation
152              
153             Currently, L<autodie|autodie> is not properly treated as a pragma; its
154             lexical effects aren't taken into account.
155              
156              
157             =head1 CONFIGURATION
158              
159             This policy watches for a configurable list of function names. By
160             default, it applies to C<open>, C<print>, C<say> and C<close>. You can
161             override this to set it to a different list of functions with the
162             C<functions> and C<exclude_functions> settings. To do this, put
163             entries in a F<.perlcriticrc> file like this:
164              
165             [InputOutput::RequireCheckedSyscalls]
166             functions = open opendir read readline readdir close closedir
167              
168             We have defined a few shortcuts for creating this list
169              
170             [InputOutput::RequireCheckedSyscalls]
171             functions = :defaults opendir readdir closedir
172              
173             [InputOutput::RequireCheckedSyscalls]
174             functions = :builtins
175              
176             [InputOutput::RequireCheckedSyscalls]
177             functions = :all
178              
179             The C<:builtins> shortcut above represents all of the builtin
180             functions that have error conditions (about 65 of them, many of them
181             rather obscure).
182              
183             You can require checking all builtins except C<print> by combining
184             the C<functions> and C<exclude_functions>:
185              
186             [InputOutput::RequireCheckedSyscalls]
187             functions = :builtins
188             exclude_functions = print
189              
190             This is a lot easier to read than the alternative.
191              
192             The C<:all> is the insane case: you must check the return value of
193             EVERY function call, even C<return> and C<exit>. Yes, this "feature"
194             is overkill and is wasting CPU cycles on your computer by just
195             existing. Nyah nyah. I shouldn't code after midnight.
196              
197             If you create a module that exports C<autodie> you can tell this policy about
198             it with the C<autodie_modules> setting:
199              
200             [InputOutput::RequireCheckedSyscalls]
201             autodie_modules = My::Thing
202              
203             =head1 CREDITS
204              
205             Initial development of this policy was supported by a grant from the
206             Perl Foundation.
207              
208             This policy module is based heavily on policies written by Andrew
209             Moore <amoore@mooresystems.com>.
210              
211              
212             =head1 AUTHOR
213              
214             Chris Dolan <cdolan@cpan.org>
215              
216              
217             =head1 COPYRIGHT
218              
219             Copyright (c) 2007-2011 Chris Dolan. Many rights reserved.
220              
221             This program is free software; you can redistribute it and/or modify
222             it under the same terms as Perl itself. The full text of this license
223             can be found in the LICENSE file included with this module.
224              
225             =cut
226              
227             ##############################################################################
228             # Local Variables:
229             # mode: cperl
230             # cperl-indent-level: 4
231             # fill-column: 78
232             # indent-tabs-mode: nil
233             # c-indentation-style: bsd
234             # End:
235             # ex: set ts=8 sts=4 sw=4 tw=78 ft=perl expandtab shiftround :