From: Erik van der Kouwe Date: Sat, 11 Dec 2010 18:20:31 +0000 (+0000) Subject: Workaround for circular dependency problem in pkgadd X-Git-Tag: v3.2.0~715 X-Git-Url: http://zhaoyanbai.com/repos/doc/man.3.txt?a=commitdiff_plain;h=7aab862a06acb735a1a6444fadfed836627b1ebe;p=minix.git Workaround for circular dependency problem in pkgadd --- diff --git a/commands/pkg_install/add/perform.c b/commands/pkg_install/add/perform.c index c56fdfba4..3f7e85795 100644 --- a/commands/pkg_install/add/perform.c +++ b/commands/pkg_install/add/perform.c @@ -134,7 +134,12 @@ static const struct pkg_meta_desc { { 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 mkdir_p(const char *path) @@ -1092,7 +1097,7 @@ check_implicit_conflict(struct pkg_task *pkg) } static int -check_dependencies(struct pkg_task *pkg) +check_dependencies(struct pkg_task *pkg, struct dependency_stack *dependency_stack) { plist_t *p; char *best_installed; @@ -1123,7 +1128,7 @@ check_dependencies(struct pkg_task *pkg) p->name); continue; } - if (pkg_do(p->name, 1, 0)) { + if (pkg_do(p->name, 1, 0, dependency_stack)) { if (ForceDepends) { warnx("Can't install dependency %s, " "continuing", p->name); @@ -1372,12 +1377,33 @@ check_license(struct pkg_task *pkg) * Install a single package. */ 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; int status, invalid_sig; 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)); status = -1; @@ -1489,7 +1515,7 @@ pkg_do(const char *pkgpath, int mark_automatic, int top_level) pkg->install_logdir_real = NULL; } - if (check_dependencies(pkg)) + if (check_dependencies(pkg, &dependency_stack_top)) goto nuke_pkgdb; } else { /* @@ -1497,7 +1523,7 @@ pkg_do(const char *pkgpath, int mark_automatic, int top_level) * Install/update dependencies first and * write the current package to disk afterwards. */ - if (check_dependencies(pkg)) + if (check_dependencies(pkg, &dependency_stack_top)) goto clean_memory; if (write_meta_data(pkg)) @@ -1581,7 +1607,7 @@ pkg_perform(lpkg_head_t *pkgs) lpkg_t *lpp; while ((lpp = TAILQ_FIRST(pkgs)) != NULL) { - if (pkg_do(lpp->lp_name, Automatic, 1)) + if (pkg_do(lpp->lp_name, Automatic, 1, NULL)) ++errors; TAILQ_REMOVE(pkgs, lpp, lp_link); free_lpkg(lpp);