From 76f98c27de4564fcefee83878f525a9a66940a0e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felix=20Geisend=C3=B6rfer?= Date: Tue, 20 Apr 2010 00:22:59 +0200 Subject: [PATCH] Get rid of coupling for stdout --- lib/fs.js | 6 ++++-- src/node.js | 13 +++++++++++-- src/node_stdio.cc | 28 +++++++++++++--------------- test/fixtures/echo.js | 4 ++-- test/fixtures/stdout.js | 2 ++ test/simple/test-stdout-to-file.js | 19 +++++++++++++++++++ 6 files changed, 51 insertions(+), 21 deletions(-) create mode 100644 test/fixtures/stdout.js create mode 100644 test/simple/test-stdout-to-file.js diff --git a/lib/fs.js b/lib/fs.js index 963ac6a7cf..75f5112bd2 100644 --- a/lib/fs.js +++ b/lib/fs.js @@ -639,8 +639,10 @@ var FileWriteStream = fs.FileWriteStream = function(path, options) { this.busy = false; this._queue = []; - this._queue.push([fs.open, this.path, this.flags, this.mode, undefined]); - this.flush(); + if (this.fd === null) { + this._queue.push([fs.open, this.path, this.flags, this.mode, undefined]); + this.flush(); + } }; sys.inherits(FileWriteStream, events.EventEmitter); diff --git a/src/node.js b/src/node.js index 253cf0ff7b..caaf27d93d 100644 --- a/src/node.js +++ b/src/node.js @@ -129,8 +129,17 @@ global.clearInterval = global.clearTimeout; var stdout; process.__defineGetter__('stdout', function () { if (stdout) return stdout; - var net = module.requireNative('net'); - stdout = new net.Stream(process.binding('stdio').stdoutFD); + + var binding = process.binding('stdio'), + net = module.requireNative('net'), + fs = module.requireNative('fs'), + fd = binding.stdoutFD; + + if (binding.isStdoutBlocking()) { + stdout = new fs.FileWriteStream(null, {fd: fd}); + } else { + stdout = new net.Stream(fd); + } return stdout; }); diff --git a/src/node_stdio.cc b/src/node_stdio.cc index b5caf0aa3e..01a123ac41 100644 --- a/src/node_stdio.cc +++ b/src/node_stdio.cc @@ -12,7 +12,6 @@ namespace node { static struct coupling *stdin_coupling = NULL; -static struct coupling *stdout_coupling = NULL; static int stdin_fd = -1; static int stdout_fd = -1; @@ -81,6 +80,14 @@ static Handle OpenStdin(const Arguments& args) { return scope.Close(Integer::New(stdin_fd)); } +static Handle +IsStdoutBlocking (const Arguments& args) +{ + HandleScope scope; + bool tty = isatty(STDOUT_FILENO); + return scope.Close(Boolean::New(!tty)); +} + void Stdio::Flush() { if (stdin_flags != -1) { @@ -95,35 +102,26 @@ void Stdio::Flush() { close(stdout_fd); stdout_fd = -1; } - - if (stdout_coupling) { - coupling_join(stdout_coupling); - coupling_destroy(stdout_coupling); - stdout_coupling = NULL; - } } void Stdio::Initialize(v8::Handle target) { HandleScope scope; + stdout_fd = STDOUT_FILENO; + if (isatty(STDOUT_FILENO)) { // XXX selecting on tty fds wont work in windows. // Must ALWAYS make a coupling on shitty platforms. - stdout_fd = STDOUT_FILENO; - } else { - stdout_coupling = coupling_new_push(STDOUT_FILENO); - stdout_fd = coupling_nonblocking_fd(stdout_coupling); + stdout_flags = fcntl(stdout_fd, F_GETFL, 0); + int r = fcntl(stdout_fd, F_SETFL, stdout_flags | O_NONBLOCK); } - stdout_flags = fcntl(stdout_fd, F_GETFL, 0); - - int r = fcntl(stdout_fd, F_SETFL, stdout_flags | O_NONBLOCK); - target->Set(String::NewSymbol("stdoutFD"), Integer::New(stdout_fd)); NODE_SET_METHOD(target, "writeError", WriteError); NODE_SET_METHOD(target, "openStdin", OpenStdin); + NODE_SET_METHOD(target, "isStdoutBlocking", IsStdoutBlocking); } diff --git a/test/fixtures/echo.js b/test/fixtures/echo.js index 60f3b614a0..4a963c9142 100644 --- a/test/fixtures/echo.js +++ b/test/fixtures/echo.js @@ -5,9 +5,9 @@ print("hello world\r\n"); var stdin = process.openStdin(); stdin.addListener("data", function (data) { - process.stdout.write(data); + process.stdout.write(data.toString()); }); stdin.addListener("end", function () { - process.stdout.close(); + process.stdout.end(); }); diff --git a/test/fixtures/stdout.js b/test/fixtures/stdout.js new file mode 100644 index 0000000000..9aa72340c1 --- /dev/null +++ b/test/fixtures/stdout.js @@ -0,0 +1,2 @@ +var sys = require('sys'); +sys.puts('test'); \ No newline at end of file diff --git a/test/simple/test-stdout-to-file.js b/test/simple/test-stdout-to-file.js new file mode 100644 index 0000000000..12d8b5e2eb --- /dev/null +++ b/test/simple/test-stdout-to-file.js @@ -0,0 +1,19 @@ +require('../common'); +var path = require('path') + , childProccess = require('child_process') + , fs = require('fs') + , stdoutScript = path.join(path.dirname(__dirname), 'fixtures/stdout.js') + , tmpFile = path.join(path.dirname(__dirname), 'fixtures/stdout.txt') + , cmd = process.argv[0]+' '+stdoutScript+' > '+tmpFile; + +try { + fs.unlinkSync(tmpFile); +} catch (e) {} + +childProccess.exec(cmd, function(err) { + if (err) throw err; + + var data = fs.readFileSync(tmpFile); + assert.equal(data, "test\n"); + fs.unlinkSync(tmpFile); +}); \ No newline at end of file