5 # This software may be used and distributed according to the terms of the |
5 # This software may be used and distributed according to the terms of the |
6 # GNU General Public License version 2, incorporated herein by reference. |
6 # GNU General Public License version 2, incorporated herein by reference. |
7 |
7 |
8 from i18n import _ |
8 from i18n import _ |
9 import osutil |
9 import osutil |
10 import os, sys, errno, stat, getpass, pwd, grp |
10 import os, sys, errno, stat, getpass, pwd, grp, fcntl |
11 |
11 |
12 posixfile = open |
12 posixfile = open |
13 nulldev = '/dev/null' |
13 nulldev = '/dev/null' |
14 normpath = os.path.normpath |
14 normpath = os.path.normpath |
15 samestat = os.path.samestat |
15 samestat = os.path.samestat |
102 return path |
102 return path |
103 |
103 |
104 def localpath(path): |
104 def localpath(path): |
105 return path |
105 return path |
106 |
106 |
|
107 if sys.platform == 'darwin': |
|
108 def realpath(path): |
|
109 ''' |
|
110 Returns the true, canonical file system path equivalent to the given |
|
111 path. |
|
112 |
|
113 Equivalent means, in this case, resulting in the same, unique |
|
114 file system link to the path. Every file system entry, whether a file, |
|
115 directory, hard link or symbolic link or special, will have a single |
|
116 path preferred by the system, but may allow multiple, differing path |
|
117 lookups to point to it. |
|
118 |
|
119 Most regular UNIX file systems only allow a file system entry to be |
|
120 looked up by its distinct path. Obviously, this does not apply to case |
|
121 insensitive file systems, whether case preserving or not. The most |
|
122 complex issue to deal with is file systems transparently reencoding the |
|
123 path, such as the non-standard Unicode normalisation required for HFS+ |
|
124 and HFSX. |
|
125 ''' |
|
126 # Constants copied from /usr/include/sys/fcntl.h |
|
127 F_GETPATH = 50 |
|
128 O_SYMLINK = 0x200000 |
|
129 |
|
130 try: |
|
131 fd = os.open(path, O_SYMLINK) |
|
132 except OSError, err: |
|
133 if err.errno is errno.ENOENT: |
|
134 return path |
|
135 raise |
|
136 |
|
137 try: |
|
138 return fcntl.fcntl(fd, F_GETPATH, '\0' * 1024).rstrip('\0') |
|
139 finally: |
|
140 os.close(fd) |
|
141 else: |
|
142 # Fallback to the likely inadequate Python builtin function. |
|
143 realpath = os.path.realpath |
|
144 |
107 def shellquote(s): |
145 def shellquote(s): |
108 if os.sys.platform == 'OpenVMS': |
146 if os.sys.platform == 'OpenVMS': |
109 return '"%s"' % s |
147 return '"%s"' % s |
110 else: |
148 else: |
111 return "'%s'" % s.replace("'", "'\\''") |
149 return "'%s'" % s.replace("'", "'\\''") |