Guido van Rossum | c636014 | 1990-10-13 19:23:40 +0000 | [diff] [blame] | 1 | # Module 'path' -- common operations on POSIX pathnames |
| 2 | |
| 3 | import posix |
Guido van Rossum | 40d9304 | 1990-10-21 16:17:34 +0000 | [diff] [blame] | 4 | import stat |
Guido van Rossum | c636014 | 1990-10-13 19:23:40 +0000 | [diff] [blame] | 5 | |
| 6 | |
| 7 | # Intelligent pathname concatenation. |
| 8 | # Inserts a '/' unless the first part is empty or already ends in '/'. |
| 9 | # Ignores the first part altogether if the second part is absolute |
| 10 | # (begins with '/'). |
| 11 | # |
| 12 | def cat(a, b): |
| 13 | if b[:1] = '/': return b |
| 14 | if a = '' or a[-1:] = '/': return a + b |
| 15 | return a + '/' + b |
| 16 | |
| 17 | |
| 18 | # Split a path in head (empty or ending in '/') and tail (no '/'). |
| 19 | # The tail will be empty if the path ends in '/'. |
| 20 | # |
| 21 | def split(p): |
| 22 | head, tail = '', '' |
| 23 | for c in p: |
| 24 | tail = tail + c |
| 25 | if c = '/': |
| 26 | head, tail = head + tail, '' |
| 27 | return head, tail |
| 28 | |
| 29 | |
| 30 | # Return the tail (basename) part of a path. |
| 31 | # |
| 32 | def basename(p): |
| 33 | return split(p)[1] |
| 34 | |
| 35 | |
| 36 | # Return the longest prefix of all list elements. |
| 37 | # |
| 38 | def commonprefix(m): |
| 39 | if not m: return '' |
| 40 | prefix = m[0] |
| 41 | for item in m: |
| 42 | for i in range(len(prefix)): |
| 43 | if prefix[:i+1] <> item[:i+1]: |
| 44 | prefix = prefix[:i] |
| 45 | if i = 0: return '' |
| 46 | break |
| 47 | return prefix |
| 48 | |
| 49 | |
| 50 | # Does a file/directory exist? |
| 51 | # |
| 52 | def exists(path): |
| 53 | try: |
| 54 | st = posix.stat(path) |
| 55 | except posix.error: |
| 56 | return 0 |
| 57 | return 1 |
| 58 | |
| 59 | |
| 60 | # Is a path a posix directory? |
| 61 | # |
| 62 | def isdir(path): |
| 63 | try: |
| 64 | st = posix.stat(path) |
| 65 | except posix.error: |
| 66 | return 0 |
Guido van Rossum | 40d9304 | 1990-10-21 16:17:34 +0000 | [diff] [blame] | 67 | return stat.S_ISDIR(st[stat.ST_MODE]) |
Guido van Rossum | c636014 | 1990-10-13 19:23:40 +0000 | [diff] [blame] | 68 | |
| 69 | |
| 70 | # Is a path a symbolic link? |
| 71 | # This will always return false on systems where posix.lstat doesn't exist. |
| 72 | # |
| 73 | def islink(path): |
| 74 | try: |
| 75 | st = posix.lstat(path) |
| 76 | except (posix.error, NameError): |
| 77 | return 0 |
Guido van Rossum | 40d9304 | 1990-10-21 16:17:34 +0000 | [diff] [blame] | 78 | return stat.S_ISLNK(st[stat.ST_MODE]) |
Guido van Rossum | c636014 | 1990-10-13 19:23:40 +0000 | [diff] [blame] | 79 | |
| 80 | |
| 81 | _mounts = [] |
| 82 | |
| 83 | def _getmounts(): |
| 84 | import commands, string |
| 85 | mounts = [] |
| 86 | data = commands.getoutput('/etc/mount') |
| 87 | lines = string.splitfields(data, '\n') |
| 88 | for line in lines: |
| 89 | words = string.split(line) |
| 90 | if len(words) >= 3 and words[1] = 'on': |
| 91 | mounts.append(words[2]) |
| 92 | return mounts |
| 93 | |
| 94 | |
| 95 | # Is a path a mount point? |
| 96 | # This only works for normalized, absolute paths, |
| 97 | # and only if the mount table as printed by /etc/mount is correct. |
| 98 | # Sorry. |
| 99 | # |
| 100 | def ismount(path): |
| 101 | if not _mounts: |
| 102 | _mounts[:] = _getmounts() |
| 103 | return path in _mounts |
| 104 | |
| 105 | |
| 106 | # Directory tree walk. |
| 107 | # For each directory under top (including top itself), |
| 108 | # func(arg, dirname, filenames) is called, where dirname |
| 109 | # is the name of the directory and filenames is the list of |
| 110 | # files (and subdirectories etc.) in the directory. |
| 111 | # func may modify the filenames list, to implement a filter, |
| 112 | # or to impose a different order of visiting. |
| 113 | # |
| 114 | def walk(top, func, arg): |
| 115 | try: |
| 116 | names = posix.listdir(top) |
| 117 | except posix.error: |
| 118 | return |
| 119 | func(arg, top, names) |
| 120 | exceptions = ('.', '..') |
| 121 | for name in names: |
| 122 | if name not in exceptions: |
| 123 | name = cat(top, name) |
| 124 | if isdir(name): |
| 125 | walk(name, func, arg) |