Browse Source

* apt-pkg/deb/dpkgpm.cc:

- use std::vector instead of fixed size arrays to store args and
    multiarch-packagename strings
  - load the dpkg base arguments only one time and reuse them later
* cmdline/apt-get.cc:
  - follow Provides in the evaluation of saving candidates, too, for
    statisfying garbage package dependencies (Closes: #640590)
* apt-pkg/algorithms.cc:
  - if a package is garbage, don't try to save it with FixByInstall
debian/1.8.y
David Kalnischkies 11 years ago
parent
commit
778559db79
  1. 2
      apt-pkg/algorithms.cc
  2. 150
      apt-pkg/deb/dpkgpm.cc
  3. 59
      cmdline/apt-get.cc
  4. 11
      debian/changelog

2
apt-pkg/algorithms.cc

@ -1002,7 +1002,7 @@ bool pkgProblemResolver::Resolve(bool BrokenFix)
if (BrokenFix == false || DoUpgrade(I) == false)
{
// Consider other options
if (InOr == false)
if (InOr == false || Cache[I].Garbage == true)
{
if (Debug == true)
clog << " Removing " << I.FullName(false) << " rather than change " << Start.TargetPkg().FullName(false) << endl;

150
apt-pkg/deb/dpkgpm.cc

@ -887,6 +887,28 @@ bool pkgDPkgPM::Go(int OutStatusFd)
// create log
OpenLog();
// Generate the base argument list for dpkg
std::vector<const char *> Args;
unsigned long StartSize = 0;
string const Tmp = _config->Find("Dir::Bin::dpkg","dpkg");
Args.push_back(Tmp.c_str());
StartSize += Tmp.length();
// Stick in any custom dpkg options
Configuration::Item const *Opts = _config->Tree("DPkg::Options");
if (Opts != 0)
{
Opts = Opts->Child;
for (; Opts != 0; Opts = Opts->Next)
{
if (Opts->Value.empty() == true)
continue;
Args.push_back(Opts->Value.c_str());
StartSize += Opts->Value.length();
}
}
size_t const BaseArgs = Args.size();
// this loop is runs once per operation
for (vector<Item>::const_iterator I = List.begin(); I != List.end();)
{
@ -908,11 +930,12 @@ bool pkgDPkgPM::Go(int OutStatusFd)
for (; J != List.end() && J->Op == I->Op; ++J)
/* nothing */;
// Generate the argument list
const char *Args[MaxArgs + 50];
// keep track of allocated strings for multiarch package names
char *Packages[MaxArgs + 50];
unsigned int pkgcount = 0;
std::vector<char *> Packages;
// start with the baseset of arguments
unsigned long Size = StartSize;
Args.erase(Args.begin() + BaseArgs, Args.end());
// Now check if we are within the MaxArgs limit
//
@ -922,91 +945,67 @@ bool pkgDPkgPM::Go(int OutStatusFd)
// - with the split they may now be configured in different
// runs
if (J - I > (signed)MaxArgs)
{
J = I + MaxArgs;
unsigned int n = 0;
unsigned long Size = 0;
string const Tmp = _config->Find("Dir::Bin::dpkg","dpkg");
Args[n++] = Tmp.c_str();
Size += strlen(Args[n-1]);
// Stick in any custom dpkg options
Configuration::Item const *Opts = _config->Tree("DPkg::Options");
if (Opts != 0)
Args.reserve(MaxArgs + 10);
}
else
{
Opts = Opts->Child;
for (; Opts != 0; Opts = Opts->Next)
{
if (Opts->Value.empty() == true)
continue;
Args[n++] = Opts->Value.c_str();
Size += Opts->Value.length();
}
Args.reserve((J - I) + 10);
}
char status_fd_buf[20];
int fd[2];
pipe(fd);
Args[n++] = "--status-fd";
Size += strlen(Args[n-1]);
#define ADDARG(X) Args.push_back(X); Size += strlen(X)
#define ADDARGC(X) Args.push_back(X); Size += sizeof(X) - 1
ADDARGC("--status-fd");
char status_fd_buf[20];
snprintf(status_fd_buf,sizeof(status_fd_buf),"%i", fd[1]);
Args[n++] = status_fd_buf;
Size += strlen(Args[n-1]);
ADDARG(status_fd_buf);
switch (I->Op)
{
case Item::Remove:
Args[n++] = "--force-depends";
Size += strlen(Args[n-1]);
Args[n++] = "--force-remove-essential";
Size += strlen(Args[n-1]);
Args[n++] = "--remove";
Size += strlen(Args[n-1]);
ADDARGC("--force-depends");
ADDARGC("--force-remove-essential");
ADDARGC("--remove");
break;
case Item::Purge:
Args[n++] = "--force-depends";
Size += strlen(Args[n-1]);
Args[n++] = "--force-remove-essential";
Size += strlen(Args[n-1]);
Args[n++] = "--purge";
Size += strlen(Args[n-1]);
ADDARGC("--force-depends");
ADDARGC("--force-remove-essential");
ADDARGC("--purge");
break;
case Item::Configure:
Args[n++] = "--configure";
Size += strlen(Args[n-1]);
ADDARGC("--configure");
break;
case Item::ConfigurePending:
Args[n++] = "--configure";
Size += strlen(Args[n-1]);
Args[n++] = "--pending";
Size += strlen(Args[n-1]);
ADDARGC("--configure");
ADDARGC("--pending");
break;
case Item::TriggersPending:
Args[n++] = "--triggers-only";
Size += strlen(Args[n-1]);
Args[n++] = "--pending";
Size += strlen(Args[n-1]);
ADDARGC("--triggers-only");
ADDARGC("--pending");
break;
case Item::Install:
Args[n++] = "--unpack";
Size += strlen(Args[n-1]);
Args[n++] = "--auto-deconfigure";
Size += strlen(Args[n-1]);
ADDARGC("--unpack");
ADDARGC("--auto-deconfigure");
break;
}
if (NoTriggers == true && I->Op != Item::TriggersPending &&
I->Op != Item::ConfigurePending)
{
Args[n++] = "--no-triggers";
Size += strlen(Args[n-1]);
ADDARGC("--no-triggers");
}
#undef ADDARGC
// Write in the file or package names
if (I->Op == Item::Install)
@ -1015,10 +1014,10 @@ bool pkgDPkgPM::Go(int OutStatusFd)
{
if (I->File[0] != '/')
return _error->Error("Internal Error, Pathname to install is not absolute '%s'",I->File.c_str());
Args[n++] = I->File.c_str();
Size += strlen(Args[n-1]);
Args.push_back(I->File.c_str());
Size += I->File.length();
}
}
}
else
{
string const nativeArch = _config->Find("APT::Architecture");
@ -1030,29 +1029,35 @@ bool pkgDPkgPM::Go(int OutStatusFd)
if (I->Op == Item::Configure && disappearedPkgs.find(I->Pkg.Name()) != disappearedPkgs.end())
continue;
if (I->Pkg.Arch() == nativeArch || !strcmp(I->Pkg.Arch(), "all"))
Args[n++] = I->Pkg.Name();
{
char const * const name = I->Pkg.Name();
ADDARG(name);
}
else
{
Packages[pkgcount] = strdup(I->Pkg.FullName(false).c_str());
Args[n++] = Packages[pkgcount++];
char * const fullname = strdup(I->Pkg.FullName(false).c_str());
Packages.push_back(fullname);
ADDARG(fullname);
}
Size += strlen(Args[n-1]);
}
// skip configure action if all sheduled packages disappeared
if (oldSize == Size)
continue;
}
Args[n] = 0;
#undef ADDARG
J = I;
if (_config->FindB("Debug::pkgDPkgPM",false) == true)
{
for (unsigned int k = 0; k != n; k++)
clog << Args[k] << ' ';
for (std::vector<const char *>::const_iterator a = Args.begin();
a != Args.end(); ++a)
clog << *a << ' ';
clog << endl;
continue;
}
Args.push_back(NULL);
cout << flush;
clog << flush;
cerr << flush;
@ -1162,7 +1167,7 @@ bool pkgDPkgPM::Go(int OutStatusFd)
/* No Job Control Stop Env is a magic dpkg var that prevents it
from using sigstop */
putenv((char *)"DPKG_NO_TSTP=yes");
execvp(Args[0],(char **)Args);
execvp(Args[0], (char**) &Args[0]);
cerr << "Could not exec dpkg!" << endl;
_exit(100);
}
@ -1188,10 +1193,11 @@ bool pkgDPkgPM::Go(int OutStatusFd)
sigemptyset(&sigmask);
sigprocmask(SIG_BLOCK,&sigmask,&original_sigmask);
/* clean up the temporary allocation for multiarch package names in
the parent, so we don't leak memory when we return. */
for (unsigned int i = 0; i < pkgcount; i++)
free(Packages[i]);
/* free vectors (and therefore memory) as we don't need the included data anymore */
for (std::vector<char *>::const_iterator p = Packages.begin();
p != Packages.end(); ++p)
free(*p);
Packages.clear();
// the result of the waitpid call
int res;

