line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
# mt-aws-glacier - Amazon Glacier sync client |
2
|
|
|
|
|
|
|
# Copyright (C) 2012-2014 Victor Efimov |
3
|
|
|
|
|
|
|
# http://mt-aws.com (also http://vs-dev.com) vs@vs-dev.com |
4
|
|
|
|
|
|
|
# License: GPLv3 |
5
|
|
|
|
|
|
|
# |
6
|
|
|
|
|
|
|
# This file is part of "mt-aws-glacier" |
7
|
|
|
|
|
|
|
# |
8
|
|
|
|
|
|
|
# mt-aws-glacier is free software: you can redistribute it and/or modify |
9
|
|
|
|
|
|
|
# it under the terms of the GNU General Public License as published by |
10
|
|
|
|
|
|
|
# the Free Software Foundation, either version 3 of the License, or |
11
|
|
|
|
|
|
|
# (at your option) any later version. |
12
|
|
|
|
|
|
|
# |
13
|
|
|
|
|
|
|
# mt-aws-glacier is distributed in the hope that it will be useful, |
14
|
|
|
|
|
|
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
15
|
|
|
|
|
|
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
16
|
|
|
|
|
|
|
# GNU General Public License for more details. |
17
|
|
|
|
|
|
|
# |
18
|
|
|
|
|
|
|
# You should have received a copy of the GNU General Public License |
19
|
|
|
|
|
|
|
# along with this program. If not, see <http://www.gnu.org/licenses/>. |
20
|
|
|
|
|
|
|
|
21
|
|
|
|
|
|
|
package App::MtAws::IntermediateFile; |
22
|
|
|
|
|
|
|
|
23
|
|
|
|
|
|
|
our $VERSION = '1.114_2'; |
24
|
|
|
|
|
|
|
|
25
|
24
|
|
|
24
|
|
250619
|
use strict; |
|
24
|
|
|
|
|
48
|
|
|
24
|
|
|
|
|
696
|
|
26
|
24
|
|
|
24
|
|
101
|
use warnings; |
|
24
|
|
|
|
|
31
|
|
|
24
|
|
|
|
|
594
|
|
27
|
24
|
|
|
24
|
|
100
|
use utf8; |
|
24
|
|
|
|
|
34
|
|
|
24
|
|
|
|
|
151
|
|
28
|
24
|
|
|
24
|
|
538
|
use Carp; |
|
24
|
|
|
|
|
24
|
|
|
24
|
|
|
|
|
1331
|
|
29
|
24
|
|
|
24
|
|
106
|
use File::Temp 0.16 (); |
|
24
|
|
|
|
|
870
|
|
|
24
|
|
|
|
|
472
|
|
30
|
24
|
|
|
24
|
|
107
|
use File::Path; |
|
24
|
|
|
|
|
33
|
|
|
24
|
|
|
|
|
1124
|
|
31
|
24
|
|
|
24
|
|
102
|
use File::Basename; |
|
24
|
|
|
|
|
55
|
|
|
24
|
|
|
|
|
1248
|
|
32
|
24
|
|
|
24
|
|
119
|
use App::MtAws::Utils; |
|
24
|
|
|
|
|
37
|
|
|
24
|
|
|
|
|
3062
|
|
33
|
24
|
|
|
24
|
|
125
|
use App::MtAws::Exceptions; |
|
24
|
|
|
|
|
46
|
|
|
24
|
|
|
|
|
16247
|
|
34
|
|
|
|
|
|
|
|
35
|
|
|
|
|
|
|
|
36
|
|
|
|
|
|
|
sub new |
37
|
|
|
|
|
|
|
{ |
38
|
27
|
|
|
27
|
0
|
10477751
|
my ($class, %args) = @_; |
39
|
27
|
|
|
|
|
136
|
my $self = {}; |
40
|
27
|
100
|
|
|
|
437
|
defined ($self->{target_file} = delete $args{target_file}) or confess "target_file expected"; |
41
|
26
|
|
|
|
|
142
|
$self->{mtime} = delete $args{mtime}; |
42
|
26
|
100
|
|
|
|
315
|
confess "unknown arguments" if %args; |
43
|
25
|
|
|
|
|
85
|
bless $self, $class; |
44
|
25
|
|
|
|
|
211
|
$self->_init(); |
45
|
25
|
|
|
|
|
109
|
$self->{_init_pid} = $$; |
46
|
25
|
|
|
|
|
92
|
return $self; |
47
|
|
|
|
|
|
|
} |
48
|
|
|
|
|
|
|
|
49
|
|
|
|
|
|
|
sub _init |
50
|
|
|
|
|
|
|
{ |
51
|
24
|
|
|
24
|
|
51
|
my ($self) = @_; |
52
|
24
|
|
|
|
|
2669
|
my $dir = dirname($self->{target_file}); |
53
|
24
|
|
|
|
|
250
|
my $binary_dirname = binaryfilename $dir; |
54
|
24
|
50
|
|
|
|
5173
|
eval { mkpath($binary_dirname); 1 } or do { |
|
24
|
|
|
|
|
2519
|
|
|
24
|
|
|
|
|
120
|
|
55
|
0
|
|
|
|
|
0
|
die exception 'cannot_create_directory' => |
56
|
|
|
|
|
|
|
'Cannot create directory %string dir%, errors: %error%', |
57
|
|
|
|
|
|
|
dir => $dir, error => hex_dump_string($@); |
58
|
|
|
|
|
|
|
}; |
59
|
|
|
|
|
|
|
$self->{tmp} = eval { |
60
|
|
|
|
|
|
|
# PID is needed cause child processes re-use random number generators, improves performance only, no risk of race cond. |
61
|
24
|
|
|
|
|
468
|
File::Temp->new(TEMPLATE => "__mtglacier_temp${$}_XXXXXX", UNLINK => 1, SUFFIX => '.tmp', DIR => $binary_dirname) |
62
|
24
|
50
|
|
|
|
62
|
} or do { |
63
|
0
|
|
|
|
|
0
|
die exception 'cannot_create_tempfile' => |
64
|
|
|
|
|
|
|
'Cannot create temporary file in directory %string dir%, errors: %error%', |
65
|
|
|
|
|
|
|
dir => $dir, error => hex_dump_string($@); |
66
|
|
|
|
|
|
|
}; |
67
|
24
|
|
|
|
|
14044
|
my $binary_tempfile = $self->{tmp}->filename; |
68
|
24
|
|
|
|
|
237
|
$self->{tempfile} = characterfilename($binary_tempfile); |
69
|
|
|
|
|
|
|
# it's important to close file, it's filename can be passed to different process, and it can be locked |
70
|
24
|
50
|
|
|
|
1833
|
close $self->{tmp} or confess; |
71
|
|
|
|
|
|
|
} |
72
|
|
|
|
|
|
|
|
73
|
|
|
|
|
|
|
sub tempfilename |
74
|
|
|
|
|
|
|
{ |
75
|
25
|
100
|
|
25
|
0
|
1631
|
shift->{tempfile} or confess; |
76
|
|
|
|
|
|
|
} |
77
|
|
|
|
|
|
|
|
78
|
|
|
|
|
|
|
sub make_permanent |
79
|
|
|
|
|
|
|
{ |
80
|
9
|
|
|
9
|
0
|
3541
|
my $self = shift; |
81
|
9
|
100
|
|
|
|
98
|
confess "unknown arguments" if @_; |
82
|
8
|
|
|
|
|
27
|
my $binary_target_filename = binaryfilename($self->{target_file}); |
83
|
|
|
|
|
|
|
|
84
|
8
|
100
|
|
|
|
442
|
my $character_tempfile = delete $self->{tempfile} or confess "file already permanent or not initialized"; |
85
|
7
|
|
|
|
|
27
|
$self->{tmp}->unlink_on_destroy(0); |
86
|
7
|
|
|
|
|
66
|
undef $self->{tmp}; |
87
|
7
|
|
|
|
|
190
|
my $binary_tempfile = binaryfilename($character_tempfile); |
88
|
|
|
|
|
|
|
|
89
|
7
|
50
|
|
|
|
365
|
chmod((0666 & ~umask), $binary_tempfile) or confess "cannot chmod file $character_tempfile"; |
90
|
7
|
100
|
33
|
|
|
67
|
utime $self->{mtime}, $self->{mtime}, $binary_tempfile or confess "cannot change mtime for $character_tempfile" if defined $self->{mtime}; |
91
|
|
|
|
|
|
|
rename $binary_tempfile, $binary_target_filename or |
92
|
|
|
|
|
|
|
die exception "cannot_rename_file" => "Cannot rename file %string from% to %string to%", |
93
|
7
|
50
|
|
|
|
293
|
from => $character_tempfile, to => $self->{target_file}; |
94
|
|
|
|
|
|
|
} |
95
|
|
|
|
|
|
|
|
96
|
|
|
|
|
|
|
# File::Temp < 0.19 does not have protection from calling destructor in fork'ed child |
97
|
|
|
|
|
|
|
# and forking can happen any moments, some code in File::Spec/Cwd etc call it to exec external commands |
98
|
|
|
|
|
|
|
# this workaround prevents this, however destruction order is undefined so that might just fail |
99
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
# we can try use File::Temp::tempfile() but it destroys temp files only on program exit |
101
|
|
|
|
|
|
|
# (can workaround with DESTROY) + when handle is closed! (thats bad) |
102
|
|
|
|
|
|
|
sub DESTROY |
103
|
|
|
|
|
|
|
{ |
104
|
285
|
|
|
285
|
|
1293968
|
my ($self) = @_; |
105
|
285
|
|
|
|
|
1585
|
local ($!, $@, $?); |
106
|
1
|
|
|
|
|
40
|
eval { $self->{tmp}->unlink_on_destroy(0) } |
107
|
285
|
50
|
100
|
|
|
3660
|
if ($self->{_init_pid} && $self->{_init_pid} != $$ && $self->{tmp}); |
|
|
|
66
|
|
|
|
|
108
|
|
|
|
|
|
|
} |
109
|
|
|
|
|
|
|
|
110
|
|
|
|
|
|
|
1; |