diff options
author | Enrico Scholz <enrico.scholz@sigma-chemnitz.de> | 2013-02-11 20:21:52 +0100 |
---|---|---|
committer | Richard Purdie <richard.purdie@linuxfoundation.org> | 2013-02-11 22:45:25 +0000 |
commit | 8c22531e491e6b0cfffaaa80d6bc75db757fc1d1 (patch) | |
tree | 2d326aaea7250fac0e276500111c230cecbe971a /meta/lib/oe | |
parent | d518019d6ccb0ffebe7e21b973eb4f9aa5241dec (diff) | |
download | poky-8c22531e491e6b0cfffaaa80d6bc75db757fc1d1.tar.gz |
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>
Diffstat (limited to 'meta/lib/oe')
-rw-r--r-- | meta/lib/oe/path.py | 26 | ||||
-rw-r--r-- | meta/lib/oe/tests/test_path.py | 10 |
2 files changed, 19 insertions, 17 deletions
diff --git a/meta/lib/oe/path.py b/meta/lib/oe/path.py index 0b34cebdab..faa0f61fab 100644 --- a/meta/lib/oe/path.py +++ b/meta/lib/oe/path.py | |||
@@ -168,13 +168,13 @@ def find(dir, **walkoptions): | |||
168 | def __is_path_below(file, root): | 168 | def __is_path_below(file, root): |
169 | return (file + os.path.sep).startswith(root) | 169 | return (file + os.path.sep).startswith(root) |
170 | 170 | ||
171 | def __realpath_rel(start, rel_path, root, loop_cnt): | 171 | def __realpath_rel(start, rel_path, root, loop_cnt, assume_dir): |
172 | """Calculates real path of symlink 'start' + 'rel_path' below | 172 | """Calculates real path of symlink 'start' + 'rel_path' below |
173 | 'root'; no part of 'start' below 'root' must contain symlinks. """ | 173 | 'root'; no part of 'start' below 'root' must contain symlinks. """ |
174 | have_dir = True | 174 | have_dir = True |
175 | 175 | ||
176 | for d in rel_path.split(os.path.sep): | 176 | for d in rel_path.split(os.path.sep): |
177 | if not have_dir: | 177 | if not have_dir and not assume_dir: |
178 | raise OSError(errno.ENOENT, "no such directory %s" % start) | 178 | raise OSError(errno.ENOENT, "no such directory %s" % start) |
179 | 179 | ||
180 | if d == os.path.pardir: # '..' | 180 | if d == os.path.pardir: # '..' |
@@ -186,13 +186,13 @@ def __realpath_rel(start, rel_path, root, loop_cnt): | |||
186 | pass | 186 | pass |
187 | else: | 187 | else: |
188 | (start, have_dir) = __realpath(os.path.join(start, d), | 188 | (start, have_dir) = __realpath(os.path.join(start, d), |
189 | root, loop_cnt) | 189 | root, loop_cnt, assume_dir) |
190 | 190 | ||
191 | assert(__is_path_below(start, root)) | 191 | assert(__is_path_below(start, root)) |
192 | 192 | ||
193 | return start | 193 | return start |
194 | 194 | ||
195 | def __realpath(file, root, loop_cnt): | 195 | def __realpath(file, root, loop_cnt, assume_dir): |
196 | while os.path.islink(file) and len(file) >= len(root): | 196 | while os.path.islink(file) and len(file) >= len(root): |
197 | if loop_cnt == 0: | 197 | if loop_cnt == 0: |
198 | raise OSError(errno.ELOOP, file) | 198 | raise OSError(errno.ELOOP, file) |
@@ -206,7 +206,7 @@ def __realpath(file, root, loop_cnt): | |||
206 | else: | 206 | else: |
207 | tdir = root | 207 | tdir = root |
208 | 208 | ||
209 | file = __realpath_rel(tdir, target, root, loop_cnt) | 209 | file = __realpath_rel(tdir, target, root, loop_cnt, assume_dir) |
210 | 210 | ||
211 | try: | 211 | try: |
212 | is_dir = os.path.isdir(file) | 212 | is_dir = os.path.isdir(file) |
@@ -215,11 +215,13 @@ def __realpath(file, root, loop_cnt): | |||
215 | 215 | ||
216 | return (file, is_dir) | 216 | return (file, is_dir) |
217 | 217 | ||
218 | def realpath(file, root, use_physdir = True, loop_cnt = 100): | 218 | def realpath(file, root, use_physdir = True, loop_cnt = 100, assume_dir = False): |
219 | """ Returns the canonical path of 'file' with assuming a toplevel | 219 | """ Returns the canonical path of 'file' with assuming a |
220 | 'root' directory. When 'use_physdir' is set, all preceding path | 220 | toplevel 'root' directory. When 'use_physdir' is set, all |
221 | components of 'file' will be resolved first; this flag should be | 221 | preceding path components of 'file' will be resolved first; |
222 | set unless it is guaranteed that there is no symlink in the path.""" | 222 | this flag should be set unless it is guaranteed that there is |
223 | no symlink in the path. When 'assume_dir' is not set, missing | ||
224 | path components will raise an ENOENT error""" | ||
223 | 225 | ||
224 | root = os.path.normpath(root) | 226 | root = os.path.normpath(root) |
225 | file = os.path.normpath(file) | 227 | file = os.path.normpath(file) |
@@ -233,9 +235,9 @@ def realpath(file, root, use_physdir = True, loop_cnt = 100): | |||
233 | 235 | ||
234 | try: | 236 | try: |
235 | if use_physdir: | 237 | if use_physdir: |
236 | file = __realpath_rel(root, file[(len(root) - 1):], root, loop_cnt) | 238 | file = __realpath_rel(root, file[(len(root) - 1):], root, loop_cnt, assume_dir) |
237 | else: | 239 | else: |
238 | file = __realpath(file, root, loop_cnt)[0] | 240 | file = __realpath(file, root, loop_cnt, assume_dir)[0] |
239 | except OSError, e: | 241 | except OSError, e: |
240 | if e.errno == errno.ELOOP: | 242 | if e.errno == errno.ELOOP: |
241 | # make ELOOP more readable; without catching it, there will | 243 | # make ELOOP more readable; without catching it, there will |
diff --git a/meta/lib/oe/tests/test_path.py b/meta/lib/oe/tests/test_path.py index e6aa601618..3d41ce157a 100644 --- a/meta/lib/oe/tests/test_path.py +++ b/meta/lib/oe/tests/test_path.py | |||
@@ -25,7 +25,7 @@ class TestRealPath(unittest.TestCase): | |||
25 | ( "usr/bin/prog-F", "../../../sbin/prog-F", "/sbin/prog-F" ), | 25 | ( "usr/bin/prog-F", "../../../sbin/prog-F", "/sbin/prog-F" ), |
26 | ( "loop", "a/loop", None ), | 26 | ( "loop", "a/loop", None ), |
27 | ( "a/loop", "../loop", None ), | 27 | ( "a/loop", "../loop", None ), |
28 | ( "b/test", "file/foo", None ), | 28 | ( "b/test", "file/foo", "/b/file/foo" ), |
29 | ] | 29 | ] |
30 | 30 | ||
31 | LINKS_PHYS = [ | 31 | LINKS_PHYS = [ |
@@ -59,8 +59,9 @@ class TestRealPath(unittest.TestCase): | |||
59 | for l in self.LINKS: | 59 | for l in self.LINKS: |
60 | os.symlink(l[1], os.path.join(self.root, l[0])) | 60 | os.symlink(l[1], os.path.join(self.root, l[0])) |
61 | 61 | ||
62 | def __realpath(self, file, use_physdir): | 62 | def __realpath(self, file, use_physdir, assume_dir = True): |
63 | return oe.path.realpath(os.path.join(self.root, file), self.root, use_physdir) | 63 | return oe.path.realpath(os.path.join(self.root, file), self.root, |
64 | use_physdir, assume_dir = assume_dir) | ||
64 | 65 | ||
65 | def test_norm(self): | 66 | def test_norm(self): |
66 | for l in self.LINKS: | 67 | for l in self.LINKS: |
@@ -85,5 +86,4 @@ class TestRealPath(unittest.TestCase): | |||
85 | def test_loop(self): | 86 | def test_loop(self): |
86 | for e in self.EXCEPTIONS: | 87 | for e in self.EXCEPTIONS: |
87 | self.assertRaisesRegexp(OSError, r'\[Errno %u\]' % e[1], | 88 | self.assertRaisesRegexp(OSError, r'\[Errno %u\]' % e[1], |
88 | self.__realpath, e[0], False) | 89 | self.__realpath, e[0], False, False) |
89 | |||