Raphael Hertzog wrote:
> Yes, so what matters is the undef parameter, and you want to modify all
> files in a single call to have the same timestamp everywhere. But I'm not
> sure you have that guarantee.
Hmph, true enough. perl calls futimes(fd, NULL) in a loop.
> ... and thus you
> might reintroduce a time skew between the various patched files.
Another possibility to worry about is
$ touch file_one.c && dpkg-source --before-build .
which will result in file_one.c having a later timestamp than the
patched files, assuming the filesystem supports nanosecond timestamps
(e.g., tmpfs). "make" only guards against that for dependencies of
the special
.LOW_RESOLUTION_TIME:
target.
GNU patch just _preserves_ file timestamps when patching. Could
dpkg-source do that?
If not, I am tempted to suggest something like the following.
(NEEDSWORK: does not handle nanosecond timestamps.)
---
diff --git a/scripts/Dpkg/Source/Patch.pm b/scripts/Dpkg/Source/Patch.pm
index 59d1004..8e70cb8 100644
--- a/scripts/Dpkg/Source/Patch.pm
+++ b/scripts/Dpkg/Source/Patch.pm
@@ -465,6 +465,32 @@ sub prepare_apply {
}
}
+sub touch_patched_files {
+ my ($new, @files) = @_;
+ return unless @files;
+
+ unless (defined($now)) {
+ # On NFS, "utime(undef, undef, $file)" sets mtime and atime to the
+ # current time on the server side. The time() function returns
+ # the current time on the client side. Sadly, the two can disagree.
+ #
+ # Everything else (normal modification, "touch") uses the time on
+ # the server side, so to avoid problems in the presence of time
+ # skew, we should, too.
+
+ my $fn = shift @files;
+ utime(undef, undef, $fn) ||
+ syserr(_g("cannot change timestamp for %s"), $fn);
+ lstat($fn) ||
+ syserr(_g("cannot read timestamp from %s"), $fn);
+ $now = lstat("_")[9];
+ }
+
+ utime($now, $now, @files) ||
+ $! == ENOENT ||
+ syserr(_g("cannot change timestamp of patched file"));
+}
+
sub apply {
my ($self, $destdir, %opts) = @_;
# Set default values to options
@@ -500,13 +526,12 @@ sub apply {
}
$self->close();
# Reset the timestamp of all the patched files
- # and remove .dpkg-orig files
- my $now = $opts{"timestamp"} || time;
+ if ($opts{"force_timestamp"}) {
+ my $now = $opts{"timestamp"} || undef;
+ touch_patched_files($now, %{$analysis->{'filepatched'}});
+ }
+ # Remove .dpkg-orig files
foreach my $fn (keys %{$analysis->{'filepatched'}}) {
- if ($opts{"force_timestamp"}) {
- utime($now, $now, $fn) || $! == ENOENT ||
- syserr(_g("cannot change timestamp for %s"), $fn);
- }
if ($opts{"remove_backup"}) {
$fn .= ".dpkg-orig";
unlink($fn) || syserr(_g("remove patch backup file %s"), $fn);
--
To UNSUBSCRIBE, email to [email protected]
with a subject of "unsubscribe". Trouble? Contact [email protected]