Author: Maciej Fijalkowski <fij...@gmail.com> Branch: fileops2 Changeset: r67209:ad563885c46f Date: 2013-10-07 17:33 +0200 http://bitbucket.org/pypy/pypy/changeset/ad563885c46f/
Log: merge default diff --git a/rpython/rlib/rpath.py b/rpython/rlib/rpath.py --- a/rpython/rlib/rpath.py +++ b/rpython/rlib/rpath.py @@ -61,3 +61,65 @@ except os.error: return False return True + + +import os +from os.path import isabs, islink, abspath, normpath + +def join(a, p): + """Join two or more pathname components, inserting '/' as needed. + If any component is an absolute path, all previous path components + will be discarded. An empty last part will result in a path that + ends with a separator.""" + path = a + for b in p: + if b.startswith('/'): + path = b + elif path == '' or path.endswith('/'): + path += b + else: + path += '/' + b + return path + +def realpath(filename): + """Return the canonical path of the specified filename, eliminating any +symbolic links encountered in the path.""" + if isabs(filename): + bits = ['/'] + filename.split('/')[1:] + else: + bits = [''] + filename.split('/') + + for i in range(2, len(bits)+1): + component = join(bits[0], bits[1:i]) + # Resolve symbolic links. + if islink(component): + resolved = _resolve_link(component) + if resolved is None: + # Infinite loop -- return original component + rest of the path + return abspath(join(component, bits[i:])) + else: + newpath = join(resolved, bits[i:]) + return realpath(newpath) + + return abspath(filename) + + +def _resolve_link(path): + """Internal helper function. Takes a path and follows symlinks + until we either arrive at something that isn't a symlink, or + encounter a path we've seen before (meaning that there's a loop). + """ + paths_seen = {} + while islink(path): + if path in paths_seen: + # Already seen this path, so we must have a symlink loop + return None + paths_seen[path] = None + # Resolve where the link points to + resolved = os.readlink(path) + if not isabs(resolved): + dir = dirname(path) + path = normpath(join(dir, [resolved])) + else: + path = normpath(resolved) + return path _______________________________________________ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit