File Coverage

blib/lib/Filesys/POSIX/FdTable.pm
Criterion Covered Total %
statement 31 31 100.0
branch 8 8 100.0
condition n/a
subroutine 8 8 100.0
pod 5 5 100.0
total 52 52 100.0


line stmt bran cond sub pod time code
1             # Copyright (c) 2014, cPanel, Inc.
2             # All rights reserved.
3             # http://cpanel.net/
4             #
5             # This is free software; you can redistribute it and/or modify it under the same
6             # terms as Perl itself. See the LICENSE file for further details.
7              
8             package Filesys::POSIX::FdTable;
9              
10 26     26   449 use strict;
  26         31  
  26         569  
11 26     26   78 use warnings;
  26         24  
  26         552  
12              
13 26     26   406 use Filesys::POSIX::Error qw(throw);
  26         66  
  26         6635  
14              
15             =head1 NAME
16              
17             Filesys::POSIX::FdTable - File descriptor table
18              
19             =head1 DESCRIPTION
20              
21             This internal module used by Filesys::POSIX handles the allocation and tracking
22             of numeric file descriptors associated with inodes opened for I/O. It does not
23             intend to expose any public interfaces.
24              
25             =head1 METHODS
26              
27             =over
28              
29             =item Cnew>
30              
31             Create a new file descriptor table object. Returns a blessed hash.
32              
33             =cut
34              
35             sub new {
36 41     41 1 211 return bless {}, shift;
37             }
38              
39             =item C<$fd_table-Eopen($inode, $flags)>
40              
41             Asks the C<$inode> object to open and return a L
42             object. Accepts flags as defined in L. A reference to
43             the inode, file handle, flags passed will be stored.
44              
45             Returns a unused file descriptor number greater than 2, unique to the current
46             file descriptor table, upon success. Possible exceptions may be thrown:
47              
48             =over
49              
50             =item * ENODEV (No such device or address)
51              
52             Could not open a file handle for the inode passed.
53              
54             =back
55              
56             =cut
57              
58             sub open {
59 77     77 1 730 my ( $self, $inode, $flags ) = @_;
60              
61 77         63 my $fd = 2;
62 77         166 my $handle = $inode->open($flags);
63              
64 77         101 $! = 0;
65              
66 77 100       158 throw &Errno::ENODEV unless $handle;
67              
68 76         253 foreach ( sort { $a <=> $b } ( $fd, keys %$self ) ) {
  41         42  
69 98 100       193 next if $self->{ $fd = $_ + 1 };
70 76         76 last;
71             }
72              
73 76         192 $self->{$fd} = {
74             'inode' => $inode,
75             'handle' => $handle,
76             'flags' => $flags
77             };
78              
79 76         234 return $fd;
80             }
81              
82             =item C<$fd_table-Elookup($fd)>
83              
84             Given a file descriptor number, return the file descriptor table entry stored;
85             such an object contains an inode reference, a file handle reference, and the
86             flags with which the file was opened. Possible exceptions include:
87              
88             =over
89              
90             =item * EBADF (Bad file descriptor)
91              
92             No handle found for the given file descriptor.
93              
94             =back
95              
96             =cut
97              
98             sub lookup {
99 603     603 1 486 my ( $self, $fd ) = @_;
100              
101 603         482 $! = 0;
102              
103 603 100       829 my $entry = $self->{$fd} or throw &Errno::EBADF;
104              
105 602         787 return $entry;
106             }
107              
108             =item C<$fd_table-Eclose($fd)>
109              
110             Close the file handle corresponding to the given file descriptor, and remove the
111             file descriptor from the table, freeing it for future reallocation.
112              
113             =cut
114              
115             sub close {
116 66     66 1 70 my ( $self, $fd ) = @_;
117 66 100       136 my $entry = $self->{$fd} or return;
118              
119 65         156 $entry->{'handle'}->close;
120              
121 65         241 delete $self->{$fd};
122             }
123              
124             =item C<$fd_table-Elist>
125              
126             Return a list of all file descriptor numbers currently allocated.
127              
128             =cut
129              
130             sub list {
131 6     6 1 5 my ($self) = @_;
132              
133 6         14 return keys %$self;
134             }
135              
136             =back
137              
138             =cut
139              
140             1;
141              
142             __END__