| OLD | NEW |
| 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 part of dart.io; | 5 part of dart.io; |
| 6 | 6 |
| 7 /** | 7 /** |
| 8 * [Link] objects are references to filesystem links. | 8 * [Link] objects are references to filesystem links. |
| 9 * | 9 * |
| 10 */ | 10 */ |
| 11 abstract class Link implements FileSystemEntity { | 11 abstract class Link implements FileSystemEntity { |
| 12 /** | 12 /** |
| 13 * Creates a Link object. | 13 * Creates a Link object. |
| 14 */ | 14 */ |
| 15 factory Link(String path) => new _Link(path); | 15 factory Link(String path) => new _Link(path); |
| 16 | 16 |
| 17 /** | 17 /** |
| 18 * Creates a symbolic link. Returns a [:Future<Link>:] that completes with | 18 * Creates a symbolic link. Returns a [:Future<Link>:] that completes with |
| 19 * the link when it has been created. If the link exists, | 19 * the link when it has been created. If the link exists, |
| 20 * the future will complete with an error. | 20 * the future will complete with an error. |
| 21 * | 21 * |
| 22 * On the Windows platform, this will only work with directories, and the | 22 * On the Windows platform, this will only work with directories, and the |
| 23 * target directory must exist. The link will be created as a Junction. | 23 * target directory must exist. The link will be created as a Junction. |
| 24 * Only absolute links will be created, and relative paths to the target | 24 * Only absolute links will be created, and relative paths to the target |
| 25 * will be converted to absolute paths. | 25 * will be converted to absolute paths by joining them with the path of the |
| 26 * directory the link is contained in. |
| 26 * | 27 * |
| 27 * On other platforms, the posix symlink() call is used to make a symbolic | 28 * On other platforms, the posix symlink() call is used to make a symbolic |
| 28 * link containing the string [target]. If [target] is a relative path, | 29 * link containing the string [target]. If [target] is a relative path, |
| 29 * it will be interpreted relative to the directory containing the link. | 30 * it will be interpreted relative to the directory containing the link. |
| 30 */ | 31 */ |
| 31 Future<Link> create(String target); | 32 Future<Link> create(String target); |
| 32 | 33 |
| 33 /** | 34 /** |
| 34 * Synchronously create the link. Calling [createSync] on an existing link | 35 * Synchronously create the link. Calling [createSync] on an existing link |
| 35 * will throw an exception. | 36 * will throw an exception. |
| (...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 163 void createSync(String target) { | 164 void createSync(String target) { |
| 164 if (Platform.operatingSystem == 'windows') { | 165 if (Platform.operatingSystem == 'windows') { |
| 165 target = _makeWindowsLinkTarget(target); | 166 target = _makeWindowsLinkTarget(target); |
| 166 } | 167 } |
| 167 var result = _File._createLink(path, target); | 168 var result = _File._createLink(path, target); |
| 168 throwIfError(result, "Cannot create link", path); | 169 throwIfError(result, "Cannot create link", path); |
| 169 } | 170 } |
| 170 | 171 |
| 171 // Put target into the form "\??\C:\my\target\dir". | 172 // Put target into the form "\??\C:\my\target\dir". |
| 172 String _makeWindowsLinkTarget(String target) { | 173 String _makeWindowsLinkTarget(String target) { |
| 173 if (target.startsWith('\\??\\')) { | 174 Uri base = new Uri.file('${Directory.current.path}\\'); |
| 174 return target; | 175 Uri link = new Uri.file(path); |
| 175 } | 176 Uri destination = new Uri.file(target); |
| 176 if (!(target.length > 3 && target[1] == ':' && target[2] == '\\')) { | 177 String result = base.resolveUri(link).resolveUri(destination).toFilePath(); |
| 177 try { | 178 if (result.length > 3 && result[1] == ':' && result[2] == '\\') { |
| 178 target = new File(target).fullPathSync(); | 179 return '\\??\\$result'; |
| 179 } on FileException catch (e) { | |
| 180 throw new LinkException('Could not locate target', target, e.osError); | |
| 181 } | |
| 182 } | |
| 183 if (target.length > 3 && target[1] == ':' && target[2] == '\\') { | |
| 184 target = '\\??\\$target'; | |
| 185 } else { | 180 } else { |
| 186 throw new LinkException( | 181 throw new LinkException( |
| 187 'Target $target of Link.create on Windows cannot be converted' + | 182 'Target $result of Link.create on Windows cannot be converted' + |
| 188 ' to start with a drive letter. Unexpected error.'); | 183 ' to start with a drive letter. Unexpected error.'); |
| 189 } | 184 } |
| 190 return target; | 185 return target; |
| 191 } | 186 } |
| 192 | 187 |
| 193 void updateSync(String target) { | 188 void updateSync(String target) { |
| 194 // TODO(12414): Replace with atomic update, where supported by platform. | 189 // TODO(12414): Replace with atomic update, where supported by platform. |
| 195 // Atomically changing a link can be done by creating the new link, with | 190 // Atomically changing a link can be done by creating the new link, with |
| 196 // a different name, and using the rename() posix call to move it to | 191 // a different name, and using the rename() posix call to move it to |
| 197 // the old name atomically. | 192 // the old name atomically. |
| (...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 324 if (path != null) { | 319 if (path != null) { |
| 325 sb.write(", path = $path"); | 320 sb.write(", path = $path"); |
| 326 } | 321 } |
| 327 } | 322 } |
| 328 return sb.toString(); | 323 return sb.toString(); |
| 329 } | 324 } |
| 330 final String message; | 325 final String message; |
| 331 final String path; | 326 final String path; |
| 332 final OSError osError; | 327 final OSError osError; |
| 333 } | 328 } |
| OLD | NEW |