Whilst trying to write some other modifications to setup.exe, I've found what looks like an obscure bug introduced in the following change:
> CVSROOT: /sourceware/projects/cygwin-apps-home/cvsfiles > Module name: setup > Changes by: [email protected] 2009-05-07 14:14:59 > > Modified files: > . : ChangeLog package_db.cc > > Log message: > * package_db.cc (ConnectedLoopFinder::doIt): Revert patch from > 2008-08-29. Add dumb hardcoded algorithm to make sure base-cygwin > and base-passwd are always the first packages in the postinstall > executable order. > > Patches: > http://sourceware.org/cgi-bin/cvsweb.cgi/setup/ChangeLog.diff?cvsroot=cygwin-apps&r1=2.618&r2=2.619 > http://sourceware.org/cgi-bin/cvsweb.cgi/setup/package_db.cc.diff?cvsroot=cygwin-apps&r1=2.40&r2=2.41 This change to package_db.cc doesn't do what it claims as casecompare() returns 0 to indicate equality. Since db.packages is sorted alphabetically, it looks like it actually inserts the dependencies of the first (in alphabetical order) installed package (assuming that's not base-cygwin or base-passwd), twice. The log output actually shows this happening. In my case aewm++ is the installed package which comes first in alphabetical order, which is why the logged dependency order list before running the postinstall scripts starts "Dependency order of packages: base-cygwin base-passwd cygwin libgcc1 libXau6 libXdmcp6 libxcb1 libX11_6 libXext6 aewm++ aewm++ ..." Attached is the obvious patch to fix this, but I'm not sure that's right, as it runs base-passwd and base-cygwin in the opposite order to the comment ("Dependency order of packages: base-passwd cygwin base-cygwin ..."), which isn't very clear about if they merely both have to run first, or in a given order
>From aa8c426c310b932b3791b3d2d25682448c7d1f52 Mon Sep 17 00:00:00 2001 From: Jon TURNEY <[email protected]> Date: Fri, 19 Nov 2010 00:51:52 +0000 Subject: [PATCH] Obvious and probably incorrect fix for incorrect use of casecompare() casecompare() returns 0 for equality also adjust visit() so it does nothing when used to visit a node a second time (so explicit 'base-passwd' visit won't add a duplicate entry if it's already been visited, which also allows the recursive use to be simplified. Signed-off-by: Jon TURNEY <[email protected]> --- package_db.cc | 13 +++++++------ 1 files changed, 7 insertions(+), 6 deletions(-) diff --git a/package_db.cc b/package_db.cc index 45dd3ce..f01624c 100644 --- a/package_db.cc +++ b/package_db.cc @@ -250,7 +250,7 @@ ConnectedLoopFinder::doIt() for (size_t i = 0; i < db.packages.size(); ++i) { packagemeta &pkg (*db.packages[i]); - if (pkg.installed && casecompare (pkg.name, "base-cygwin")) + if (pkg.installed && (casecompare (pkg.name, "base-cygwin") == 0)) { visit (i); break; @@ -259,7 +259,7 @@ ConnectedLoopFinder::doIt() for (size_t i = 0; i < db.packages.size(); ++i) { packagemeta &pkg (*db.packages[i]); - if (pkg.installed && casecompare (pkg.name, "base-passwd")) + if (pkg.installed && (casecompare (pkg.name, "base-passwd") == 0)) { visit (i); break; @@ -297,6 +297,10 @@ ConnectedLoopFinder::visit(size_t const nodeToVisit) if (!db.packages[nodeToVisit]->installed) /* Can't visit this node, and it is not less than any visted node */ return db.packages.size() + 1; + + if (visitOrder[nodeToVisit]) + return visitOrder[nodeToVisit]; + ++visited; visitOrder[nodeToVisit] = visited; @@ -324,10 +328,7 @@ ConnectedLoopFinder::visit(size_t const nodeToVisit) log (LOG_PLAIN) << "Search for package '" << (*i)->packageName() << "' failed." << endLog; else { - if (visitOrder[nodeJustVisited]) - minimumVisitId = std::min (minimumVisitId, visitOrder[nodeJustVisited]); - else - minimumVisitId = std::min (minimumVisitId, visit (nodeJustVisited)); + minimumVisitId = std::min (minimumVisitId, visit (nodeJustVisited)); } /* next and clause */ ++dp; -- 1.7.2.3
