File Coverage

blib/lib/POE/Devel/ProcAlike/PerlInfo.pm
Criterion Covered Total %
statement 15 125 12.0
branch 0 50 0.0
condition 0 15 0.0
subroutine 5 14 35.7
pod 1 3 33.3
total 21 207 10.1


line stmt bran cond sub pod time code
1             # Declare our package
2             package POE::Devel::ProcAlike::PerlInfo;
3 1     1   1145 use strict; use warnings;
  1     1   3  
  1         56  
  1         5  
  1         3  
  1         76  
4              
5             # Initialize our version
6 1     1   18 use vars qw( $VERSION );
  1         1  
  1         75  
7             $VERSION = '0.02';
8              
9             # Set our superclass
10 1     1   8 use base 'Filesys::Virtual::Async::inMemory';
  1         2  
  1         1786  
11              
12             # portable tools
13 1     1   39023 use File::Spec;
  1         2  
  1         1796  
14              
15             sub new {
16             # make sure we set a readonly filesystem!
17 0     0 1   return __PACKAGE__->SUPER::new(
18             'readonly' => 1,
19             );
20             }
21              
22             #/perl
23             # # place for generic perl data
24             #
25             # binary # $^X
26             # version # $^V
27             # pid # $$
28             # script # $0
29             # osname # $^O
30             # starttime # $^T
31             #
32             # inc # dumps the @inc array
33             #
34             # /env
35             # # dumps the %ENV hash
36             #
37             # PWD # data is $ENV{PWD}
38             # ...
39             #
40             # /modules
41             # # lists all loaded modules
42             #
43             # /Foo-Bar
44             # # module name will be converted to above format
45             #
46             # version # $module->VERSION ||= 'UNDEF'
47             # path # module's path in %INC
48             my %fs = (
49             'binary' => $^X . "\n",
50             'version' => "$^V\n",
51             'pid' => $$ . "\n",
52             'script' => $0 . "\n",
53             'osname' => $^O . "\n",
54             'starttime' => $^T . "\n",
55             'inc' => join( "\n", @INC ) . "\n",
56              
57             'env' => \&manage_env,
58              
59             'modules' => \&manage_modules,
60             );
61              
62             # helper to get loaded modules
63             sub _get_loadedmodules {
64 0     0     my @list = grep { $_ !~ /(?:al|ix)$/ } keys %INC; # remove those annoying non-module files
  0            
65 0           for ( @list ) {
66 0           s/\.pm$//; # remove trailing .pm
67 0           $_ = join( '-', File::Spec->splitdir( $_ ) ); # convert "/" into "-" ( portably )
68             }
69              
70 0           return \@list;
71             }
72              
73             sub _get_module_metrics {
74 0     0     return [ qw( version path ) ];
75             }
76              
77             sub _get_module_metric {
78 0     0     my $incpath = shift;
79 0           my $module = shift;
80 0           my $metric = shift;
81              
82             # what metric?
83 0 0         if ( $metric eq 'version' ) {
    0          
84 0           my $size = join( '::', split( '-', $module ) );
85              
86             ## no critic
87 0           $size = eval "$size->VERSION";
88             ## use critic
89              
90 0 0         if ( defined $size ) {
91 0           return $size . "\n";
92             } else {
93 0           return 'UNDEF' . "\n";
94             }
95             } elsif ( $metric eq 'path' ) {
96 0           return $INC{ $incpath } . "\n";
97             } else {
98 0           die "unknown module metric: $metric\n";
99             }
100             }
101              
102             sub manage_modules {
103 0     0 0   my( $type, @path ) = @_;
104              
105             # what's the operation?
106 0 0         if ( $type eq 'readdir' ) {
    0          
    0          
107             # trying to read the root or the module itself?
108 0 0         if ( defined $path[0] ) {
109             # shortcut, because we always know what's in the module dir
110 0           return _get_module_metrics();
111             } else {
112             # list all loaded modules
113 0           return _get_loadedmodules();
114             }
115             } elsif ( $type eq 'stat' ) {
116             # set some default data
117 0           my ($atime, $ctime, $mtime, $size, $modes);
118 0           $atime = $ctime = $mtime = time();
119 0           my ($dev, $ino, $rdev, $blocks, $gid, $uid, $nlink, $blksize) = ( 0, 0, 0, 1, (split( /\s+/, $) ))[0], $>, 1, 1024 );
120              
121             # trying to stat the dir or stuff inside it?
122 0 0         if ( defined $path[0] ) {
123             # convert it back to %INC type
124 0           my $incpath = join( '/', split( '-', $path[0] ) ) . '.pm';
125              
126             # does it exist?
127 0 0         if ( ! exists $INC{ $incpath } ) {
128 0           return;
129             }
130              
131             # trying to stat the module or data inside it?
132 0 0         if ( defined $path[1] ) {
133             # valid filename?
134 0 0 0       if ( ! grep { $_ eq $path[1] } @{ _get_module_metrics() } or defined $path[2] ) {
  0            
  0            
135 0           return;
136             }
137              
138 0           $modes = oct( '100644' );
139              
140             # get the data
141 0           $size = length( _get_module_metric( $incpath, $path[0], $path[1] ) );
142             } else {
143             # a directory, munge the data
144 0           $size = 0;
145 0           $modes = oct( '040755' );
146 0           $nlink = 2;
147             }
148             } else {
149             # a directory, munge the data
150 0           $size = 0;
151 0           $modes = oct( '040755' );
152 0           $nlink = 2 + scalar @{ _get_loadedmodules() };
  0            
153             }
154              
155             # finally, return the darn data!
156 0           return( [ $dev, $ino, $modes, $nlink, $uid, $gid, $rdev, $size, $atime, $mtime, $ctime, $blksize, $blocks ] );
157             } elsif ( $type eq 'open' ) {
158             # convert it back to %INC type
159 0           my $incpath = join( '/', split( '-', $path[0] ) ) . '.pm';
160              
161             # does it exist?
162 0 0 0       if ( ! exists $INC{ $incpath } or ! defined $path[1] ) {
163 0           return;
164             }
165              
166             # valid filename?
167 0 0 0       if ( ! grep { $_ eq $path[1] } @{ _get_module_metrics() } or defined $path[2] ) {
  0            
  0            
168 0           return;
169             }
170              
171             # get the metric!
172 0           my $data = _get_module_metric( $incpath, $path[0], $path[1] );
173 0           return \$data;
174             }
175             }
176              
177             sub manage_env {
178 0     0 0   my( $type, @path ) = @_;
179              
180             # what's the operation?
181 0 0         if ( $type eq 'readdir' ) {
    0          
    0          
182             # we don't have any subdirs so simply return the entire hash!
183 0           return [ keys %ENV ];
184             } elsif ( $type eq 'stat' ) {
185             # set some default data
186 0           my ($atime, $ctime, $mtime, $size, $modes);
187 0           $atime = $ctime = $mtime = time();
188 0           my ($dev, $ino, $rdev, $blocks, $gid, $uid, $nlink, $blksize) = ( 0, 0, 0, 1, (split( /\s+/, $) ))[0], $>, 1, 1024 );
189              
190             # trying to stat the dir or stuff inside it?
191 0 0         if ( defined $path[0] ) {
192             # does it exist?
193 0 0 0       if ( ! exists $ENV{ $path[0] } or defined $path[1] ) {
194 0           return;
195             }
196              
197             # a file, munge the data
198 0           $size = length( $ENV{ $path[0] } . "\n" );
199 0           $modes = oct( '100644' );
200             } else {
201             # a directory, munge the data
202 0           $size = 0;
203 0           $modes = oct( '040755' );
204 0           $nlink = 2;
205             }
206              
207             # finally, return the darn data!
208 0           return( [ $dev, $ino, $modes, $nlink, $uid, $gid, $rdev, $size, $atime, $mtime, $ctime, $blksize, $blocks ] );
209             } elsif ( $type eq 'open' ) {
210             # return a scalar ref
211 0 0         if ( exists $ENV{ $path[0] } ) {
212 0           my $data = $ENV{ $path[0] } . "\n";
213 0           return \$data;
214             } else {
215 0           return;
216             }
217             }
218             }
219              
220             # we cheat here and not implement a lot of stuff because we know the FUSE api never calls the "extra" APIs
221             # that ::Async provides. Furthermore, this is a read-only filesystem so we can skip even more APIs :)
222              
223             # _rmtree
224              
225             # _scandir
226              
227             # _move
228              
229             # _copy
230              
231             # _load
232              
233             sub _readdir {
234 0     0     my( $self, $path ) = @_;
235              
236 0 0         if ( $path eq File::Spec->rootdir() ) {
237 0           return [ keys %fs ];
238             } else {
239             # sanitize the path
240 0           my @dirs = File::Spec->splitdir( $path );
241 0           shift( @dirs ); # get rid of the root entry which is always '' for me
242 0           return $fs{ $dirs[0] }->( 'readdir', @dirs[ 1 .. $#dirs ] );
243             }
244             }
245              
246             # _rmdir
247              
248             # _mkdir
249              
250             # _rename
251              
252             # _mknod
253              
254             # _unlink
255              
256             # _chmod
257              
258             # _truncate
259              
260             # _chown
261              
262             # _utime
263              
264             sub _stat {
265 0     0     my( $self, $path ) = @_;
266              
267             # stating the root?
268 0 0         if ( $path eq File::Spec->rootdir() ) {
269 0           my ($atime, $ctime, $mtime, $size, $modes);
270 0           $atime = $ctime = $mtime = time();
271 0           my ($dev, $ino, $rdev, $blocks, $gid, $uid, $nlink, $blksize) = ( 0, 0, 0, 1, (split( /\s+/, $) ))[0], $>, 1, 1024 );
272 0           $size = 0;
273 0           $modes = oct( '040755' );
274              
275             # count subdirs
276 0           $nlink = 2 + grep { ref $fs{ $_ } } keys %fs;
  0            
277              
278 0           return( [ $dev, $ino, $modes, $nlink, $uid, $gid, $rdev, $size, $atime, $mtime, $ctime, $blksize, $blocks ] );
279             }
280              
281             # sanitize the path
282 0           my @dirs = File::Spec->splitdir( $path );
283 0           shift( @dirs ); # get rid of the root entry which is always '' for me
284              
285 0 0         if ( exists $fs{ $dirs[0] } ) {
286             # directory or file?
287 0 0         if ( ref $fs{ $dirs[0] } ) {
288             # trying to stat the dir or the subpath?
289 0           return $fs{ $dirs[0] }->( 'stat', @dirs[ 1 .. $#dirs ] );
290             } else {
291             # arg, stat is a finicky beast!
292 0           my $size = length( $fs{ $dirs[0] } );
293 0           my $modes = oct( '100644' );
294              
295 0           my ($dev, $ino, $rdev, $blocks, $gid, $uid, $nlink, $blksize) = ( 0, 0, 0, 1, (split( /\s+/, $) ))[0], $>, 1, 1024 );
296 0           my ($atime, $ctime, $mtime);
297 0           $atime = $ctime = $mtime = time();
298              
299 0           return( [ $dev, $ino, $modes, $nlink, $uid, $gid, $rdev, $size, $atime, $mtime, $ctime, $blksize, $blocks ] );
300             }
301             } else {
302 0           return;
303             }
304             }
305              
306             # _write
307              
308             sub _open {
309 0     0     my( $self, $path ) = @_;
310              
311             # sanitize the path
312 0           my @dirs = File::Spec->splitdir( $path );
313 0           shift( @dirs ); # get rid of the root entry which is always '' for me
314 0 0 0       if ( defined $dirs[0] and exists $fs{ $dirs[0] } ) {
315             # directory or file?
316 0 0         if ( ref $fs{ $dirs[0] } ) {
317 0           return $fs{ $dirs[0] }->( 'open', @dirs[ 1 .. $#dirs ] );
318             } else {
319             # return a scalar ref
320 0           return \$fs{ $dirs[0] };
321             }
322             } else {
323 0           return;
324             }
325             }
326              
327             1;
328             __END__