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   27205 use 5.010001;
  40         174  
4 40     40   256 use strict;
  40         103  
  40         881  
5 40     40   212 use warnings;
  40         104  
  40         1062  
6 40     40   258 use Readonly;
  40         97  
  40         2371  
7              
8 40         2360 use Perl::Critic::Utils qw{ :booleans :characters :severities :classification
9 40     40   290 hashify is_perl_bareword };
  40         113  
10              
11 40     40   22080 use parent 'Perl::Critic::Policy';
  40         99  
  40         288  
12              
13             our $VERSION = '1.148';
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 2646 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 399 sub default_severity { return $SEVERITY_LOWEST }
63 74     74 1 342 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 304 my ($self, $config) = @_;
70              
71 89         203 my @specified_functions = keys %{ $self->{_functions} };
  89         534  
72 89         248 my @resulting_functions;
73              
74 89         286 foreach my $function (@specified_functions) {
75 335 50       923 if ( $function eq ':defaults' ) {
    100          
76 0         0 push @resulting_functions, @DEFAULT_FUNCTIONS;
77             }
78             elsif ( $function eq ':builtins' ) {
79 3         13 push @resulting_functions, @BUILTIN_FUNCTIONS;
80             }
81             else {
82 332         769 push @resulting_functions, $function;
83             }
84             }
85              
86 89         1161 my %functions = hashify(@resulting_functions);
87              
88 89         272 foreach my $function ( keys %{ $self->{_exclude_functions} } ) {
  89         399  
89 3         11 delete $functions{$function};
90             }
91              
92 89         301 $self->{_functions} = \%functions;
93              
94 89         540 return $TRUE;
95             }
96              
97             #-----------------------------------------------------------------------------
98              
99             sub violates {
100 530     530 1 1072 my ( $self, $elem, undef ) = @_;
101              
102 530 100       1567 if ( $self->{_functions}->{':all'} ) {
    100          
103 11 100       40 return if is_perl_bareword($elem);
104 9 100       131 return if $self->{_exclude_functions}->{ $elem->content() };
105             }
106             elsif ( not $self->{_functions}->{ $elem->content() } ) {
107 446         2382 return;
108             }
109              
110 81 100       399 return if ! is_unchecked_call( $elem, [ keys %{ $self->{_autodie_modules} } ] );
  81         396  
111              
112 17         98 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 :