mirror of
https://git.yoctoproject.org/poky
synced 2026-09-19 18:49:32 +02:00
lib/oe/path.py: support missing directory components in realpath()
Some use cases in OE operate on symlinks which dangling path components. Assume that these are directories instead of raising ENOENT. (From OE-Core rev: a96e2c84f24c15b77ee1fbc1f998b8b4796b8664) Signed-off-by: Enrico Scholz <enrico.scholz@sigma-chemnitz.de> Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
This commit is contained in:
committed by
Richard Purdie
parent
d518019d6c
commit
8c22531e49
@@ -168,13 +168,13 @@ def find(dir, **walkoptions):
|
|||||||
def __is_path_below(file, root):
|
def __is_path_below(file, root):
|
||||||
return (file + os.path.sep).startswith(root)
|
return (file + os.path.sep).startswith(root)
|
||||||
|
|
||||||
def __realpath_rel(start, rel_path, root, loop_cnt):
|
def __realpath_rel(start, rel_path, root, loop_cnt, assume_dir):
|
||||||
"""Calculates real path of symlink 'start' + 'rel_path' below
|
"""Calculates real path of symlink 'start' + 'rel_path' below
|
||||||
'root'; no part of 'start' below 'root' must contain symlinks. """
|
'root'; no part of 'start' below 'root' must contain symlinks. """
|
||||||
have_dir = True
|
have_dir = True
|
||||||
|
|
||||||
for d in rel_path.split(os.path.sep):
|
for d in rel_path.split(os.path.sep):
|
||||||
if not have_dir:
|
if not have_dir and not assume_dir:
|
||||||
raise OSError(errno.ENOENT, "no such directory %s" % start)
|
raise OSError(errno.ENOENT, "no such directory %s" % start)
|
||||||
|
|
||||||
if d == os.path.pardir: # '..'
|
if d == os.path.pardir: # '..'
|
||||||
@@ -186,13 +186,13 @@ def __realpath_rel(start, rel_path, root, loop_cnt):
|
|||||||
pass
|
pass
|
||||||
else:
|
else:
|
||||||
(start, have_dir) = __realpath(os.path.join(start, d),
|
(start, have_dir) = __realpath(os.path.join(start, d),
|
||||||
root, loop_cnt)
|
root, loop_cnt, assume_dir)
|
||||||
|
|
||||||
assert(__is_path_below(start, root))
|
assert(__is_path_below(start, root))
|
||||||
|
|
||||||
return start
|
return start
|
||||||
|
|
||||||
def __realpath(file, root, loop_cnt):
|
def __realpath(file, root, loop_cnt, assume_dir):
|
||||||
while os.path.islink(file) and len(file) >= len(root):
|
while os.path.islink(file) and len(file) >= len(root):
|
||||||
if loop_cnt == 0:
|
if loop_cnt == 0:
|
||||||
raise OSError(errno.ELOOP, file)
|
raise OSError(errno.ELOOP, file)
|
||||||
@@ -206,7 +206,7 @@ def __realpath(file, root, loop_cnt):
|
|||||||
else:
|
else:
|
||||||
tdir = root
|
tdir = root
|
||||||
|
|
||||||
file = __realpath_rel(tdir, target, root, loop_cnt)
|
file = __realpath_rel(tdir, target, root, loop_cnt, assume_dir)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
is_dir = os.path.isdir(file)
|
is_dir = os.path.isdir(file)
|
||||||
@@ -215,11 +215,13 @@ def __realpath(file, root, loop_cnt):
|
|||||||
|
|
||||||
return (file, is_dir)
|
return (file, is_dir)
|
||||||
|
|
||||||
def realpath(file, root, use_physdir = True, loop_cnt = 100):
|
def realpath(file, root, use_physdir = True, loop_cnt = 100, assume_dir = False):
|
||||||
""" Returns the canonical path of 'file' with assuming a toplevel
|
""" Returns the canonical path of 'file' with assuming a
|
||||||
'root' directory. When 'use_physdir' is set, all preceding path
|
toplevel 'root' directory. When 'use_physdir' is set, all
|
||||||
components of 'file' will be resolved first; this flag should be
|
preceding path components of 'file' will be resolved first;
|
||||||
set unless it is guaranteed that there is no symlink in the path."""
|
this flag should be set unless it is guaranteed that there is
|
||||||
|
no symlink in the path. When 'assume_dir' is not set, missing
|
||||||
|
path components will raise an ENOENT error"""
|
||||||
|
|
||||||
root = os.path.normpath(root)
|
root = os.path.normpath(root)
|
||||||
file = os.path.normpath(file)
|
file = os.path.normpath(file)
|
||||||
@@ -233,9 +235,9 @@ def realpath(file, root, use_physdir = True, loop_cnt = 100):
|
|||||||
|
|
||||||
try:
|
try:
|
||||||
if use_physdir:
|
if use_physdir:
|
||||||
file = __realpath_rel(root, file[(len(root) - 1):], root, loop_cnt)
|
file = __realpath_rel(root, file[(len(root) - 1):], root, loop_cnt, assume_dir)
|
||||||
else:
|
else:
|
||||||
file = __realpath(file, root, loop_cnt)[0]
|
file = __realpath(file, root, loop_cnt, assume_dir)[0]
|
||||||
except OSError, e:
|
except OSError, e:
|
||||||
if e.errno == errno.ELOOP:
|
if e.errno == errno.ELOOP:
|
||||||
# make ELOOP more readable; without catching it, there will
|
# make ELOOP more readable; without catching it, there will
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ class TestRealPath(unittest.TestCase):
|
|||||||
( "usr/bin/prog-F", "../../../sbin/prog-F", "/sbin/prog-F" ),
|
( "usr/bin/prog-F", "../../../sbin/prog-F", "/sbin/prog-F" ),
|
||||||
( "loop", "a/loop", None ),
|
( "loop", "a/loop", None ),
|
||||||
( "a/loop", "../loop", None ),
|
( "a/loop", "../loop", None ),
|
||||||
( "b/test", "file/foo", None ),
|
( "b/test", "file/foo", "/b/file/foo" ),
|
||||||
]
|
]
|
||||||
|
|
||||||
LINKS_PHYS = [
|
LINKS_PHYS = [
|
||||||
@@ -59,8 +59,9 @@ class TestRealPath(unittest.TestCase):
|
|||||||
for l in self.LINKS:
|
for l in self.LINKS:
|
||||||
os.symlink(l[1], os.path.join(self.root, l[0]))
|
os.symlink(l[1], os.path.join(self.root, l[0]))
|
||||||
|
|
||||||
def __realpath(self, file, use_physdir):
|
def __realpath(self, file, use_physdir, assume_dir = True):
|
||||||
return oe.path.realpath(os.path.join(self.root, file), self.root, use_physdir)
|
return oe.path.realpath(os.path.join(self.root, file), self.root,
|
||||||
|
use_physdir, assume_dir = assume_dir)
|
||||||
|
|
||||||
def test_norm(self):
|
def test_norm(self):
|
||||||
for l in self.LINKS:
|
for l in self.LINKS:
|
||||||
@@ -85,5 +86,4 @@ class TestRealPath(unittest.TestCase):
|
|||||||
def test_loop(self):
|
def test_loop(self):
|
||||||
for e in self.EXCEPTIONS:
|
for e in self.EXCEPTIONS:
|
||||||
self.assertRaisesRegexp(OSError, r'\[Errno %u\]' % e[1],
|
self.assertRaisesRegexp(OSError, r'\[Errno %u\]' % e[1],
|
||||||
self.__realpath, e[0], False)
|
self.__realpath, e[0], False, False)
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user