joyent / libuv

Go to
https://github.com/libuv/libuv
3.27k stars 653 forks source link

fs__create_junction append a slash to src path when the source path is regular file #1568

Closed hwwan80 closed 10 years ago

hwwan80 commented 10 years ago

The following code in src/win/fs.c:

  add_slash = 0;
  for (i = is_long_path ? LONG_PATH_PREFIX_LEN : 0; path[i] != L'\0'; i++) {
    if (IS_SLASH(path[i])) {
      add_slash = 1;
      continue;
    }

Append a slash to the source path without checking the source path is regular file or directory. This make junction not work for regular file in windows since the source path is incorrect.

saghul commented 10 years ago

Junctions are only supported for directories, not regular files. (by Windows)

hwwan80 commented 10 years ago

@saghul That depend whether the application is aware of junction. This is at least supported by application written with node( which use libuv) and also mingw cat:

D:\tmp>rm foo.txt

D:\tmp>echo text > foo.txt

D:\tmp>d:\tools\junction bar.txt foo.txt

Junction v1.06 - Windows junction creator and reparse point viewer
Copyright (C) 2000-2010 Mark Russinovich
Sysinternals - www.sysinternals.com

Created: D:\tmp\bar.txt
Targetted at: D:\tmp\foo.txt

D:\tmp>cat bar.txt
text

D:\tmp>node
> fs.readFileSync("bar.txt")
<Buffer 74 65 78 74 20 0d 0a>
>

However, using symlink in node doesnot work because libuv append a slash after it:

D:\tmp>node
> fs.symlinkSync("foo.txt","baz.txt","junction");
undefined
> fs.readFileSync("baz.txt");
Error: ENOENT, no such file or directory 'D:\tmp\baz.txt'
    at Object.fs.openSync (fs.js:432:18)
    at Object.fs.readFileSync (fs.js:289:15)
    at repl:1:4
    at REPLServer.self.eval (repl.js:110:21)
    at repl.js:249:20
    at REPLServer.self.eval (repl.js:122:7)
    at Interface.<anonymous> (repl.js:239:12)
    at Interface.emit (events.js:95:17)
    at Interface._onLine (readline.js:202:10)
    at Interface._line (readline.js:531:8)
>

D:\tmp>d:\tools\junction baz.txt

Junction v1.06 - Windows junction creator and reparse point viewer
Copyright (C) 2000-2010 Mark Russinovich
Sysinternals - www.sysinternals.com

D:\tmp\baz.txt: JUNCTION
   Print Name     : D:\tmp\foo.txt
   Substitute Name: D:\tmp\foo.txt\

D:\tmp>d:\tools\junction bar.txt

Junction v1.06 - Windows junction creator and reparse point viewer
Copyright (C) 2000-2010 Mark Russinovich
Sysinternals - www.sysinternals.com

D:\tmp\bar.txt: JUNCTION
   Substitute Name: D:\tmp\foo.txt

It is also inconsistent that libuv allow reading regular file for junction but unable to create a junction on it.

saghul commented 10 years ago

I'm not sure what the junction utility does, it may create a hard link. Windows only supports junctions for directories, and this is also what libuv supports.