Skip to content

Input from TTY is strange #2504

Description

@anseki

I tried read from STDIN by fs.readSync that is given process.stdin.fd.
For example:

var
  fs = require('fs'),
  buffer = new Buffer(1024),
  fd = process.platform === 'win32' ? process.stdin.fd : fs.openSync('/dev/tty', 'r'),
  readSize = fs.readSync(fd, buffer, 0, 1024);

console.log('INPUT: ' + buffer.toString('utf8', 0, readSize));

In v2.3.1-, no problem:

foo
INPUT: foo

In v2.3.2+, first line is ignored, and second line is accepted:

foo
bar
INPUT: bar

This problem occurs in only Windows + iojs v2.3.2+.
I don't use process.stdin.fd in non-Win because fs.readSync can't read it.
Therefore, process.stdin of v2.3.2+ might have problem. (not fs.readSync)

Activity

  1. added
    fsIssues and PRs related to file-system APIs and the fs module.
    windowsIssues and PRs related to the Windows platform.
    on Aug 23, 2015
  2. brendanashworth commented on Aug 23, 2015

    @brendanashworth
    Contributor

    This is seems to be a regression that could have been introduced by 8cee8f5 (didn't do git bisect, just layman's bisecting). @nodejs/platform-windows ?

  3. anseki commented on Aug 23, 2015

    @anseki
    Author

    If 8cee8f5 made this problem, I think that windows label is not suitably, because I didn't use process.stdin in non-Win. And in case that doesn't use process.stdin (open('CONIN$') instead of it) in Windows is no problem.

  4. mscdex commented on Aug 23, 2015

    @mscdex
    Contributor

    From what I can tell it has to do with process.stdin taking so long to initialize when first accessed.

    For example, if you use:

    process.stdin;
    console.log('ready');
    var
      fs = require('fs'),
      buffer = new Buffer(1024),
      fd = process.platform === 'win32' ? process.stdin.fd : fs.openSync('/dev/tty', 'r'),
      readSize = fs.readSync(fd, buffer, 0, 1024);
    
    console.log('INPUT: ' + buffer.toString('utf8', 0, readSize));

    Then the first line will get read as expected if you type it after ready is displayed.

  5. mscdex commented on Aug 23, 2015

    @mscdex
    Contributor

    You can also replace process.stdin.fd in the original code with just 0 and it will get the first line too.

    I'm trying this all on Windows, so I haven't looked at it on *nix. Also, reverting 8cee8f5 does not affect this particular issue.

  6. anseki commented on Aug 24, 2015

    @anseki
    Author

    Thank you, but... I tried your solution, and it did not read first line.

    ready
    foo
    bar
    INPUT: bar

    I tried your sample code on Windows 8.1 64bit with iojs v2.3.1, v2.3.2 and v3.1.0. Of course v2.3.1 works fine.

    Also I tried 0 instead of process.stdin.fd. It works fine before accessing to process.stdin, but it doesn't read first line after accessing to process.stdin.

    For example, this code doesn't read first line:

    var
      fs = require('fs'),
      buffer = new Buffer(1024),
      fd = process.platform === 'win32' ? process.stdin.fd : fs.openSync('/dev/tty', 'r'),
      //readSize = fs.readSync(fd, buffer, 0, 1024);
      readSize = fs.readSync(0, buffer, 0, 1024);
    
    console.log('INPUT: ' + buffer.toString('utf8', 0, readSize));

    Yes I know that fd is meaningless now, then this works fine:

    var
      fs = require('fs'),
      buffer = new Buffer(1024),
      //fd = process.platform === 'win32' ? process.stdin.fd : fs.openSync('/dev/tty', 'r'),
      //readSize = fs.readSync(fd, buffer, 0, 1024);
      readSize = fs.readSync(0, buffer, 0, 1024);
    
    console.log('INPUT: ' + buffer.toString('utf8', 0, readSize));

    But process.stdin might be used at a place I don't know. (e.g. other packages)
    That is, this code doesn't read first line:

    process.stdin;
    
    var
      fs = require('fs'),
      buffer = new Buffer(1024),
      readSize = fs.readSync(0, buffer, 0, 1024);
    
    console.log('INPUT: ' + buffer.toString('utf8', 0, readSize));

    I think that a point is that the programers don't know that process.stdin makes problem, and it should not so. (this is not designed behavior, right?)

  7. orangemocha commented on Sep 9, 2015

    @orangemocha
    Contributor

    @nodejs/streams : is it legal to use fs.readSync to read from process.stdin, which in this case is not a file?

  8. calvinmetcalf commented on Sep 9, 2015

    @calvinmetcalf
    Contributor

    so is the issue that references to process.stdin initiate the readable stream, which does some buffering and that buffering prevents somebody from reading stdin like it was a file?

  9. anseki commented on Sep 9, 2015

    @anseki
    Author

    It seems that programmers use read/readSync with STDIN to get the user's input easily instead of process.stdin.on('data'). Also my module readlineSync tries readSync.
    https://www.google.com/search?q=nodejs+read+from+stdin

    This problem occurs when it reads from TTY. It seems no problem when it reads from the file or pipe. (e.g. script < file, echo foo | script etc)

  10. anseki commented on Oct 17, 2015

    @anseki
    Author

    It seems that the Readline module also is affected by this problem.

    For example:

    var readline = require('readline').createInterface({
      input: process.stdin,
      output: process.stdout
    });
    
    readline.question('> ', function(answer) {
      console.log('INPUT: ', answer);
      readline.close();
    });

    In io.js v2.3.1-, no problem:

    > foo
    INPUT:  foo
    

    In io.js v2.3.2+, strange second line is shown:

    > foo
    foo
    INPUT:  foo
    

    Node.js v4.2.1 also returns same result:

    > foo
    foo
    INPUT:  foo
    
  11. anseki commented on Oct 17, 2015

    @anseki
    Author

    It seems that REPL also is affected by this problem.

    I typed a first 1 and pushed the Enter key.
    In io.js v2.3.1-, no problem:

    E:\test>node
    > 1
    1
    >
    

    In io.js v2.3.2+, strange second 1 is shown:

    E:\test>node
    > 1
    1
    1
    >
    

    Node.js v4.2.1 also returns same result:

    E:\test>node
    > 1
    1
    1
    >
    
  12. changed the title [-]fs.readSync of v2.3.2+ can't read first line from STDIN[/-] [+]Input from STDIN is strange[/+] on Oct 17, 2015
  13. changed the title [-]Input from STDIN is strange[/-] [+]Input from TTY is strange[/+] on Oct 17, 2015
  14. anseki commented on Oct 17, 2015

    @anseki
    Author

    It seems that only the first line of both readline module and REPL is strange, like readSync.
    #2504 (comment)

    For example:

    > foo
    foo
    INPUT:  foo
    > bar
    INPUT:  bar
    
    E:\test>node
    > 1
    1
    1
    > 2
    2
    >
    
  15. 6 remaining items

  16. silverwind commented on Oct 22, 2015

    @silverwind
    Contributor

    Filed #3490 for the revert. I could use some assistence with a regression test for this.

  17. anseki commented on Jun 4, 2016

    @anseki
    Author

    Related to #5384

    This issue came again, and it was fixed in v6.2.0.
    Then, the versions of Node.js that have the problem:

    • VERSION >= 2.3.2 && VERSION < 4.2.4
    • VERSION >= 5.0.0 && VERSION < 5.1.0
    • VERSION >= 5.6.0 && VERSION < 6.2.0

    Easy check:

    var verNum = (function(ver) {
        var nums = ver.replace(/^\D+/, '').split('.');
        var verNum = 0;
        if ((nums[0] = +nums[0])) { verNum += nums[0] * 10000; }
        if ((nums[1] = +nums[1])) { verNum += nums[1] * 100; }
        if ((nums[2] = +nums[2])) { verNum += nums[2]; }
        return verNum;
      })(process.version),
    
      hasProblem =
        verNum >= 20302 && verNum < 40204 ||
        verNum >= 50000 && verNum < 50100 ||
        verNum >= 50600 && verNum < 60200;
    
    if (hasProblem) {
      console.log('TTY has problem.');
    } else {
      console.log('TTY has NO problem.');
    }
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

    readlineIssues and PRs related to the built-in readline module.streamIssues and PRs related to Node.js streams.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