bitbake: utils: Add path_is_descendant()

Adds a utility that checks if one path is an descendant of another. This
check uses os.path.samestat() to make it immune to symlinks and bind
mounts.

(Bitbake rev: c3ae45946886ee2049939dd5a205790657a7de32)

Signed-off-by: Joshua Watt <JPEWhacker@gmail.com>
Signed-off-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
This commit is contained in:
Joshua Watt
2023-09-13 13:04:24 -06:00
committed by Richard Purdie
parent a96f735ff9
commit b2ab9bd4a3

View File

@@ -1828,6 +1828,29 @@ def mkstemp(suffix=None, prefix=None, dir=None, text=False):
prefix = tempfile.gettempprefix() + entropy
return tempfile.mkstemp(suffix=suffix, prefix=prefix, dir=dir, text=text)
def path_is_descendant(descendant, ancestor):
"""
Returns True if the path `descendant` is a descendant of `ancestor`
(including being equivalent to `ancestor` itself). Otherwise returns False.
Correctly accounts for symlinks, bind mounts, etc. by using
os.path.samestat() to compare paths
May raise any exception that os.stat() raises
"""
ancestor_stat = os.stat(ancestor)
# Recurse up each directory component of the descendant to see if it is
# equivalent to the ancestor
check_dir = os.path.abspath(descendant).rstrip("/")
while check_dir:
check_stat = os.stat(check_dir)
if os.path.samestat(check_stat, ancestor_stat):
return True
check_dir = os.path.dirname(check_dir).rstrip("/")
return False
# If we don't have a timeout of some kind and a process/thread exits badly (for example
# OOM killed) and held a lock, we'd just hang in the lock futex forever. It is better
# we exit at some point than hang. 5 minutes with no progress means we're probably deadlocked.