line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
=head1 NAME |
2
|
|
|
|
|
|
|
|
3
|
|
|
|
|
|
|
Win32API::File::Time - Set file times, even on open or readonly files. |
4
|
|
|
|
|
|
|
|
5
|
|
|
|
|
|
|
=head1 SYNOPSIS |
6
|
|
|
|
|
|
|
|
7
|
|
|
|
|
|
|
use Win32API::File::Time qw{:win}; |
8
|
|
|
|
|
|
|
($atime, $mtime, $ctime) = GetFileTime ($filename); |
9
|
|
|
|
|
|
|
SetFileTime ($filename, $atime, $mtime, $ctime); |
10
|
|
|
|
|
|
|
|
11
|
|
|
|
|
|
|
or |
12
|
|
|
|
|
|
|
|
13
|
|
|
|
|
|
|
use Win32API::File::Time qw{utime}; |
14
|
|
|
|
|
|
|
utime $atime, $mtime, $filename or die $^E; |
15
|
|
|
|
|
|
|
|
16
|
|
|
|
|
|
|
=head1 DESCRIPTION |
17
|
|
|
|
|
|
|
|
18
|
|
|
|
|
|
|
The purpose of Win32API::File::Time is to provide maximal access to |
19
|
|
|
|
|
|
|
the file creation, modification, and access times under MSWin32. |
20
|
|
|
|
|
|
|
|
21
|
|
|
|
|
|
|
Under Windows, the Perl utime module will not modify the time of an |
22
|
|
|
|
|
|
|
open file, nor a read-only file. The comments in win32.c indicate |
23
|
|
|
|
|
|
|
that this is the intended functionality, at least for read-only |
24
|
|
|
|
|
|
|
files. |
25
|
|
|
|
|
|
|
|
26
|
|
|
|
|
|
|
This module will read and modify the time on open files, read-only |
27
|
|
|
|
|
|
|
files, and directories. I |
28
|
|
|
|
|
|
|
|
29
|
|
|
|
|
|
|
This module is based on the SetFileTime function in kernel32.dll. |
30
|
|
|
|
|
|
|
Perl's utime built-in also makes explicit use of this function if |
31
|
|
|
|
|
|
|
the "C" run-time version of utime fails. The difference is in how |
32
|
|
|
|
|
|
|
the filehandle is created. The Perl built-in requests access |
33
|
|
|
|
|
|
|
GENERIC_READ | GENERIC_WRITE when modifying file dates, whereas |
34
|
|
|
|
|
|
|
this module requests access FILE_WRITE_ATTRIBUTES. |
35
|
|
|
|
|
|
|
|
36
|
|
|
|
|
|
|
Nothing is exported by default, but all documented subroutines |
37
|
|
|
|
|
|
|
are exportable. In addition, the following export tags are |
38
|
|
|
|
|
|
|
supported: |
39
|
|
|
|
|
|
|
|
40
|
|
|
|
|
|
|
:all => exports everything exportable |
41
|
|
|
|
|
|
|
:win => exports GetFileTime and SetFileTime |
42
|
|
|
|
|
|
|
|
43
|
|
|
|
|
|
|
Wide system calls are implemented (based on the truth of |
44
|
|
|
|
|
|
|
${^WIDE_SYSTEM_CALLS}) but not currently supported. In other words: I |
45
|
|
|
|
|
|
|
wrote the code, but haven't tested it and don't have any plans to. |
46
|
|
|
|
|
|
|
Feedback will be accepted, and implemented when I get a sufficient |
47
|
|
|
|
|
|
|
supply of tuits. |
48
|
|
|
|
|
|
|
|
49
|
|
|
|
|
|
|
=over 4 |
50
|
|
|
|
|
|
|
|
51
|
|
|
|
|
|
|
=cut |
52
|
|
|
|
|
|
|
|
53
|
|
|
|
|
|
|
# Modifications: |
54
|
|
|
|
|
|
|
|
55
|
|
|
|
|
|
|
# 0.001 13-May-2004 T. R. Wyant |
56
|
|
|
|
|
|
|
# Initial version. |
57
|
|
|
|
|
|
|
# 0.002 02-Oct-2004 T. R. Wyant |
58
|
|
|
|
|
|
|
# No code changes. Add the readme file to the manifest, |
59
|
|
|
|
|
|
|
# and add the dependencies to Makefile.PL, since they |
60
|
|
|
|
|
|
|
# really _should_ be there, and Active State is |
61
|
|
|
|
|
|
|
# complaining about them missing. |
62
|
|
|
|
|
|
|
# 0.003 17-Dec-2004 T. R. Wyant |
63
|
|
|
|
|
|
|
# Reimplement time conversion. Also modified the self- |
64
|
|
|
|
|
|
|
# test to use a scratch file for the date modification |
65
|
|
|
|
|
|
|
# portion of the test. |
66
|
|
|
|
|
|
|
# 0.003_01 28-Dec-2004 T. R. Wyant |
67
|
|
|
|
|
|
|
# Close handles after use. In case of error, preserve |
68
|
|
|
|
|
|
|
# the windows error around the close. |
69
|
|
|
|
|
|
|
# 0.004 13-Jan-2005 T. R. Wyant |
70
|
|
|
|
|
|
|
# Fix export tags. |
71
|
|
|
|
|
|
|
# Tweak "Bugs" section to more accurately represent what |
72
|
|
|
|
|
|
|
# I think is going on. |
73
|
|
|
|
|
|
|
# Release to CPAN. |
74
|
|
|
|
|
|
|
# 0.004_01 28-Apr-2005 T. R. Wyant |
75
|
|
|
|
|
|
|
# Assert FILE_FLAG_BACKUP_SEMANTICS when reading times, |
76
|
|
|
|
|
|
|
# so that it works for directories under XP and |
77
|
|
|
|
|
|
|
# 2003 server. |
78
|
|
|
|
|
|
|
# Centralize code to close handles on error. |
79
|
|
|
|
|
|
|
# 0.004_02 04-May-2005 T. R. Wyant |
80
|
|
|
|
|
|
|
# Document behaviour of FAT (and change test to |
81
|
|
|
|
|
|
|
# accomodate. |
82
|
|
|
|
|
|
|
# 0.005 04-May-2005 T. R. Wyant |
83
|
|
|
|
|
|
|
# Release to CPAN. |
84
|
|
|
|
|
|
|
|
85
|
1
|
|
|
1
|
|
60372
|
use strict; |
|
1
|
|
|
|
|
3
|
|
|
1
|
|
|
|
|
38
|
|
86
|
1
|
|
|
1
|
|
5
|
use warnings; |
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
50
|
|
87
|
|
|
|
|
|
|
|
88
|
|
|
|
|
|
|
package Win32API::File::Time; |
89
|
|
|
|
|
|
|
|
90
|
1
|
|
|
1
|
|
5
|
use base qw{Exporter}; |
|
1
|
|
|
|
|
6
|
|
|
1
|
|
|
|
|
129
|
|
91
|
1
|
|
|
1
|
|
6
|
use vars qw{@EXPORT_OK %EXPORT_TAGS $VERSION}; |
|
1
|
|
|
|
|
1
|
|
|
1
|
|
|
|
|
75
|
|
92
|
1
|
|
|
|
|
85
|
use vars qw{ |
93
|
|
|
|
|
|
|
$FileTimeToSystemTime |
94
|
|
|
|
|
|
|
$FileTimeToLocalFileTime |
95
|
|
|
|
|
|
|
$GetFileTime |
96
|
|
|
|
|
|
|
$LocalFileTimeToFileTime |
97
|
|
|
|
|
|
|
$SetFileTime |
98
|
|
|
|
|
|
|
$SystemTimeToFileTime |
99
|
1
|
|
|
1
|
|
6
|
}; |
|
1
|
|
|
|
|
2
|
|
100
|
|
|
|
|
|
|
|
101
|
1
|
|
|
1
|
|
6
|
use Carp; |
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
74
|
|
102
|
1
|
|
|
1
|
|
1076
|
use Time::Local; |
|
1
|
|
|
|
|
2591
|
|
|
1
|
|
|
|
|
149
|
|
103
|
1
|
|
|
1
|
|
2056
|
use Win32::API; |
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
104
|
|
|
|
|
|
|
use Win32API::File qw{:ALL}; |
105
|
|
|
|
|
|
|
|
106
|
|
|
|
|
|
|
$VERSION = '0.006'; |
107
|
|
|
|
|
|
|
|
108
|
|
|
|
|
|
|
@EXPORT_OK = qw{GetFileTime SetFileTime utime}; |
109
|
|
|
|
|
|
|
%EXPORT_TAGS = ( |
110
|
|
|
|
|
|
|
all => [@EXPORT_OK], |
111
|
|
|
|
|
|
|
win => [qw{GetFileTime SetFileTime}], |
112
|
|
|
|
|
|
|
); |
113
|
|
|
|
|
|
|
|
114
|
|
|
|
|
|
|
=item ($atime, $mtime, $ctime) = GetFileTime ($filename); |
115
|
|
|
|
|
|
|
|
116
|
|
|
|
|
|
|
This subroutine returns the access, modification, and creation times of |
117
|
|
|
|
|
|
|
the given file. If it fails, nothing is returned, and the error code |
118
|
|
|
|
|
|
|
can be found in $^E. |
119
|
|
|
|
|
|
|
|
120
|
|
|
|
|
|
|
No, there's no additional functionality here versus the stat |
121
|
|
|
|
|
|
|
built-in. But it was useful for development and testing, and |
122
|
|
|
|
|
|
|
has been exposed for orthogonality's sake. |
123
|
|
|
|
|
|
|
|
124
|
|
|
|
|
|
|
=cut |
125
|
|
|
|
|
|
|
|
126
|
|
|
|
|
|
|
sub GetFileTime { |
127
|
|
|
|
|
|
|
my $fn = shift or croak "usage: GetFileTime (filename)"; |
128
|
|
|
|
|
|
|
my $fh = _get_handle ($fn) or return; |
129
|
|
|
|
|
|
|
$GetFileTime ||= _map ('KERNEL32', 'GetFileTime', [qw{N P P P}], 'I'); |
130
|
|
|
|
|
|
|
my ($atime, $mtime, $ctime); |
131
|
|
|
|
|
|
|
$atime = $mtime = $ctime = pack 'LL', 0, 0; # Preallocate 64 bits. |
132
|
|
|
|
|
|
|
$GetFileTime->Call ($fh, $ctime, $atime, $mtime) or |
133
|
|
|
|
|
|
|
return _close_handle ($fh); |
134
|
|
|
|
|
|
|
CloseHandle ($fh); |
135
|
|
|
|
|
|
|
return _filetime_to_perltime ($atime, $mtime, $ctime); |
136
|
|
|
|
|
|
|
} |
137
|
|
|
|
|
|
|
|
138
|
|
|
|
|
|
|
|
139
|
|
|
|
|
|
|
=item SetFileTime (filename, atime, mtime, ctime); |
140
|
|
|
|
|
|
|
|
141
|
|
|
|
|
|
|
This subroutine sets the access, modification, and creation times of |
142
|
|
|
|
|
|
|
the given file. The return is true for success, and false for failure. |
143
|
|
|
|
|
|
|
In the latter case, $^E will contain the error. |
144
|
|
|
|
|
|
|
|
145
|
|
|
|
|
|
|
If you don't want to set all of the times, pass 0 or undef for the |
146
|
|
|
|
|
|
|
times you don't want to set. For example, |
147
|
|
|
|
|
|
|
|
148
|
|
|
|
|
|
|
$now = time (); |
149
|
|
|
|
|
|
|
SetFileTime ($filename, $now, $now); |
150
|
|
|
|
|
|
|
|
151
|
|
|
|
|
|
|
is equivalent to the "touch" command for the given file. |
152
|
|
|
|
|
|
|
|
153
|
|
|
|
|
|
|
=cut |
154
|
|
|
|
|
|
|
|
155
|
|
|
|
|
|
|
sub SetFileTime { |
156
|
|
|
|
|
|
|
my $fn = shift or croak "usage: SetFileTime (filename, atime, mtime, ctime)"; |
157
|
|
|
|
|
|
|
my $atime = _perltime_to_filetime (shift); |
158
|
|
|
|
|
|
|
my $mtime = _perltime_to_filetime (shift); |
159
|
|
|
|
|
|
|
my $ctime = _perltime_to_filetime (shift); |
160
|
|
|
|
|
|
|
# We assume we can do something useful for an undef. |
161
|
|
|
|
|
|
|
$SetFileTime ||= _map ('KERNEL32', 'SetFileTime', [qw{N P P P}], 'I'); |
162
|
|
|
|
|
|
|
my $fh = _get_handle ($fn, 1) or return; |
163
|
|
|
|
|
|
|
|
164
|
|
|
|
|
|
|
$SetFileTime->Call ($fh, $ctime, $atime, $mtime) or |
165
|
|
|
|
|
|
|
return _close_handle ($fh); |
166
|
|
|
|
|
|
|
|
167
|
|
|
|
|
|
|
CloseHandle ($fh); |
168
|
|
|
|
|
|
|
return 1; |
169
|
|
|
|
|
|
|
} |
170
|
|
|
|
|
|
|
|
171
|
|
|
|
|
|
|
=item utime ($atime, $mtime, $filename, ...) |
172
|
|
|
|
|
|
|
|
173
|
|
|
|
|
|
|
This subroutine overrides the built-in of the same name. It does |
174
|
|
|
|
|
|
|
exactly the same thing, but has a different idea than the built-in |
175
|
|
|
|
|
|
|
about what files are legal to change. |
176
|
|
|
|
|
|
|
|
177
|
|
|
|
|
|
|
Like the core utime, it returns the number of files successfully |
178
|
|
|
|
|
|
|
modified. If not all files can be modified, $^E contains the last |
179
|
|
|
|
|
|
|
error encountered. |
180
|
|
|
|
|
|
|
|
181
|
|
|
|
|
|
|
=cut |
182
|
|
|
|
|
|
|
|
183
|
|
|
|
|
|
|
sub utime { |
184
|
|
|
|
|
|
|
my $atime = shift; |
185
|
|
|
|
|
|
|
my $mtime = shift; |
186
|
|
|
|
|
|
|
my $num = 0; |
187
|
|
|
|
|
|
|
foreach my $fn (@_) { |
188
|
|
|
|
|
|
|
SetFileTime ($fn, $atime, $mtime) and $num++; |
189
|
|
|
|
|
|
|
} |
190
|
|
|
|
|
|
|
return $num; |
191
|
|
|
|
|
|
|
} |
192
|
|
|
|
|
|
|
|
193
|
|
|
|
|
|
|
|
194
|
|
|
|
|
|
|
####################################################################### |
195
|
|
|
|
|
|
|
# |
196
|
|
|
|
|
|
|
# Internal subroutines |
197
|
|
|
|
|
|
|
# |
198
|
|
|
|
|
|
|
# _close_handle |
199
|
|
|
|
|
|
|
# |
200
|
|
|
|
|
|
|
# This subroutine closes the given handle, preserving status |
201
|
|
|
|
|
|
|
# around the call. |
202
|
|
|
|
|
|
|
|
203
|
|
|
|
|
|
|
sub _close_handle { |
204
|
|
|
|
|
|
|
my $fh = shift; |
205
|
|
|
|
|
|
|
my $err = Win32::GetLastError (); |
206
|
|
|
|
|
|
|
CloseHandle ($fh); |
207
|
|
|
|
|
|
|
$^E = $err; |
208
|
|
|
|
|
|
|
return; |
209
|
|
|
|
|
|
|
} |
210
|
|
|
|
|
|
|
|
211
|
|
|
|
|
|
|
|
212
|
|
|
|
|
|
|
# _filetime_to_perltime |
213
|
|
|
|
|
|
|
# |
214
|
|
|
|
|
|
|
# This subroutine takes as input a number of Windows file times |
215
|
|
|
|
|
|
|
# and converts them to Perl times. |
216
|
|
|
|
|
|
|
# |
217
|
|
|
|
|
|
|
# The algorithm is due to the unsung heros at Hip Communications |
218
|
|
|
|
|
|
|
# Inc (currently known as ActiveState), who found a way around |
219
|
|
|
|
|
|
|
# the fact that Perl and Windows have a fundamentally different |
220
|
|
|
|
|
|
|
# idea of what local time corresponds to a given GMT when summer |
221
|
|
|
|
|
|
|
# time was in effect at the given GMT, but not at the time the |
222
|
|
|
|
|
|
|
# conversion is made. The given algorithm is consistent with the |
223
|
|
|
|
|
|
|
# results of the stat () function. |
224
|
|
|
|
|
|
|
|
225
|
|
|
|
|
|
|
sub _filetime_to_perltime { |
226
|
|
|
|
|
|
|
my @result; |
227
|
|
|
|
|
|
|
$FileTimeToSystemTime ||= _map ( |
228
|
|
|
|
|
|
|
'KERNEL32', 'FileTimeToSystemTime', [qw{P P}], 'I'); |
229
|
|
|
|
|
|
|
$FileTimeToLocalFileTime ||= _map ( |
230
|
|
|
|
|
|
|
'KERNEL32', 'FileTimeToLocalFileTime', [qw{P P}], 'I'); |
231
|
|
|
|
|
|
|
my $st = pack 'ssssssss', 0, 0, 0, 0, 0, 0, 0, 0; |
232
|
|
|
|
|
|
|
foreach my $ft (@_) { |
233
|
|
|
|
|
|
|
my ($low, $high) = unpack 'LL', $ft; |
234
|
|
|
|
|
|
|
$high or do { |
235
|
|
|
|
|
|
|
push @result, undef; |
236
|
|
|
|
|
|
|
next; |
237
|
|
|
|
|
|
|
}; |
238
|
|
|
|
|
|
|
my $lf = $ft; # Just to get the space allocated. |
239
|
|
|
|
|
|
|
$FileTimeToLocalFileTime->Call ($ft, $lf) && |
240
|
|
|
|
|
|
|
$FileTimeToSystemTime->Call ($lf, $st) or do { |
241
|
|
|
|
|
|
|
push @result, undef; |
242
|
|
|
|
|
|
|
next; |
243
|
|
|
|
|
|
|
}; |
244
|
|
|
|
|
|
|
my @tm = unpack 'ssssssss', $st; |
245
|
|
|
|
|
|
|
push @result, $tm[0] > 0 ? |
246
|
|
|
|
|
|
|
timelocal (@tm[6, 5, 4, 3], $tm[1] - 1, $tm[0]) : |
247
|
|
|
|
|
|
|
undef; |
248
|
|
|
|
|
|
|
} |
249
|
|
|
|
|
|
|
return wantarray ? @result : $result[0]; |
250
|
|
|
|
|
|
|
} |
251
|
|
|
|
|
|
|
|
252
|
|
|
|
|
|
|
|
253
|
|
|
|
|
|
|
# _get_handle |
254
|
|
|
|
|
|
|
# |
255
|
|
|
|
|
|
|
# This subroutine takes a file name and returns a handle to the |
256
|
|
|
|
|
|
|
# file. If the second argument is true, the handle is configured |
257
|
|
|
|
|
|
|
# appropriately for writing attributes; otherwise it is |
258
|
|
|
|
|
|
|
# configured appropriately for reading attributes. |
259
|
|
|
|
|
|
|
|
260
|
|
|
|
|
|
|
sub _get_handle { |
261
|
|
|
|
|
|
|
my $fn = shift; |
262
|
|
|
|
|
|
|
my $write = shift; |
263
|
|
|
|
|
|
|
|
264
|
|
|
|
|
|
|
${^WIDE_SYSTEM_CALLS} ? |
265
|
|
|
|
|
|
|
CreateFileW ($fn, |
266
|
|
|
|
|
|
|
($write ? FILE_WRITE_ATTRIBUTES : FILE_READ_ATTRIBUTES), |
267
|
|
|
|
|
|
|
($write ? FILE_SHARE_WRITE | FILE_SHARE_READ : FILE_SHARE_READ), |
268
|
|
|
|
|
|
|
[], |
269
|
|
|
|
|
|
|
OPEN_EXISTING, |
270
|
|
|
|
|
|
|
($write ? FILE_ATTRIBUTE_NORMAL | FILE_FLAG_BACKUP_SEMANTICS : FILE_FLAG_BACKUP_SEMANTICS), |
271
|
|
|
|
|
|
|
0, |
272
|
|
|
|
|
|
|
) : |
273
|
|
|
|
|
|
|
CreateFile ($fn, |
274
|
|
|
|
|
|
|
($write ? FILE_WRITE_ATTRIBUTES : FILE_READ_ATTRIBUTES), |
275
|
|
|
|
|
|
|
($write ? FILE_SHARE_WRITE | FILE_SHARE_READ : FILE_SHARE_READ), |
276
|
|
|
|
|
|
|
[], |
277
|
|
|
|
|
|
|
OPEN_EXISTING, |
278
|
|
|
|
|
|
|
($write ? FILE_ATTRIBUTE_NORMAL | FILE_FLAG_BACKUP_SEMANTICS : FILE_FLAG_BACKUP_SEMANTICS), |
279
|
|
|
|
|
|
|
0, |
280
|
|
|
|
|
|
|
) |
281
|
|
|
|
|
|
|
or do { |
282
|
|
|
|
|
|
|
$^E = Win32::GetLastError (); |
283
|
|
|
|
|
|
|
return; |
284
|
|
|
|
|
|
|
}; |
285
|
|
|
|
|
|
|
} |
286
|
|
|
|
|
|
|
|
287
|
|
|
|
|
|
|
|
288
|
|
|
|
|
|
|
# _map |
289
|
|
|
|
|
|
|
# |
290
|
|
|
|
|
|
|
# This subroutine calls Win32API to map an entry point. |
291
|
|
|
|
|
|
|
|
292
|
|
|
|
|
|
|
sub _map { |
293
|
|
|
|
|
|
|
return Win32::API->new (@_) || |
294
|
|
|
|
|
|
|
croak "Error - Failed to map $_[1] from $_[0]: $^E"; |
295
|
|
|
|
|
|
|
} |
296
|
|
|
|
|
|
|
|
297
|
|
|
|
|
|
|
|
298
|
|
|
|
|
|
|
# _perltime_to_filetime |
299
|
|
|
|
|
|
|
# |
300
|
|
|
|
|
|
|
# This subroutine converts perl times to Windows file times. |
301
|
|
|
|
|
|
|
|
302
|
|
|
|
|
|
|
# The same considerations apply to the algorithm used here as to |
303
|
|
|
|
|
|
|
# the one used in _filetime_to_perltime. |
304
|
|
|
|
|
|
|
|
305
|
|
|
|
|
|
|
sub _perltime_to_filetime { |
306
|
|
|
|
|
|
|
my @result; |
307
|
|
|
|
|
|
|
$SystemTimeToFileTime ||= _map ( |
308
|
|
|
|
|
|
|
'KERNEL32', 'SystemTimeToFileTime', [qw{P P}], 'I'); |
309
|
|
|
|
|
|
|
$LocalFileTimeToFileTime ||= _map ( |
310
|
|
|
|
|
|
|
'KERNEL32', 'LocalFileTimeToFileTime', [qw{P P}], 'I'); |
311
|
|
|
|
|
|
|
my $zero = pack 'LL', 0, 0; # To get a quadword zero. |
312
|
|
|
|
|
|
|
my ($ft, $lf) = ($zero, $zero); # To get the space allocated. |
313
|
|
|
|
|
|
|
foreach my $pt (@_) { |
314
|
|
|
|
|
|
|
if (defined $pt) { |
315
|
|
|
|
|
|
|
my @tm = localtime ($pt); |
316
|
|
|
|
|
|
|
my $st = pack 'ssssssss', $tm[5] + 1900, $tm[4] + 1, 0, |
317
|
|
|
|
|
|
|
@tm[3, 2, 1, 0], 0; |
318
|
|
|
|
|
|
|
push @result, $SystemTimeToFileTime->Call ($st, $lf) && |
319
|
|
|
|
|
|
|
$LocalFileTimeToFileTime->Call ($lf, $ft) ? $ft : $zero; |
320
|
|
|
|
|
|
|
} |
321
|
|
|
|
|
|
|
else { |
322
|
|
|
|
|
|
|
push @result, $zero; |
323
|
|
|
|
|
|
|
} |
324
|
|
|
|
|
|
|
} |
325
|
|
|
|
|
|
|
return wantarray ? @result : $result[0]; |
326
|
|
|
|
|
|
|
} |
327
|
|
|
|
|
|
|
|
328
|
|
|
|
|
|
|
=back |
329
|
|
|
|
|
|
|
|
330
|
|
|
|
|
|
|
=head1 HISTORY |
331
|
|
|
|
|
|
|
|
332
|
|
|
|
|
|
|
0.001 Initial release |
333
|
|
|
|
|
|
|
0.002 Correct MANIFEST and Makefile.PL dependencies. |
334
|
|
|
|
|
|
|
Tweak documentation. No code changes. |
335
|
|
|
|
|
|
|
0.003 Correct time conversion. |
336
|
|
|
|
|
|
|
Modify test to not change own date. |
337
|
|
|
|
|
|
|
0.004 Close handles after use. Thanks to Chris |
338
|
|
|
|
|
|
|
Camejo for pointing out the leak. |
339
|
|
|
|
|
|
|
Fix export tags to agree with docs. |
340
|
|
|
|
|
|
|
Tweak "BUGS" documentation. |
341
|
|
|
|
|
|
|
0.005 Assert FILE_FLAG_BACKUP_SEMANTICS when reading |
342
|
|
|
|
|
|
|
times, so that it works for directories |
343
|
|
|
|
|
|
|
under XP and 2003 server. Thanks to Leigh |
344
|
|
|
|
|
|
|
Power for pointing out the problem and |
345
|
|
|
|
|
|
|
suggesting the solution. |
346
|
|
|
|
|
|
|
Document FAT, and accomodate it in self-test. |
347
|
|
|
|
|
|
|
Thanks again, Leigh. |
348
|
|
|
|
|
|
|
Centralize code to close handles on error. |
349
|
|
|
|
|
|
|
0.006 T. R. Wyant |
350
|
|
|
|
|
|
|
Re-layout kit, add POD tests. |
351
|
|
|
|
|
|
|
|
352
|
|
|
|
|
|
|
=head1 BUGS |
353
|
|
|
|
|
|
|
|
354
|
|
|
|
|
|
|
As implemented, GetFileTime () constitutes an access, and |
355
|
|
|
|
|
|
|
therefore updates the access time. |
356
|
|
|
|
|
|
|
|
357
|
|
|
|
|
|
|
The stat () builtin, on the other hand, doesn't report |
358
|
|
|
|
|
|
|
an access time change even after GetFileTime () has been |
359
|
|
|
|
|
|
|
used. In fact, it looks to me very much like stat () reports |
360
|
|
|
|
|
|
|
the modification time in element [8] of the list, but I |
361
|
|
|
|
|
|
|
find this nowhere documented. |
362
|
|
|
|
|
|
|
|
363
|
|
|
|
|
|
|
FAT file time resolution is 2 seconds at best, as documented |
364
|
|
|
|
|
|
|
at F. |
365
|
|
|
|
|
|
|
Access time resolution seems to be to the nearest day. |
366
|
|
|
|
|
|
|
|
367
|
|
|
|
|
|
|
=head1 ACKNOWLEDGMENTS |
368
|
|
|
|
|
|
|
|
369
|
|
|
|
|
|
|
This module would not exist without the following people: |
370
|
|
|
|
|
|
|
|
371
|
|
|
|
|
|
|
Aldo Calpini, who gave us Win32::API. |
372
|
|
|
|
|
|
|
|
373
|
|
|
|
|
|
|
Tye McQueen, who gave us Win32API::File. |
374
|
|
|
|
|
|
|
|
375
|
|
|
|
|
|
|
Jenda Krynicky, whose "How2 create a PPM distribution" |
376
|
|
|
|
|
|
|
(F) gave me a leg up on |
377
|
|
|
|
|
|
|
both PPM and tar distributions. |
378
|
|
|
|
|
|
|
|
379
|
|
|
|
|
|
|
The folks of ActiveState (F, |
380
|
|
|
|
|
|
|
formerly known as Hip Communications), who found a way to reconcile |
381
|
|
|
|
|
|
|
Windows' and Perl's subtly different ideas of what time it is. |
382
|
|
|
|
|
|
|
|
383
|
|
|
|
|
|
|
The folks of Cygwin (F), especially those |
384
|
|
|
|
|
|
|
who worked on times.cc in the Cygwin core. This is the B |
385
|
|
|
|
|
|
|
implementation of utime I could find which did what B wanted |
386
|
|
|
|
|
|
|
it to do. |
387
|
|
|
|
|
|
|
|
388
|
|
|
|
|
|
|
|
389
|
|
|
|
|
|
|
=head1 AUTHOR |
390
|
|
|
|
|
|
|
|
391
|
|
|
|
|
|
|
Thomas R. Wyant, III (F) |
392
|
|
|
|
|
|
|
|
393
|
|
|
|
|
|
|
=head1 COPYRIGHT |
394
|
|
|
|
|
|
|
|
395
|
|
|
|
|
|
|
Copyright 2004, 2005 by |
396
|
|
|
|
|
|
|
E. I. DuPont de Nemours and Company, Inc. |
397
|
|
|
|
|
|
|
All rights reserved. |
398
|
|
|
|
|
|
|
|
399
|
|
|
|
|
|
|
Changes since version 0.005 copyright 2007 by Thomas R. Wyant, III. All |
400
|
|
|
|
|
|
|
rights reserved. |
401
|
|
|
|
|
|
|
|
402
|
|
|
|
|
|
|
=head1 LICENSE |
403
|
|
|
|
|
|
|
|
404
|
|
|
|
|
|
|
This module is free software; you can use it, redistribute it and/or |
405
|
|
|
|
|
|
|
modify it under the same terms as Perl itself. Please see |
406
|
|
|
|
|
|
|
L for current licenses. |
407
|
|
|
|
|
|
|
|
408
|
|
|
|
|
|
|
=cut |
409
|
|
|
|
|
|
|
|