minstall: never follow symlinks when setting ownership

Since we're supposed to call this for each installed path, we only should go
through what we've installed and not what this point to, as it might be
outside our scope or not existent.

To do this, since shutil.chown doesn't expose the follow_symlink that os.chown
has, we can temporarily replace os.chown with a lambda that acutually passes
all the values as we want them, and then restore it to the built-in functions.
Not the nicest way, but fixes the issue without having to reimplement what
shutil does.

Fixes #3914
pull/4030/head
Marco Trevisan (Treviño) 6 years ago
parent 2d010727ed
commit 5de2a7910a
  1. 20
      mesonbuild/minstall.py

@ -79,6 +79,24 @@ def append_to_log(lf, line):
lf.write('\n') lf.write('\n')
lf.flush() lf.flush()
def set_chown(path, user=None, group=None, dir_fd=None, follow_symlinks=True):
# shutil.chown will call os.chown without passing all the parameters
# and particularly follow_symlinks, thus we replace it temporary
# with a lambda with all the parameters so that follow_symlinks will
# be actually passed properly.
# Not nice, but better than actually rewriting shutil.chown until
# this python bug is fixed: https://bugs.python.org/issue18108
real_os_chown = os.chown
try:
os.chown = lambda p, u, g: real_os_chown(p, u, g,
dir_fd=dir_fd,
follow_symlinks=follow_symlinks)
shutil.chown(path, user, group)
except:
raise
finally:
os.chown = real_os_chown
def set_chmod(path, mode, dir_fd=None, follow_symlinks=True): def set_chmod(path, mode, dir_fd=None, follow_symlinks=True):
try: try:
os.chmod(path, mode, dir_fd=dir_fd, follow_symlinks=follow_symlinks) os.chmod(path, mode, dir_fd=dir_fd, follow_symlinks=follow_symlinks)
@ -105,7 +123,7 @@ def set_mode(path, mode, default_umask):
# No chown() on Windows, and must set one of owner/group # No chown() on Windows, and must set one of owner/group
if not is_windows() and (mode.owner or mode.group) is not None: if not is_windows() and (mode.owner or mode.group) is not None:
try: try:
shutil.chown(path, mode.owner, mode.group) set_chown(path, mode.owner, mode.group, follow_symlinks=False)
except PermissionError as e: except PermissionError as e:
msg = '{!r}: Unable to set owner {!r} and group {!r}: {}, ignoring...' msg = '{!r}: Unable to set owner {!r} and group {!r}: {}, ignoring...'
print(msg.format(path, mode.owner, mode.group, e.strerror)) print(msg.format(path, mode.owner, mode.group, e.strerror))

Loading…
Cancel
Save