diff options
author | Bartosz Sosnowski <bartosz@janeasystems.com> | 2018-10-18 02:42:14 +0200 |
---|---|---|
committer | Rich Trott <rtrott@gmail.com> | 2018-11-29 11:28:39 -0800 |
commit | cda6b2081682e1af5a6ef7eb8c137b9da070ddb6 (patch) | |
tree | e0d0c0c576076abe05351a5bf2c6dccbb20ece78 /lib | |
parent | 83d6cb98ecf6efc0792b174265a4580b31f4b3eb (diff) | |
download | android-node-v8-cda6b2081682e1af5a6ef7eb8c137b9da070ddb6.tar.gz android-node-v8-cda6b2081682e1af5a6ef7eb8c137b9da070ddb6.tar.bz2 android-node-v8-cda6b2081682e1af5a6ef7eb8c137b9da070ddb6.zip |
win, fs: detect if symlink target is a directory
On Windows creating a symlink to a directory will not work unless extra
'dir' parameter is passed. This adds a check if link target is a
directory, and if so automatically use 'dir' when creating symlink.
PR-URL: https://github.com/nodejs/node/pull/23724
Refs: https://github.com/nodejs/node/pull/23691
Reviewed-By: Refael Ackermann <refack@gmail.com>
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Rod Vagg <rod@vagg.org>
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
Diffstat (limited to 'lib')
-rw-r--r-- | lib/fs.js | 33 |
1 files changed, 32 insertions, 1 deletions
@@ -905,16 +905,47 @@ function symlink(target, path, type_, callback_) { validatePath(target, 'target'); validatePath(path); - const flags = stringToSymlinkType(type); const req = new FSReqCallback(); req.oncomplete = callback; + if (isWindows && type === null) { + let absoluteTarget; + try { + // Symlinks targets can be relative to the newly created path. + // Calculate absolute file name of the symlink target, and check + // if it is a directory. Ignore resolve error to keep symlink + // errors consistent between platforms if invalid path is + // provided. + absoluteTarget = pathModule.resolve(path, '..', target); + } catch { } + if (absoluteTarget !== undefined) { + stat(absoluteTarget, (err, stat) => { + const resolvedType = !err && stat.isDirectory() ? 'dir' : 'file'; + const resolvedFlags = stringToSymlinkType(resolvedType); + binding.symlink(preprocessSymlinkDestination(target, + resolvedType, + path), + pathModule.toNamespacedPath(path), resolvedFlags, req); + }); + return; + } + } + + const flags = stringToSymlinkType(type); binding.symlink(preprocessSymlinkDestination(target, type, path), pathModule.toNamespacedPath(path), flags, req); } function symlinkSync(target, path, type) { type = (typeof type === 'string' ? type : null); + if (isWindows && type === null) { + try { + const absoluteTarget = pathModule.resolve(path, '..', target); + if (statSync(absoluteTarget).isDirectory()) { + type = 'dir'; + } + } catch { } + } target = toPathIfFileURL(target); path = toPathIfFileURL(path); validatePath(target, 'target'); |