diff options
Diffstat (limited to 'platform_utils.py')
-rw-r--r-- | platform_utils.py | 43 |
1 files changed, 43 insertions, 0 deletions
diff --git a/platform_utils.py b/platform_utils.py index 1c719b1d..f4dfa0b1 100644 --- a/platform_utils.py +++ b/platform_utils.py | |||
@@ -167,3 +167,46 @@ class _FileDescriptorStreamsThreads(FileDescriptorStreams): | |||
167 | self.queue.put(_FileDescriptorStreamsThreads.QueueItem(self, line)) | 167 | self.queue.put(_FileDescriptorStreamsThreads.QueueItem(self, line)) |
168 | self.fd.close() | 168 | self.fd.close() |
169 | self.queue.put(_FileDescriptorStreamsThreads.QueueItem(self, None)) | 169 | self.queue.put(_FileDescriptorStreamsThreads.QueueItem(self, None)) |
170 | |||
171 | |||
172 | def symlink(source, link_name): | ||
173 | """Creates a symbolic link pointing to source named link_name. | ||
174 | Note: On Windows, source must exist on disk, as the implementation needs | ||
175 | to know whether to create a "File" or a "Directory" symbolic link. | ||
176 | """ | ||
177 | if isWindows(): | ||
178 | import platform_utils_win32 | ||
179 | source = _validate_winpath(source) | ||
180 | link_name = _validate_winpath(link_name) | ||
181 | target = os.path.join(os.path.dirname(link_name), source) | ||
182 | if os.path.isdir(target): | ||
183 | platform_utils_win32.create_dirsymlink(source, link_name) | ||
184 | else: | ||
185 | platform_utils_win32.create_filesymlink(source, link_name) | ||
186 | else: | ||
187 | return os.symlink(source, link_name) | ||
188 | |||
189 | |||
190 | def _validate_winpath(path): | ||
191 | path = os.path.normpath(path) | ||
192 | if _winpath_is_valid(path): | ||
193 | return path | ||
194 | raise ValueError("Path \"%s\" must be a relative path or an absolute " | ||
195 | "path starting with a drive letter".format(path)) | ||
196 | |||
197 | |||
198 | def _winpath_is_valid(path): | ||
199 | """Windows only: returns True if path is relative (e.g. ".\\foo") or is | ||
200 | absolute including a drive letter (e.g. "c:\\foo"). Returns False if path | ||
201 | is ambiguous (e.g. "x:foo" or "\\foo"). | ||
202 | """ | ||
203 | assert isWindows() | ||
204 | path = os.path.normpath(path) | ||
205 | drive, tail = os.path.splitdrive(path) | ||
206 | if tail: | ||
207 | if not drive: | ||
208 | return tail[0] != os.sep # "\\foo" is invalid | ||
209 | else: | ||
210 | return tail[0] == os.sep # "x:foo" is invalid | ||
211 | else: | ||
212 | return not drive # "x:" is invalid | ||