diff options
author | Michael Vogt <mvo@debian.org> | 2015-08-18 11:54:05 +0200 |
---|---|---|
committer | Michael Vogt <mvo@debian.org> | 2015-08-18 11:54:05 +0200 |
commit | 21248c0f00ee71412dbadc6ebf84011cf974346d (patch) | |
tree | 7dc1f5904399482d2128765b5b86d57a4ac5b3e1 /apt-pkg/depcache.cc | |
parent | e5f34ad3b043abf033c1626eb8449b75955d6760 (diff) | |
parent | 4fc6b7570c3e97b65c118b58cdf6729fa94c9b03 (diff) |
Merge branch 'debian/experimental' into feature/srv-records
Conflicts:
cmdline/apt-helper.cc
cmdline/makefile
Diffstat (limited to 'apt-pkg/depcache.cc')
-rw-r--r-- | apt-pkg/depcache.cc | 94 |
1 files changed, 53 insertions, 41 deletions
diff --git a/apt-pkg/depcache.cc b/apt-pkg/depcache.cc index 19a6e0d7e..b73c336db 100644 --- a/apt-pkg/depcache.cc +++ b/apt-pkg/depcache.cc @@ -33,7 +33,6 @@ #include <vector> #include <algorithm> #include <iostream> -#include <sstream> #include <set> #include <sys/stat.h> @@ -237,9 +236,11 @@ bool pkgDepCache::writeStateFile(OpProgress * /*prog*/, bool InstalledOnly) /*{{ FileFd StateFile; string const state = _config->FindFile("Dir::State::extended_states"); + if (CreateAPTDirectoryIfNeeded(_config->FindDir("Dir::State"), flNotFile(state)) == false) + return false; // if it does not exist, create a empty one - if(!RealFileExists(state)) + if(!RealFileExists(state)) { StateFile.Open(state, FileFd::WriteAtomic); StateFile.Close(); @@ -250,17 +251,14 @@ bool pkgDepCache::writeStateFile(OpProgress * /*prog*/, bool InstalledOnly) /*{{ return _error->Error(_("Failed to open StateFile %s"), state.c_str()); - FILE *OutFile; - string const outfile = state + ".tmp"; - if((OutFile = fopen(outfile.c_str(),"w")) == NULL) - return _error->Error(_("Failed to write temporary StateFile %s"), - outfile.c_str()); + FileFd OutFile(state, FileFd::ReadWrite | FileFd::Atomic); + if (OutFile.IsOpen() == false || OutFile.Failed() == true) + return _error->Error(_("Failed to write temporary StateFile %s"), state.c_str()); // first merge with the existing sections pkgTagFile tagfile(&StateFile); pkgTagSection section; std::set<string> pkgs_seen; - const char *nullreorderlist[] = {0}; while(tagfile.Step(section)) { string const pkgname = section.FindS("Package"); string pkgarch = section.FindS("Architecture"); @@ -269,7 +267,7 @@ bool pkgDepCache::writeStateFile(OpProgress * /*prog*/, bool InstalledOnly) /*{{ // Silently ignore unknown packages and packages with no actual // version. pkgCache::PkgIterator pkg = Cache->FindPkg(pkgname, pkgarch); - if(pkg.end() || pkg.VersionList().end()) + if(pkg.end() || pkg.VersionList().end()) continue; StateCache const &P = PkgState[pkg->ID]; bool newAuto = (P.Flags & Flag::Auto); @@ -290,21 +288,17 @@ bool pkgDepCache::writeStateFile(OpProgress * /*prog*/, bool InstalledOnly) /*{{ if(_config->FindB("Debug::pkgAutoRemove",false)) std::clog << "Update existing AutoInstall info: " << pkg.FullName() << std::endl; - TFRewriteData rewrite[3]; - rewrite[0].Tag = "Architecture"; - rewrite[0].Rewrite = pkg.Arch(); - rewrite[0].NewTag = 0; - rewrite[1].Tag = "Auto-Installed"; - rewrite[1].Rewrite = newAuto ? "1" : "0"; - rewrite[1].NewTag = 0; - rewrite[2].Tag = 0; - TFRewrite(OutFile, section, nullreorderlist, rewrite); - fprintf(OutFile,"\n"); + + std::vector<pkgTagSection::Tag> rewrite; + rewrite.push_back(pkgTagSection::Tag::Rewrite("Architecture", pkg.Arch())); + rewrite.push_back(pkgTagSection::Tag::Rewrite("Auto-Installed", newAuto ? "1" : "0")); + section.Write(OutFile, NULL, rewrite); + if (OutFile.Write("\n", 1) == false) + return false; pkgs_seen.insert(pkg.FullName()); } - + // then write the ones we have not seen yet - std::ostringstream ostr; for(pkgCache::PkgIterator pkg=Cache->PkgBegin(); !pkg.end(); ++pkg) { StateCache const &P = PkgState[pkg->ID]; if(P.Flags & Flag::Auto) { @@ -323,19 +317,17 @@ bool pkgDepCache::writeStateFile(OpProgress * /*prog*/, bool InstalledOnly) /*{{ continue; if(debug_autoremove) std::clog << "Writing new AutoInstall: " << pkg.FullName() << std::endl; - ostr.str(string("")); - ostr << "Package: " << pkg.Name() - << "\nArchitecture: " << pkgarch - << "\nAuto-Installed: 1\n\n"; - fprintf(OutFile,"%s",ostr.str().c_str()); + std::string stanza = "Package: "; + stanza.append(pkg.Name()) + .append("\nArchitecture: ").append(pkgarch) + .append("\nAuto-Installed: 1\n\n"); + if (OutFile.Write(stanza.c_str(), stanza.length()) == false) + return false; } } - fclose(OutFile); - - // move the outfile over the real file and set permissions - rename(outfile.c_str(), state.c_str()); + if (OutFile.Close() == false) + return false; chmod(state.c_str(), 0644); - return true; } /*}}}*/ @@ -663,10 +655,11 @@ void pkgDepCache::Update(OpProgress *Prog) { iUsrSize = 0; iDownloadSize = 0; - iDelCount = 0; iInstCount = 0; + iDelCount = 0; iKeepCount = 0; iBrokenCount = 0; + iPolicyBrokenCount = 0; iBadCount = 0; // Perform the depends pass @@ -1225,7 +1218,7 @@ bool pkgDepCache::MarkInstall(PkgIterator const &Pkg,bool AutoInst, continue; } // now check if we should consider it a automatic dependency or not - if(InstPkg->CurrentVer == 0 && Pkg->Section != 0 && ConfigValueInSubTree("APT::Never-MarkAuto-Sections", Pkg.Section())) + if(InstPkg->CurrentVer == 0 && InstVer->Section != 0 && ConfigValueInSubTree("APT::Never-MarkAuto-Sections", InstVer.Section())) { if(DebugAutoInstall == true) std::clog << OutputInDepth(Depth) << "Setting NOT as auto-installed (direct " @@ -1312,14 +1305,18 @@ bool pkgDepCache::IsInstallOkMultiArchSameVersionSynced(PkgIterator const &Pkg, GrpIterator const Grp = Pkg.Group(); for (PkgIterator P = Grp.PackageList(); P.end() == false; P = Grp.NextPkg(P)) { - // not installed or version synced: fine by definition + // not installed or self-check: fine by definition + if (P->CurrentVer == 0 || P == Pkg) + continue; + + // not having a candidate or being in sync // (simple string-compare as stuff like '1' == '0:1-0' can't happen here) - if (P->CurrentVer == 0 || strcmp(Pkg.CandVersion(), P.CandVersion()) == 0) + VerIterator CV = PkgState[P->ID].CandidateVerIter(*this); + if (CV.end() == true || strcmp(Pkg.CandVersion(), CV.VerStr()) == 0) continue; + // packages losing M-A:same can be out-of-sync - VerIterator CV = PkgState[P->ID].CandidateVerIter(*this); - if (unlikely(CV.end() == true) || - (CV->MultiArch & pkgCache::Version::Same) != pkgCache::Version::Same) + if ((CV->MultiArch & pkgCache::Version::Same) != pkgCache::Version::Same) continue; // not downloadable means the package is obsolete, so allow out-of-sync @@ -1329,7 +1326,8 @@ bool pkgDepCache::IsInstallOkMultiArchSameVersionSynced(PkgIterator const &Pkg, PkgState[Pkg->ID].iFlags |= AutoKept; if (unlikely(DebugMarker == true)) std::clog << OutputInDepth(Depth) << "Ignore MarkInstall of " << Pkg - << " as its M-A:same siblings are not version-synced" << std::endl; + << " as it is not in sync with its M-A:same sibling " << P + << " (" << Pkg.CandVersion() << " != " << CV.VerStr() << ")" << std::endl; return false; } @@ -1374,7 +1372,7 @@ bool pkgDepCache::IsInstallOkDependenciesSatisfiableByCandidates(PkgIterator con // the dependency is critical, but can't be installed, so discard the candidate // as the problemresolver will trip over it otherwise trying to install it (#735967) - if (Pkg->CurrentVer != 0) + if (Pkg->CurrentVer != 0 && (PkgState[Pkg->ID].iFlags & Protected) != Protected) SetCandidateVersion(Pkg.CurrentVer()); return false; } @@ -1678,7 +1676,7 @@ pkgCache::VerIterator pkgDepCache::Policy::GetCandidateVer(PkgIterator const &Pk { /* Not source/not automatic versions cannot be a candidate version unless they are already installed */ - VerIterator Last(*(pkgCache *)this,0); + VerIterator Last; for (VerIterator I = Pkg.VersionList(); I.end() == false; ++I) { @@ -1960,3 +1958,17 @@ bool pkgDepCache::Sweep() /*{{{*/ return true; } /*}}}*/ +// DepCache::MarkAndSweep /*{{{*/ +bool pkgDepCache::MarkAndSweep(InRootSetFunc &rootFunc) +{ + return MarkRequired(rootFunc) && Sweep(); +} +bool pkgDepCache::MarkAndSweep() +{ + std::auto_ptr<InRootSetFunc> f(GetRootSetFunc()); + if(f.get() != NULL) + return MarkAndSweep(*f.get()); + else + return false; +} + /*}}}*/ |