summaryrefslogtreecommitdiffstats
path: root/pym/portage.py
diff options
context:
space:
mode:
authorZac Medico <zmedico@gentoo.org>2007-09-26 04:46:33 +0000
committerZac Medico <zmedico@gentoo.org>2007-09-26 04:46:33 +0000
commit2aec000c6ac2b236bdd9dba00d3a001d7fdcea7b (patch)
treed405b861ab2764e1a3ac9a60318dbc3b95c872f0 /pym/portage.py
parent8e2d9cd5ab9aabbfe1e65f635e7a10c473240d69 (diff)
downloadportage-2aec000c6ac2b236bdd9dba00d3a001d7fdcea7b.tar.gz
portage-2aec000c6ac2b236bdd9dba00d3a001d7fdcea7b.tar.bz2
portage-2aec000c6ac2b236bdd9dba00d3a001d7fdcea7b.zip
Bugs #168772 and #193695 - During unmerge, only ignore specific
exceptions raised from unlink() and rmdir() calls. Bug #193695 - Add support for FreeBSD chflags during unmerge. This code is adapted from the code that already exists in movefile() for the merge phase. In movefile() FreeBSD chflags handling, use chflags instead of lchflags when temporarily adjusting the flags on the parent directory since we want to follow any symlinks to the real parent directory. (trunk r7803:7807) svn path=/main/branches/2.1.2/; revision=7832
Diffstat (limited to 'pym/portage.py')
-rw-r--r--pym/portage.py83
1 files changed, 64 insertions, 19 deletions
diff --git a/pym/portage.py b/pym/portage.py
index 47d204b63..39ecb0dab 100644
--- a/pym/portage.py
+++ b/pym/portage.py
@@ -4148,9 +4148,11 @@ def movefile(src,dest,newmtime=None,sstat=None,mysettings=None):
if bsd_chflags:
if destexists and dstat.st_flags != 0:
bsd_chflags.lchflags(dest, 0)
+ # Use normal stat/chflags for the parent since we want to
+ # follow any symlinks to the real parent directory.
pflags = os.stat(os.path.dirname(dest)).st_flags
if pflags != 0:
- bsd_chflags.lchflags(os.path.dirname(dest), 0)
+ bsd_chflags.chflags(os.path.dirname(dest), 0)
if destexists:
if stat.S_ISLNK(dstat[stat.ST_MODE]):
@@ -4257,7 +4259,7 @@ def movefile(src,dest,newmtime=None,sstat=None,mysettings=None):
if bsd_chflags:
# Restore the flags we saved before moving
if pflags:
- bsd_chflags.lchflags(os.path.dirname(dest), pflags)
+ bsd_chflags.chflags(os.path.dirname(dest), pflags)
return newmtime
@@ -7446,7 +7448,30 @@ class dblink:
#process symlinks second-to-last, directories last.
mydirs = []
+ ignored_unlink_errnos = (errno.ENOENT, errno.EISDIR)
modprotect = os.path.join(self.vartree.root, "lib/modules/")
+
+ def unlink(file_name, lstatobj):
+ if bsd_chflags:
+ if lstatobj.st_flags != 0:
+ bsd_chflags.lchflags(file_name, 0)
+ parent_name = os.path.dirname(file_name)
+ # Use normal stat/chflags for the parent since we want to
+ # follow any symlinks to the real parent directory.
+ pflags = os.stat(parent_name).st_flags
+ if pflags != 0:
+ bsd_chflags.chflags(parent_name, 0)
+ try:
+ if not stat.S_ISLNK(lstatobj.st_mode):
+ # Remove permissions to ensure that any hardlinks to
+ # suid/sgid files are rendered harmless.
+ os.chmod(file_name, 0)
+ os.unlink(file_name)
+ finally:
+ if bsd_chflags and pflags != 0:
+ # Restore the parent flags we saved before unlinking
+ bsd_chflags.chflags(parent_name, pflags)
+
def show_unmerge(zing, desc, file_type, file_name):
writemsg_stdout("%s %s %s %s\n" % \
(zing, desc.ljust(8), file_type, file_name))
@@ -7496,13 +7521,11 @@ class dblink:
not (islink and statobj and stat.S_ISDIR(statobj.st_mode)) and \
not self.isprotected(obj):
try:
- # Remove permissions to ensure that any hardlinks to
- # suid/sgid files are rendered harmless.
- if statobj and not islink:
- os.chmod(obj, 0)
- os.unlink(obj)
+ unlink(obj, lstatobj)
except EnvironmentError, e:
- pass
+ if e.errno not in ignored_unlink_errnos:
+ raise
+ del e
show_unmerge("<<<", "", file_type, obj)
continue
@@ -7528,9 +7551,12 @@ class dblink:
# contents as a directory even if it happens to correspond
# to a symlink when it's merged to the live filesystem.
try:
- os.unlink(obj)
+ unlink(obj, lstatobj)
show_unmerge("<<<", "", file_type, obj)
- except (OSError,IOError),e:
+ except (OSError, IOError),e:
+ if e.errno not in ignored_unlink_errnos:
+ raise
+ del e
show_unmerge("!!!", "", file_type, obj)
elif pkgfiles[objkey][0] == "obj":
if statobj is None or not stat.S_ISREG(statobj.st_mode):
@@ -7550,13 +7576,11 @@ class dblink:
show_unmerge("---", "!md5", file_type, obj)
continue
try:
- # Remove permissions to ensure that any hardlinks to
- # suid/sgid files are rendered harmless.
- if not islink:
- os.chmod(obj, 0)
- os.unlink(obj)
+ unlink(obj, lstatobj)
except (OSError,IOError),e:
- pass
+ if e.errno not in ignored_unlink_errnos:
+ raise
+ del e
show_unmerge("<<<", "", file_type, obj)
elif pkgfiles[objkey][0] == "fif":
if not stat.S_ISFIFO(lstatobj[stat.ST_MODE]):
@@ -7571,10 +7595,31 @@ class dblink:
for obj in mydirs:
try:
- os.rmdir(obj)
+ if bsd_chflags:
+ lstatobj = os.lstat(obj)
+ if lstatobj.st_flags != 0:
+ bsd_chflags.lchflags(obj, 0)
+ parent_name = os.path.dirname(obj)
+ # Use normal stat/chflags for the parent since we want to
+ # follow any symlinks to the real parent directory.
+ pflags = os.stat(parent_name).st_flags
+ if pflags != 0:
+ bsd_chflags.chflags(parent_name, 0)
+ try:
+ os.rmdir(obj)
+ finally:
+ if bsd_chflags and pflags != 0:
+ # Restore the parent flags we saved before unlinking
+ bsd_chflags.chflags(parent_name, pflags)
show_unmerge("<<<", "", "dir", obj)
- except (OSError, IOError):
- show_unmerge("---", "!empty", "dir", obj)
+ except EnvironmentError, e:
+ if e.errno not in (errno.ENOENT,
+ errno.EEXIST, errno.ENOTEMPTY,
+ errno.ENOTDIR):
+ raise
+ if e.errno != errno.ENOENT:
+ show_unmerge("---", "!empty", "dir", obj)
+ del e
#remove self from vartree database so that our own virtual gets zapped if we're the last node
self.vartree.zap(self.mycpv)