59
cmdline/apt-get.cc

@ -1684,8 +1684,9 @@ bool DoAutomaticRemove(CacheFile &Cache)
// install it in the first place, so nuke it instead of show it
if (Cache[Pkg].Install() == true && Pkg.CurrentVer() == 0)
{
if (Pkg.CandVersion() != 0)
tooMuch.insert(Pkg);
Cache->MarkDelete(Pkg, false);
tooMuch.insert(Pkg);
}
// only show stuff in the list that is not yet marked for removal
else if(hideAutoRemove == false && Cache[Pkg].Delete() == false)
@ -1709,33 +1710,41 @@ bool DoAutomaticRemove(CacheFile &Cache)
bool Changed;
do {
Changed = false;
for (APT::PackageSet::const_iterator P = tooMuch.begin();
P != tooMuch.end() && Changed == false; ++P)
for (APT::PackageSet::const_iterator Pkg = tooMuch.begin();
Pkg != tooMuch.end() && Changed == false; ++Pkg)
{
for (pkgCache::DepIterator R = P.RevDependsList();
R.end() == false; ++R)
{
if (R.IsNegative() == true ||
Cache->IsImportantDep(R) == false)
continue;
pkgCache::PkgIterator N = R.ParentPkg();
if (N.end() == true || (N->CurrentVer == 0 && (*Cache)[N].Install() == false))
continue;
if (Debug == true)
std::clog << "Save " << P << " as another installed garbage package depends on it" << std::endl;
Cache->MarkInstall(P, false);
if(hideAutoRemove == false)
APT::PackageSet too;
too.insert(Pkg);
for (pkgCache::PrvIterator Prv = Cache[Pkg].CandidateVerIter(Cache).ProvidesList();
Prv.end() == false; ++Prv)
too.insert(Prv.ParentPkg());
for (APT::PackageSet::const_iterator P = too.begin();
P != too.end() && Changed == false; ++P) {
for (pkgCache::DepIterator R = P.RevDependsList();
R.end() == false; ++R)
{
++autoRemoveCount;
if (smallList == false)
{
autoremovelist += P.FullName(true) + " ";
autoremoveversions += string(Cache[P].CandVersion) + "\n";
}
if (R.IsNegative() == true ||
Cache->IsImportantDep(R) == false)
continue;
pkgCache::PkgIterator N = R.ParentPkg();
if (N.end() == true || (N->CurrentVer == 0 && (*Cache)[N].Install() == false))
continue;
if (Debug == true)
std::clog << "Save " << Pkg << " as another installed garbage package depends on it" << std::endl;
Cache->MarkInstall(Pkg, false);
if (hideAutoRemove == false)
{
++autoRemoveCount;
if (smallList == false)
{
autoremovelist += Pkg.FullName(true) + " ";
autoremoveversions += string(Cache[Pkg].CandVersion) + "\n";
}
}
tooMuch.erase(Pkg);
Changed = true;
break;
}
tooMuch.erase(P);
Changed = true;
break;
}
}
} while (Changed == true);

11
debian/changelog

@ -1,9 +1,18 @@
apt (0.8.15.9) unstable; urgency=low
apt (0.8.15.9) UNRELEASED; urgency=low
[ David Kalnischkies ]
* doc/apt-get.8.xml:
- change wording of autoremove description as suggested
by Robert Simmons, thanks! (Closes: #641490)
* apt-pkg/deb/dpkgpm.cc:
- use std::vector instead of fixed size arrays to store args and
multiarch-packagename strings
- load the dpkg base arguments only one time and reuse them later
* cmdline/apt-get.cc:
- follow Provides in the evaluation of saving candidates, too, for
statisfying garbage package dependencies (Closes: #640590)
* apt-pkg/algorithms.cc:
- if a package is garbage, don't try to save it with FixByInstall
-- David Kalnischkies <kalnischkies@gmail.com> Wed, 14 Sep 2011 21:01:56 +0200

Loading…
Cancel
Save