diff --git a/lib/package_alternatives.c b/lib/package_alternatives.c index e4d94e39..510b5361 100644 --- a/lib/package_alternatives.c +++ b/lib/package_alternatives.c @@ -150,7 +150,7 @@ create_symlinks(struct xbps_handle *xhp, xbps_array_t a, const char *grname) cnt = xbps_array_count(a); for (i = 0; i < cnt; i++) { xbps_string_t str; - char *tgt_dup, *tgt_dir; + char *tgt_dup, *tgt_dir, *lnk_dup, *lnk_dir; char *l, *lnk, *tgt = NULL; const char *tgt0; int rv; @@ -171,12 +171,34 @@ create_symlinks(struct xbps_handle *xhp, xbps_array_t a, const char *grname) xbps_dbg_printf(xhp, "failed to create symlink" "target dir '%s' for group '%s': %s\n", tgt, grname, strerror(errno)); + free(tgt_dup); free(tgt); free(l); return rv; } } free(tgt); + /* always create link dir, for dangling symlinks */ + lnk_dup = strdup(l); + assert(lnk_dup); + lnk_dir = dirname(lnk_dup); + lnk = xbps_xasprintf("%s%s", xhp->rootdir, lnk_dir); + if (xbps_mkpath(lnk, 0755) != 0) { + if (errno != EEXIST) { + rv = errno; + xbps_dbg_printf(xhp, "failed to create symlink" + "dir '%s' for group '%s': %s\n", + lnk, grname, strerror(errno)); + free(tgt_dup); + free(tgt); + free(lnk_dup); + free(lnk); + free(l); + return rv; + } + } + free(lnk); + free(lnk_dup); if (l[0] != '/') { lnk = xbps_xasprintf("%s%s/%s", xhp->rootdir, tgt_dir, l); diff --git a/tests/xbps/xbps-alternatives/main.sh b/tests/xbps/xbps-alternatives/main.sh index e6368941..facd2903 100644 --- a/tests/xbps/xbps-alternatives/main.sh +++ b/tests/xbps/xbps-alternatives/main.sh @@ -36,7 +36,7 @@ register_one_dangling_head() { register_one_dangling_body() { mkdir -p repo pkg_A/usr/bin cd repo - xbps-create -A noarch -n A-1.1_1 -s "A pkg" --alternatives "file:/usr/bin/file:/usr/bin/fileA file2:file2:/usr/include/fileB" ../pkg_A + xbps-create -A noarch -n A-1.1_1 -s "A pkg" --alternatives "file:/usr/bin/file:/usr/bin/fileA file2:/usr/lib/fileB:/usr/include/fileB" ../pkg_A atf_check_equal $? 0 xbps-rindex -d -a $PWD/*.xbps atf_check_equal $? 0 @@ -54,9 +54,9 @@ register_one_dangling_body() { fi atf_check_equal $rv 0 rv=1 - if [ -h root/usr/include/file2 ]; then - lnk=$(readlink root/usr/include/file2) - if [ "$lnk" = "fileB" ]; then + if [ -h root/usr/lib/fileB ]; then + lnk=$(readlink -f root/usr/lib/fileB) + if [ "$lnk" = "$PWD/root/usr/include/fileB" ]; then rv=0 fi echo "A lnk: $lnk"