aboutsummaryrefslogtreecommitdiff
path: root/mesonbuild/minstall.py
diff options
context:
space:
mode:
Diffstat (limited to 'mesonbuild/minstall.py')
-rw-r--r--mesonbuild/minstall.py37
1 files changed, 31 insertions, 6 deletions
diff --git a/mesonbuild/minstall.py b/mesonbuild/minstall.py
index f08a6b3..748f06b 100644
--- a/mesonbuild/minstall.py
+++ b/mesonbuild/minstall.py
@@ -69,9 +69,9 @@ class DirMaker:
for d in self.dirs:
append_to_log(self.lf, d)
-def is_executable(path):
+def is_executable(path, follow_symlinks=False):
'''Checks whether any of the "x" bits are set in the source file mode.'''
- return bool(os.stat(path).st_mode & 0o111)
+ return bool(os.stat(path, follow_symlinks=follow_symlinks).st_mode & 0o111)
def append_to_log(lf, line):
lf.write(line)
@@ -79,13 +79,38 @@ def append_to_log(lf, line):
lf.write('\n')
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):
+ try:
+ os.chmod(path, mode, dir_fd=dir_fd, follow_symlinks=follow_symlinks)
+ except (NotImplementedError, OSError, SystemError) as e:
+ if not os.path.islink(path):
+ os.chmod(path, mode, dir_fd=dir_fd)
+
def sanitize_permissions(path, umask):
if umask is None:
return
- new_perms = 0o777 if is_executable(path) else 0o666
+ new_perms = 0o777 if is_executable(path, follow_symlinks=False) else 0o666
new_perms &= ~umask
try:
- os.chmod(path, new_perms)
+ set_chmod(path, new_perms, follow_symlinks=False)
except PermissionError as e:
msg = '{!r}: Unable to set permissions {!r}: {}, ignoring...'
print(msg.format(path, new_perms, e.strerror))
@@ -98,7 +123,7 @@ def set_mode(path, mode, default_umask):
# No chown() on Windows, and must set one of owner/group
if not is_windows() and (mode.owner or mode.group) is not None:
try:
- shutil.chown(path, mode.owner, mode.group)
+ set_chown(path, mode.owner, mode.group, follow_symlinks=False)
except PermissionError as e:
msg = '{!r}: Unable to set owner {!r} and group {!r}: {}, ignoring...'
print(msg.format(path, mode.owner, mode.group, e.strerror))
@@ -116,7 +141,7 @@ def set_mode(path, mode, default_umask):
# NOTE: On Windows you can set read/write perms; the rest are ignored
if mode.perms_s is not None:
try:
- os.chmod(path, mode.perms)
+ set_chmod(path, mode.perms, follow_symlinks=False)
except PermissionError as e:
msg = '{!r}: Unable to set permissions {!r}: {}, ignoring...'
print(msg.format(path, mode.perms_s, e.strerror))