aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJoshua Watt <JPEWhacker@gmail.com>2023-09-13 13:04:24 -0600
committerRichard Purdie <richard.purdie@linuxfoundation.org>2023-09-14 15:08:18 +0100
commitc3ae45946886ee2049939dd5a205790657a7de32 (patch)
tree570aa584d098f4add80d8289d1e18775d25bdb22
parent033896da8daaff69df3c2adb4ad5fee29121e831 (diff)
downloadbitbake-contrib-c3ae45946886ee2049939dd5a205790657a7de32.tar.gz
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. Signed-off-by: Joshua Watt <JPEWhacker@gmail.com> Signed-off-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
-rw-r--r--lib/bb/utils.py23
1 files changed, 23 insertions, 0 deletions
diff --git a/lib/bb/utils.py b/lib/bb/utils.py
index 0624a4f3e..b401fa5ec 100644
--- a/lib/bb/utils.py
+++ b/lib/bb/utils.py
@@ -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.