cfgfiledict = grabdict(self.vartree.dbapi._conf_mem_file)
stale_confmem = []
- protected_symlinks = []
+ protected_symlinks = {}
unmerge_orphans = "unmerge-orphans" in self.settings.features
calc_prelink = "prelink-checksums" in self.settings.features
break
if symlink_orphan:
- protected_symlinks.append(relative_path)
+ protected_symlinks.setdefault(
+ (statobj.st_dev, statobj.st_ino),
+ []).append(relative_path)
if is_owned:
show_unmerge("---", unmerge_desc["replaced"], file_type, obj)
if lstatobj is None or not stat.S_ISDIR(lstatobj.st_mode):
show_unmerge("---", unmerge_desc["!dir"], file_type, obj)
continue
- mydirs.add(obj)
+ mydirs.add((obj, (lstatobj.st_dev, lstatobj.st_ino)))
elif pkgfiles[objkey][0] == "sym":
if not islink:
show_unmerge("---", unmerge_desc["!sym"], file_type, obj)
break
if not all_owned:
- protected_symlinks.append(relative_path)
+ protected_symlinks.setdefault(
+ (statobj.st_dev, statobj.st_ino),
+ []).append(relative_path)
show_unmerge("---", unmerge_desc["!empty"],
file_type, obj)
continue
mydirs = sorted(mydirs)
mydirs.reverse()
- for obj in mydirs:
+ for obj, inode_key in mydirs:
try:
if bsd_chflags:
lstatobj = os.lstat(obj)
if e.errno != errno.ENOENT:
show_unmerge("---", unmerge_desc["!empty"], "dir", obj)
del e
+ else:
+ # When a directory is successfully removed, there's
+ # no need to protect symlinks that point to it.
+ unmerge_syms = protected_symlinks.pop(inode_key, None)
+ if unmerge_syms is not None:
+ for relative_path in unmerge_syms:
+ obj = os.path.join(real_root,
+ relative_path.lstrip(os.sep))
+ try:
+ unlink(obj, os.lstat(obj))
+ show_unmerge("<<<", "", "sym", obj)
+ except (OSError, IOError) as e:
+ if e.errno not in ignored_unlink_errnos:
+ raise
+ del e
+ show_unmerge("!!!", "", "sym", obj)
if protected_symlinks:
msg = "One or more symlinks to directories have been " + \
"via these symlinks remain accessible:"
lines = textwrap.wrap(msg, 72)
lines.append("")
- protected_symlinks.reverse()
- for f in protected_symlinks:
+ flat_list = set()
+ flat_list.update(*protected_symlinks.values())
+ flat_list = sorted(flat_list, reverse=True)
+ for f in flat_list:
lines.append("\t%s" % (os.path.join(real_root,
f.lstrip(os.sep))))
lines.append("")