summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorBartosz Sosnowski <bartosz@janeasystems.com>2018-10-18 02:42:14 +0200
committerRich Trott <rtrott@gmail.com>2018-11-29 11:28:39 -0800
commitcda6b2081682e1af5a6ef7eb8c137b9da070ddb6 (patch)
treee0d0c0c576076abe05351a5bf2c6dccbb20ece78 /lib
parent83d6cb98ecf6efc0792b174265a4580b31f4b3eb (diff)
downloadandroid-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.js33
1 files changed, 32 insertions, 1 deletions
diff --git a/lib/fs.js b/lib/fs.js
index 5915083db9..2e4bdc8964 100644
--- a/lib/fs.js
+++ b/lib/fs.js
@@ -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');