Workaround for circular dependency problem in pkgadd

This commit is contained in:
Erik van der Kouwe 2010-12-11 18:20:31 +00:00
parent 4fe0dfa9aa
commit 7aab862a06

View file

@ -134,7 +134,12 @@ static const struct pkg_meta_desc {
{ 0, NULL, 0, 0 }, { 0, NULL, 0, 0 },
}; };
static int pkg_do(const char *, int, int); struct dependency_stack {
struct dependency_stack *prev;
const char *pkgpath;
};
static int pkg_do(const char *, int, int, struct dependency_stack *);
static int static int
mkdir_p(const char *path) mkdir_p(const char *path)
@ -1092,7 +1097,7 @@ check_implicit_conflict(struct pkg_task *pkg)
} }
static int static int
check_dependencies(struct pkg_task *pkg) check_dependencies(struct pkg_task *pkg, struct dependency_stack *dependency_stack)
{ {
plist_t *p; plist_t *p;
char *best_installed; char *best_installed;
@ -1123,7 +1128,7 @@ check_dependencies(struct pkg_task *pkg)
p->name); p->name);
continue; continue;
} }
if (pkg_do(p->name, 1, 0)) { if (pkg_do(p->name, 1, 0, dependency_stack)) {
if (ForceDepends) { if (ForceDepends) {
warnx("Can't install dependency %s, " warnx("Can't install dependency %s, "
"continuing", p->name); "continuing", p->name);
@ -1372,12 +1377,33 @@ check_license(struct pkg_task *pkg)
* Install a single package. * Install a single package.
*/ */
static int static int
pkg_do(const char *pkgpath, int mark_automatic, int top_level) pkg_do(const char *pkgpath, int mark_automatic, int top_level,
struct dependency_stack *dependency_stack)
{ {
char *archive_name; char *archive_name;
int status, invalid_sig; int status, invalid_sig;
struct pkg_task *pkg; struct pkg_task *pkg;
/* workaround 2010-12-10: prevent endless recursion for circular dependencies */
struct dependency_stack dependency_stack_top;
dependency_stack_top.prev = dependency_stack;
dependency_stack_top.pkgpath = pkgpath;
while (dependency_stack) {
if (strcmp(dependency_stack->pkgpath, pkgpath) == 0) {
fprintf(stderr, "warning: ignoring circular dependency:\n");
dependency_stack = &dependency_stack_top;
while (dependency_stack) {
fprintf(stderr, "- %s\n", dependency_stack->pkgpath);
dependency_stack = dependency_stack->prev;
}
return 0;
}
dependency_stack = dependency_stack->prev;
}
/* end workaround */
pkg = xcalloc(1, sizeof(*pkg)); pkg = xcalloc(1, sizeof(*pkg));
status = -1; status = -1;
@ -1489,7 +1515,7 @@ pkg_do(const char *pkgpath, int mark_automatic, int top_level)
pkg->install_logdir_real = NULL; pkg->install_logdir_real = NULL;
} }
if (check_dependencies(pkg)) if (check_dependencies(pkg, &dependency_stack_top))
goto nuke_pkgdb; goto nuke_pkgdb;
} else { } else {
/* /*
@ -1497,7 +1523,7 @@ pkg_do(const char *pkgpath, int mark_automatic, int top_level)
* Install/update dependencies first and * Install/update dependencies first and
* write the current package to disk afterwards. * write the current package to disk afterwards.
*/ */
if (check_dependencies(pkg)) if (check_dependencies(pkg, &dependency_stack_top))
goto clean_memory; goto clean_memory;
if (write_meta_data(pkg)) if (write_meta_data(pkg))
@ -1581,7 +1607,7 @@ pkg_perform(lpkg_head_t *pkgs)
lpkg_t *lpp; lpkg_t *lpp;
while ((lpp = TAILQ_FIRST(pkgs)) != NULL) { while ((lpp = TAILQ_FIRST(pkgs)) != NULL) {
if (pkg_do(lpp->lp_name, Automatic, 1)) if (pkg_do(lpp->lp_name, Automatic, 1, NULL))
++errors; ++errors;
TAILQ_REMOVE(pkgs, lpp, lp_link); TAILQ_REMOVE(pkgs, lpp, lp_link);
free_lpkg(lpp); free_lpkg(lpp);