diff options
author | Eli Schwartz <eschwartz@archlinux.org> | 2021-11-18 17:52:12 -0500 |
---|---|---|
committer | Eli Schwartz <eschwartz@archlinux.org> | 2022-08-23 21:07:00 -0400 |
commit | f8ebfdf7b1f33f88007d107791a661a17827be43 (patch) | |
tree | e577c3ebc1ed54d2ce75c345c761e28665b4de6b /mesonbuild | |
parent | b7245d3f273dd6ddadc1fe2c2d06dbe25c1b9b5f (diff) | |
download | meson-f8ebfdf7b1f33f88007d107791a661a17827be43.zip meson-f8ebfdf7b1f33f88007d107791a661a17827be43.tar.gz meson-f8ebfdf7b1f33f88007d107791a661a17827be43.tar.bz2 |
install modes should not apply sticky bit to files
This is generally a bad idea, e.g. it causes OSError on freebsd.
It also gets ignored by solaris and thus causes unittest failures.
The proper solution is to simply reject any attempt to set this, and log a
warning.
The install_emptydir function does apply the mode as well, and since it
is a directory it actually does something. This is the only place where
we don't reset the mode.
Although install_subdir also installs directories, and in theory it
could set the mode as well, that would be a new feature. Also it doesn't
provide much granularity and has mixed semantics with files. Better to
let people use install_emptydir + install_subdir.
Fixes #5902
Diffstat (limited to 'mesonbuild')
-rw-r--r-- | mesonbuild/interpreter/interpreter.py | 33 |
1 files changed, 27 insertions, 6 deletions
diff --git a/mesonbuild/interpreter/interpreter.py b/mesonbuild/interpreter/interpreter.py index 131f073..0521125 100644 --- a/mesonbuild/interpreter/interpreter.py +++ b/mesonbuild/interpreter/interpreter.py @@ -1894,6 +1894,7 @@ class Interpreter(InterpreterBase, HoldableObject): kwargs: 'kwargs.CustomTarget') -> build.CustomTarget: if kwargs['depfile'] and ('@BASENAME@' in kwargs['depfile'] or '@PLAINNAME@' in kwargs['depfile']): FeatureNew.single_use('substitutions in custom_target depfile', '0.47.0', self.subproject, location=node) + install_mode = self._warn_kwarg_install_mode_sticky(kwargs['install_mode']) # Don't mutate the kwargs @@ -1976,7 +1977,7 @@ class Interpreter(InterpreterBase, HoldableObject): feed=kwargs['feed'], install=kwargs['install'], install_dir=kwargs['install_dir'], - install_mode=kwargs['install_mode'], + install_mode=install_mode, install_tag=kwargs['install_tag'], backend=self.backend) self.add_target(tg.name, tg) @@ -2129,6 +2130,7 @@ class Interpreter(InterpreterBase, HoldableObject): def func_install_headers(self, node: mparser.BaseNode, args: T.Tuple[T.List['mesonlib.FileOrString']], kwargs: 'kwargs.FuncInstallHeaders') -> build.Headers: + install_mode = self._warn_kwarg_install_mode_sticky(kwargs['install_mode']) source_files = self.source_strings_to_files(args[0]) install_subdir = kwargs['subdir'] if install_subdir is not None: @@ -2150,7 +2152,7 @@ class Interpreter(InterpreterBase, HoldableObject): for childdir in dirs: h = build.Headers(dirs[childdir], os.path.join(install_subdir, childdir), kwargs['install_dir'], - kwargs['install_mode'], self.subproject) + install_mode, self.subproject) ret_headers.append(h) self.build.headers.append(h) @@ -2166,6 +2168,7 @@ class Interpreter(InterpreterBase, HoldableObject): def func_install_man(self, node: mparser.BaseNode, args: T.Tuple[T.List['mesonlib.FileOrString']], kwargs: 'kwargs.FuncInstallMan') -> build.Man: + install_mode = self._warn_kwarg_install_mode_sticky(kwargs['install_mode']) # We just need to narrow this, because the input is limited to files and # Strings as inputs, so only Files will be returned sources = self.source_strings_to_files(args[0]) @@ -2177,7 +2180,7 @@ class Interpreter(InterpreterBase, HoldableObject): if not 1 <= num <= 9: raise InvalidArguments('Man file must have a file extension of a number between 1 and 9') - m = build.Man(sources, kwargs['install_dir'], kwargs['install_mode'], + m = build.Man(sources, kwargs['install_dir'], install_mode, self.subproject, kwargs['locale']) self.build.man.append(m) @@ -2321,6 +2324,21 @@ class Interpreter(InterpreterBase, HoldableObject): 'permissions arg to be a string or false') return FileMode(*install_mode) + + # This is either ignored on basically any OS nowadays, or silently gets + # ignored (Solaris) or triggers an "illegal operation" error (FreeBSD). + # It was likely added "because it exists", but should never be used. In + # theory it is useful for directories, but we never apply modes to + # directories other than in install_emptydir. + def _warn_kwarg_install_mode_sticky(self, mode: FileMode) -> None: + if mode.perms > 0 and mode.perms & stat.S_ISVTX: + mlog.deprecation('install_mode with the sticky bit on a file does not do anything and will ' + f'be ignored since Meson 0.64.0', location=self.current_node) + perms = stat.filemode(mode.perms - stat.S_ISVTX)[1:] + return FileMode(perms, mode.owner, mode.group) + else: + return mode + @typed_pos_args('install_data', varargs=(str, mesonlib.File)) @typed_kwargs( 'install_data', @@ -2342,7 +2360,8 @@ class Interpreter(InterpreterBase, HoldableObject): '"rename" and "sources" argument lists must be the same length if "rename" is given. ' f'Rename has {len(rename)} elements and sources has {len(sources)}.') - return self.install_data_impl(sources, kwargs['install_dir'], kwargs['install_mode'], + install_mode = self._warn_kwarg_install_mode_sticky(kwargs['install_mode']) + return self.install_data_impl(sources, kwargs['install_dir'], install_mode, rename, kwargs['install_tag'], preserve_path=kwargs['preserve_path']) @@ -2398,12 +2417,13 @@ class Interpreter(InterpreterBase, HoldableObject): FeatureNew.single_use('install_subdir with empty directory', '0.47.0', self.subproject, location=node) FeatureDeprecated.single_use('install_subdir with empty directory', '0.60.0', self.subproject, 'It worked by accident and is buggy. Use install_emptydir instead.', node) + install_mode = self._warn_kwarg_install_mode_sticky(kwargs['install_mode']) idir = build.InstallDir( self.subdir, args[0], kwargs['install_dir'], - kwargs['install_mode'], + install_mode, exclude, kwargs['strip_directory'], self.subproject, @@ -2469,6 +2489,8 @@ class Interpreter(InterpreterBase, HoldableObject): if kwargs['capture'] and not kwargs['command']: raise InvalidArguments('configure_file: "capture" keyword requires "command" keyword.') + install_mode = self._warn_kwarg_install_mode_sticky(kwargs['install_mode']) + fmt = kwargs['format'] output_format = kwargs['output_format'] depfile = kwargs['depfile'] @@ -2594,7 +2616,6 @@ class Interpreter(InterpreterBase, HoldableObject): if isinstance(idir_name, P_OBJ.OptionString): idir_name = idir_name.optname cfile = mesonlib.File.from_built_file(ofile_path, ofile_fname) - install_mode = kwargs['install_mode'] install_tag = kwargs['install_tag'] self.build.data.append(build.Data([cfile], idir, idir_name, install_mode, self.subproject, install_tag=install_tag, data_type='configure')) |