File Coverage

lib/File/Mountpoint.pm
Criterion Covered Total %
statement 35 35 100.0
branch 9 10 90.0
condition 3 6 50.0
subroutine 7 7 100.0
pod 1 1 100.0
total 55 59 93.2


line stmt bran cond sub pod time code
1             # Copyright (c) 2008 Joshua Hoblitt
2             #
3             # $Id: Mountpoint.pm,v 1.5 2008/09/30 06:58:06 jhoblitt Exp $
4              
5             package File::Mountpoint;
6              
7 3     3   207289 use strict;
  3         8  
  3         170  
8              
9             our $VERSION = '0.01';
10              
11 3     3   16 use base qw( Exporter );
  3         6  
  3         351  
12              
13 3     3   15 use Carp;
  3         9  
  3         260  
14 3     3   3018 use File::stat qw( :FIELDS );
  3         49382  
  3         30  
15 3     3   935 use Fcntl qw( :mode );
  3         6  
  3         995  
16 3     3   19 use File::Spec;
  3         6  
  3         897  
17              
18             our @EXPORT_OK = qw( is_mountpoint );
19              
20             sub is_mountpoint
21             {
22             # running mountpoint on /tmp yields:
23             # lstat("/tmp", {st_mode=S_IFDIR|S_ISVTX|0777, st_size=28672, ...}) = 0
24             # stat("/tmp/..", {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0
25             # running mountpoint on /tmp/ yields:
26             # lstat("/tmp/", {st_mode=S_IFDIR|S_ISVTX|0777, st_size=28672, ...}) = 0
27             # stat("/tmp//..", {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0
28              
29             # $ mountpoint /tmp/asdf
30             # mountpoint: /tmp/asdf: No such file or directory
31             # $ mountpoint /tmp/binutils-2.18.tar.bz2
32             # mountpoint: /tmp/binutils-2.18.tar.bz2: not a directory
33             # $ mountpoint /tmp
34             # /tmp is not a mountpoint
35              
36 5     5 1 3486 my $path = shift;
37              
38 5 100       18 return unless defined $path;
39              
40             # verbose - currnetly unused
41 4         4 my $verbose;
42              
43             # run lstat() on the path
44 4         15 my $ls = lstat($path);
45              
46             # check to see if the path exists
47 4 100       482 unless (defined $ls) {
48 1         213 croak "is_mountpoint: $path: No such file or directory";
49             }
50              
51             # check to make sure that the path exists and is a directory
52 3 100       15 unless (S_ISDIR($st_mode)) {
53 1         161 croak "is_mountpoint: $path: not a directory";
54             }
55              
56             # store the lstat() device and inode
57 2         4 my $ls_dev = $st_dev;
58 2         3 my $ls_ino = $st_ino;
59              
60             # append /.. to the path and run stat() on it
61 2         28 stat(File::Spec->catdir($path, "/.."));
62              
63             # store the stat() device
64 2         233 my $s_dev = $st_dev;
65 2         3 my $s_ino = $st_ino;
66              
67             # compare the lstat() and stat() devs
68             # based directly on code from mountpoint.c
69 2 100 66     19 unless (($ls_dev != $s_dev) || ($ls_dev == $s_dev && $ls_ino == $s_ino)) {
      33        
70 1 50       5 carp "is_mounpoint: $path is not a mountpoint" if $verbose;
71 1         7 return;
72             }
73              
74 1         9 return 1;
75             }
76              
77              
78             1;
79              
80             __END__