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 },
};
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);