Get rid of coupling for stdout

This commit is contained in:
Felix Geisendörfer 2010-04-20 00:22:59 +02:00 committed by Ryan Dahl
parent f618551694
commit 76f98c27de
6 changed files with 51 additions and 21 deletions

View File

@ -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);

View File

@ -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;
});

View File

@ -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<Value> OpenStdin(const Arguments& args) {
return scope.Close(Integer::New(stdin_fd));
}
static Handle<Value>
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<v8::Object> 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);
}

View File

@ -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();
});

2
test/fixtures/stdout.js vendored Normal file
View File

@ -0,0 +1,2 @@
var sys = require('sys');
sys.puts('test');

View File

@ -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);
});