Skip to content

fs.watch - on change returns incorrect file name #19170

Description

@captainrdubb

In another project, I ran into the following scenario:

The function os.tmpDir returns a path with the 8.3 short name for the user name, example "C:\Users\<FIRST SIX CHARS OF NAME>~1\AppData\Local\Temp".

The Windows api returns the changed file name including the long version of the user name, example,
"C:\Users\<actual 18 char user name>\AppData\Local\Temp".

Pretend we are monitoring, "C:\Users\<8.3 file name>\AppData\Local\Temp\Configuration", expecting the file "config.json" to change. We would then expect the FSWatcher change event to return "config.json" as the name of the changed file. Instead, it returns something like "figuration\config.json", depending on the difference in length between the 8.3 file name and the actual file name.

It seems that node is saving an index so that it can quickly determine the part of the uri that is the file name, but the uri passed to fs.watch is a different length than the uri returned by the Windows api.

Activity

  1. seishun commented on Mar 7, 2018

    @seishun
    Contributor

    It's not clear from your description how one can reproduce this issue. Can you provide a test case?

  2. captainrdubb commented on Mar 7, 2018

    @captainrdubb
    Author

    @seishun

    var os = require('os');
    var fs = require('fs');
    var path = require('path');
    var assert = require('assert');
    
    var expectedFilename = 'testFile.txt';
    
    var tmpDir = os.tmpdir();
    var testDir = path.join(tmpDir, 'testCase');
    var testFile = path.join(testDir, expectedFilename);
    
    if (!fs.existsSync(testDir)) {
        fs.mkdirSync(testDir);
    }
    
    fs.watch(testDir, function (eventType, filename) {
        var areEqual = filename === expectedFilename;
    
        //This assert will fail if testDir contains an 8.3 short filename https://en.wikipedia.org/wiki/8.3_filename
        assert.deepStrictEqual(filename, expectedFilename, `"${filename}\" ${areEqual ? '=' : '!'}== \"${expectedFilename}\"`);
    });
    
    
    if (!fs.exists(testFile)) {
        fs.writeFileSync(testFile);
    } else {
        fs.appendFileSync(testFile, 'data');
    }
  3. added
    fsIssues and PRs related to file-system APIs and the fs module.
    windowsIssues and PRs related to the Windows platform.
    on Mar 7, 2018
  4. bzoz commented on Mar 8, 2018

    @bzoz
    Contributor

    Its a libuv issue. The wrong relative filename is created in fs-event.c.

  5. captainrdubb commented on Mar 8, 2018

    @captainrdubb
    Author

    @bzoz Maybe we need the long_dirw, instead of passing handle->dirw
    image

  6. bzoz commented on Mar 8, 2018

    @bzoz
    Contributor

    I think we should get long directory name here: https://github.com/libuv/libuv/blob/v1.x/src/win/fs-event.c#L200.

  7. bzoz commented on Mar 19, 2018

    @bzoz
    Contributor

    @seishun fixed this in libuv

  8. added a commit that references this issue on Apr 5, 2018
  9. added a commit that references this issue on Apr 6, 2018
  10. added a commit that references this issue on Aug 7, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    fsIssues and PRs related to file-system APIs and the fs module.windowsIssues and PRs related to the Windows platform.

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions