Skip to content

fs.readSync throws EOF Error instead of returning 0 (Windows, if STDIN is a pipe) #35997

@RomainMuller

Description

@RomainMuller
  • Version: 14.15.0
  • Platform: Windows 10 x86_64
  • Subsystem: fs

What steps will reproduce the bug?

Given the following node script:

/// script.js
const fs = require('fs');

console.error('Node: ' + process.execPath);
console.error('Version: ' + process.version);
console.error('Platform: ' + process.platform);

console.error('process.stdin: ' + process.stdin.constructor.name);

const fd = 0; // STDIN
const buffer = Buffer.alloc(4_096);

let read;
do {
  read = fs.readSync(fd, buffer, 0, buffer.length, null);
  if (read != 0) {
      console.log('STDIN: ' + buffer.slice(0, read).toString('utf-8'))
  }
} while (read != 0);

console.log('EOF was (normally) reached.')

Will behave differently based on how it is invoked:

$ node script.js
Node: C:\Program Files\nodejs\node.exe
Version: v14.15.0
Platform: win32
process.stdin: ReadStream
Data!
STDIN: Data!
^Z
EOF was (normally) reached.


$ echo 'Data!' | node script.js
Node: C:\Program Files\nodejs\node.exe
Version: v14.15.0
Platform: win32
process.stdin: Socket
STDIN: Data!
internal/fs/utils.js:308
    throw err;
    ^

Error: EOF: end of file, read
    at Object.readSync (fs.js:592:3)
    at Object.<anonymous> (H:\repro\test\script.js:14:13)
    at Module._compile (internal/modules/cjs/loader.js:1063:30)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:1092:10)
    at Module.load (internal/modules/cjs/loader.js:928:32)
    at Function.Module._load (internal/modules/cjs/loader.js:769:14)
    at Function.executeUserEntryPoint [as runMain] (internal/modules/run_main.js:72:12)
    at internal/main/run_main_module.js:17:47 {
  errno: -4095,
  syscall: 'read',
  code: 'EOF'
}

How often does it reproduce? Is there a required condition?

This issue happens 100% of the time when process.stdin is a Socket instance.

What is the expected behavior?

The expected and documented behavior is that fs.readSync returns 0 when EOF is reached.

What do you see instead?

Instead, an Error: EOF is thrown, which is unexpected.

Additional information

This problem was surfaced as users are starting to see failures on Windows at aws/aws-cdk#11314.

We have additionally seen issues where in similar conditions (process.stdin is a socket/pipe), attempting to perform fs.readSync on file descriptor 0 (aka STDIN), occasionally results in unexpected EAGAIN errors being thrown, which might be related. That was highlighted in aws/aws-cdk#5187 and we are currently working with a pretty ugly workaround that would be nice if removed (but that other issue is a lot more difficult to steadily reproduce, as it does not always trigger, and may be caused by side-effects of another operation).

Metadata

Metadata

Assignees

No one assigned

    Labels

    fsIssues and PRs related to the fs subsystem / file system.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions