File: Flock.pm

package info (click to toggle)
liblog-dispatch-filerotate-perl 1.38-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 200 kB
  • sloc: perl: 951; makefile: 2
file content (153 lines) | stat: -rw-r--r-- 3,517 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
#
# This file is part of Log-Dispatch-FileRotate
#
# This software is copyright (c) 2005 by Mark Pfeiffer.
#
# This is free software; you can redistribute it and/or modify it under
# the same terms as the Perl 5 programming language system itself.
#

package Log::Dispatch::FileRotate::Flock;
$Log::Dispatch::FileRotate::Flock::VERSION = '1.38';
# ABSTRACT: File Locking Functions for L<Log::Dispatch::FileRotate>

use strict;
use warnings;

use base 'Exporter';

use Fcntl ':flock';

our @EXPORT_OK = qw(safe_flock flopen);


sub safe_flock {
    my ($fh, $flags) = @_;

    while (1) {
        unless (flock $fh, $flags) {
            # retry if we were interrupted or we are in non-blocking and the file is locked
            next if $!{EAGAIN} or $!{EWOULDBLOCK};

            return 0;
        }
        else {
            return 1;
        }
    }
}


sub flopen {
    my $path = shift;

    my $flags = LOCK_EX; my $fh;

    while (1) {
        unless (open $fh, '>>', $path) {
            return;
        }

        unless (safe_flock($fh, $flags)) {
            return;
        }

        my @path_stat = stat $path;
        unless (@path_stat) {
            # file disappeared fron under our feet
            close $fh;
            next;
        }

        my @fh_stat = stat $fh;
        unless (@fh_stat) {
            # This should never happen
            return;
        }

        unless ($^O =~ /^MSWin/) {
            # stat on a filehandle and path return different "dev" and "rdev"
            # fields on windows
            if ($path_stat[0] != $fh_stat[0]) {
                # file was changed under our feet. try again;
                close $fh;
                next;
            }
        }

        # check that inode are the same for the path and fh
        if ($path_stat[1] != $fh_stat[1])
        {
            # file was changed under our feet. try again;
            close $fh;
            next;
        }

        return ($fh, $fh_stat[1]);
    }
}

1;

__END__

=pod

=encoding UTF-8

=head1 NAME

Log::Dispatch::FileRotate::Flock - File Locking Functions for L<Log::Dispatch::FileRotate>

=head1 VERSION

version 1.38

=head1 SYNOPSIS

 Internal Use Only!

=head2 DESCRIPTION

Internal Use Only!

=head1 METHODS

=head2 safe_flock($filehandle, $flags): boolean

This is a wrapper around C<flock()> that handles things such as interruption of
the call by a signal automatically.

=head2 flopen($path): ($filehandle, $inode)

This function is similar to BSD's C<flopen()> function.  It opens a file,
obtiains an exclusive lock on it using C<flock()>, and handles a bunch of race
conditions that can happen.  It returns the opened filehandle and the inode of
the file on success, nothing on failure.

=head1 SOURCE

The development version is on github at L<https://https://github.com/mschout/perl-log-dispatch-filerotate>
and may be cloned from L<git://https://github.com/mschout/perl-log-dispatch-filerotate.git>

=head1 BUGS

Please report any bugs or feature requests on the bugtracker website
L<https://github.com/mschout/perl-log-dispatch-filerotate/issues>

When submitting a bug or request, please include a test-file or a
patch to an existing test-file that illustrates the bug or desired
feature.

=head1 AUTHOR

Michael Schout <mschout@cpan.org>

=head1 COPYRIGHT AND LICENSE

This software is copyright (c) 2005 by Mark Pfeiffer.

This is free software; you can redistribute it and/or modify it under
the same terms as the Perl 5 programming language system itself.

=cut