summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Kalnischkies <david@kalnischkies.de>2016-02-16 15:35:36 +0100
committerDavid Kalnischkies <david@kalnischkies.de>2016-03-06 09:39:30 +0100
commit872bd447163066b331eb12c0fed0d71c0585f47b (patch)
tree247f61887925e596c3cfd4291550d4f7da8c94f7
parentf7bd44bae0d7cb7f9838490b5eece075da83899e (diff)
deal with partially downloaded changelogs
Changelogs are relatively small and we have no hashes for them, but we had partial support for them before, so lets stick to it. This also deletes the (partial) file before moving the downloaded file into its place – rename(2) should be doing this by itself, but testing on semaphoreci suggests that this isn't always the case (error is "Stale file handle") and we don't need an atomic replace here, so be explicit. Git-Dch: Ignore
-rw-r--r--apt-pkg/acquire-item.cc21
-rwxr-xr-xtest/integration/test-apt-get-changelog6
2 files changed, 25 insertions, 2 deletions
diff --git a/apt-pkg/acquire-item.cc b/apt-pkg/acquire-item.cc
index 4c1d93be1..62d960633 100644
--- a/apt-pkg/acquire-item.cc
+++ b/apt-pkg/acquire-item.cc
@@ -3145,7 +3145,21 @@ void pkgAcqChangelog::Init(std::string const &DestDir, std::string const &DestFi
DestFile = flCombine(TemporaryDirectory, DestFileName);
if (DestDir.empty() == false)
+ {
d->FinalFile = flCombine(DestDir, DestFileName);
+ if (RealFileExists(d->FinalFile))
+ {
+ FileFd file1, file2;
+ if (file1.Open(DestFile, FileFd::WriteOnly | FileFd::Create | FileFd::Exclusive) &&
+ file2.Open(d->FinalFile, FileFd::ReadOnly) && CopyFile(file2, file1))
+ {
+ struct timeval times[2];
+ times[0].tv_sec = times[1].tv_sec = file2.ModificationTime();
+ times[0].tv_usec = times[1].tv_usec = 0;
+ utimes(DestFile.c_str(), times);
+ }
+ }
+ }
Desc.ShortDesc = "Changelog";
strprintf(Desc.Description, "%s %s %s Changelog", URI::SiteOnly(Desc.URI).c_str(), SrcName.c_str(), SrcVersion.c_str());
@@ -3292,7 +3306,6 @@ void pkgAcqChangelog::Failed(string const &Message, pkgAcquire::MethodConfig con
ErrorText = errText;
else
ErrorText = errText + " (" + ErrorText + ")";
- return;
}
/*}}}*/
// AcqChangelog::Done - Item downloaded OK /*{{{*/
@@ -3301,7 +3314,11 @@ void pkgAcqChangelog::Done(string const &Message,HashStringList const &CalcHashe
{
Item::Done(Message,CalcHashes,Cnf);
if (d->FinalFile.empty() == false)
- Rename(DestFile, d->FinalFile);
+ {
+ if (RemoveFile("pkgAcqChangelog::Done", d->FinalFile) == false ||
+ Rename(DestFile, d->FinalFile) == false)
+ Status = StatError;
+ }
Complete = true;
}
diff --git a/test/integration/test-apt-get-changelog b/test/integration/test-apt-get-changelog
index d65c9530e..1815b9961 100755
--- a/test/integration/test-apt-get-changelog
+++ b/test/integration/test-apt-get-changelog
@@ -94,9 +94,15 @@ testsuccess aptget changelog foo foo -d
testfilestats 'foo.changelog' '%U:%G:%a' '=' "${TEST_DEFAULT_USER}:${TEST_DEFAULT_GROUP}:644"
testfileequal 'foo.changelog' "$(cat aptarchive/pool/main/f/foo/foo_1.0/changelog)"
echo 'bogus' > foo.changelog
+touch -d 'now + 1 hour' foo.changelog
testsuccess aptget changelog foo foo -d
testfilestats 'foo.changelog' '%U:%G:%a' '=' "${TEST_DEFAULT_USER}:${TEST_DEFAULT_GROUP}:644"
testfileequal 'foo.changelog' "$(cat aptarchive/pool/main/f/foo/foo_1.0/changelog)"
+echo -n 'bogus' > foo.changelog
+touch -d "$(stat -c%y aptarchive/pool/main/f/foo/foo_1.0/changelog)" foo.changelog
+testsuccess aptget changelog foo foo -d
+testfilestats 'foo.changelog' '%U:%G:%a' '=' "${TEST_DEFAULT_USER}:${TEST_DEFAULT_GROUP}:644"
+testequal 'bogus1.0) stable; urgency=low' head -n 1 foo.changelog
rm -f foo.changelog
# no @CHANGEPATH@ in the URI