diff --git a/lib/fs.js b/lib/fs.js index d5d1a2050ac..15c37e06523 100644 --- a/lib/fs.js +++ b/lib/fs.js @@ -499,8 +499,11 @@ var FileReadStream = fs.FileReadStream = function(path, options) { this[key] = options[key]; } - var self = this; + if (this.fd !== null) { + return; + } + var self = this; fs.open(this.path, this.flags, this.mode, function(err, fd) { if (err) { self.emit('error', err); diff --git a/src/node.js b/src/node.js index caaf27d93d8..1ebed979e6f 100644 --- a/src/node.js +++ b/src/node.js @@ -147,11 +147,20 @@ process.__defineGetter__('stdout', function () { var stdin; process.openStdin = function () { if (stdin) return stdin; - var net = module.requireNative('net'); - var fd = process.binding('stdio').openStdin(); - stdin = new net.Stream(fd); + + var net = module.requireNative('net') + , fs = module.requireNative('fs') + , fd = process.binding('stdio').openStdin(); + + if (process.binding('stdio').isStdinBlocking()) { + stdin = new net.Stream(fd); + stdin.readable = true; + } else { + stdin = new fs.FileReadStream(null, {fd: fd}); + } + stdin.resume(); - stdin.readable = true; + return stdin; }; diff --git a/src/node_stdio.cc b/src/node_stdio.cc index 01a123ac410..c27e6f37263 100644 --- a/src/node_stdio.cc +++ b/src/node_stdio.cc @@ -1,6 +1,5 @@ #include #include -#include #include #include @@ -11,8 +10,6 @@ using namespace v8; namespace node { -static struct coupling *stdin_coupling = NULL; - static int stdin_fd = -1; static int stdout_fd = -1; @@ -56,30 +53,33 @@ static Handle OpenStdin(const Arguments& args) { return ThrowException(Exception::Error(String::New("stdin already open"))); } + stdin_fd = STDIN_FILENO; if (isatty(STDIN_FILENO)) { // XXX selecting on tty fds wont work in windows. // Must ALWAYS make a coupling on shitty platforms. - stdin_fd = STDIN_FILENO; - } else { - stdin_coupling = coupling_new_pull(STDIN_FILENO); - stdin_fd = coupling_nonblocking_fd(stdin_coupling); - } + stdin_flags = fcntl(stdin_fd, F_GETFL, 0); + if (stdin_flags == -1) { + // TODO DRY + return ThrowException(Exception::Error(String::New("fcntl error!"))); + } - stdin_flags = fcntl(stdin_fd, F_GETFL, 0); - if (stdin_flags == -1) { - // TODO DRY - return ThrowException(Exception::Error(String::New("fcntl error!"))); - } - - int r = fcntl(stdin_fd, F_SETFL, stdin_flags | O_NONBLOCK); - if (r == -1) { - // TODO DRY - return ThrowException(Exception::Error(String::New("fcntl error!"))); + int r = fcntl(stdin_fd, F_SETFL, stdin_flags | O_NONBLOCK); + if (r == -1) { + // TODO DRY + return ThrowException(Exception::Error(String::New("fcntl error!"))); + } } return scope.Close(Integer::New(stdin_fd)); } +static Handle +IsStdinBlocking (const Arguments& args) +{ + HandleScope scope; + return scope.Close(Boolean::New(isatty(STDIN_FILENO))); +} + static Handle IsStdoutBlocking (const Arguments& args) { @@ -122,6 +122,7 @@ void Stdio::Initialize(v8::Handle target) { NODE_SET_METHOD(target, "writeError", WriteError); NODE_SET_METHOD(target, "openStdin", OpenStdin); NODE_SET_METHOD(target, "isStdoutBlocking", IsStdoutBlocking); + NODE_SET_METHOD(target, "isStdinBlocking", IsStdinBlocking); } diff --git a/test/simple/test-stdin-from-file.js b/test/simple/test-stdin-from-file.js new file mode 100644 index 00000000000..3167adfd640 --- /dev/null +++ b/test/simple/test-stdin-from-file.js @@ -0,0 +1,26 @@ +require('../common'); +var TEST_STR = "abc\n123\nhello world\nsomething else" + , path = require('path') + , childProccess = require('child_process') + , fs = require('fs') + , stdoutScript = path.join(fixturesDir, 'echo.js') + , tmpFile = path.join(fixturesDir, 'stdin.txt') + , cmd = process.argv[0] + ' ' + stdoutScript + ' < ' + tmpFile + ; + +puts(cmd + "\n\n"); + +try { + fs.unlinkSync(tmpFile); +} catch (e) {} + +fs.writeFileSync(tmpFile, TEST_STR); + +childProccess.exec(cmd, function(err, stdout, stderr) { + fs.unlinkSync(tmpFile); + + if (err) throw err; + puts(stdout); + assert.equal(stdout, "hello world\r\n" + TEST_STR); + assert.equal("", stderr); +});