Get rid of coupling for stdout
This commit is contained in:
parent
f618551694
commit
76f98c27de
@ -639,8 +639,10 @@ var FileWriteStream = fs.FileWriteStream = function(path, options) {
|
|||||||
this.busy = false;
|
this.busy = false;
|
||||||
this._queue = [];
|
this._queue = [];
|
||||||
|
|
||||||
this._queue.push([fs.open, this.path, this.flags, this.mode, undefined]);
|
if (this.fd === null) {
|
||||||
this.flush();
|
this._queue.push([fs.open, this.path, this.flags, this.mode, undefined]);
|
||||||
|
this.flush();
|
||||||
|
}
|
||||||
};
|
};
|
||||||
sys.inherits(FileWriteStream, events.EventEmitter);
|
sys.inherits(FileWriteStream, events.EventEmitter);
|
||||||
|
|
||||||
|
13
src/node.js
13
src/node.js
@ -129,8 +129,17 @@ global.clearInterval = global.clearTimeout;
|
|||||||
var stdout;
|
var stdout;
|
||||||
process.__defineGetter__('stdout', function () {
|
process.__defineGetter__('stdout', function () {
|
||||||
if (stdout) return stdout;
|
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;
|
return stdout;
|
||||||
});
|
});
|
||||||
|
@ -12,7 +12,6 @@ namespace node {
|
|||||||
|
|
||||||
|
|
||||||
static struct coupling *stdin_coupling = NULL;
|
static struct coupling *stdin_coupling = NULL;
|
||||||
static struct coupling *stdout_coupling = NULL;
|
|
||||||
|
|
||||||
static int stdin_fd = -1;
|
static int stdin_fd = -1;
|
||||||
static int stdout_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));
|
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() {
|
void Stdio::Flush() {
|
||||||
if (stdin_flags != -1) {
|
if (stdin_flags != -1) {
|
||||||
@ -95,35 +102,26 @@ void Stdio::Flush() {
|
|||||||
close(stdout_fd);
|
close(stdout_fd);
|
||||||
stdout_fd = -1;
|
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) {
|
void Stdio::Initialize(v8::Handle<v8::Object> target) {
|
||||||
HandleScope scope;
|
HandleScope scope;
|
||||||
|
|
||||||
|
stdout_fd = STDOUT_FILENO;
|
||||||
|
|
||||||
if (isatty(STDOUT_FILENO)) {
|
if (isatty(STDOUT_FILENO)) {
|
||||||
// XXX selecting on tty fds wont work in windows.
|
// XXX selecting on tty fds wont work in windows.
|
||||||
// Must ALWAYS make a coupling on shitty platforms.
|
// Must ALWAYS make a coupling on shitty platforms.
|
||||||
stdout_fd = STDOUT_FILENO;
|
stdout_flags = fcntl(stdout_fd, F_GETFL, 0);
|
||||||
} else {
|
int r = fcntl(stdout_fd, F_SETFL, stdout_flags | O_NONBLOCK);
|
||||||
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);
|
|
||||||
|
|
||||||
target->Set(String::NewSymbol("stdoutFD"), Integer::New(stdout_fd));
|
target->Set(String::NewSymbol("stdoutFD"), Integer::New(stdout_fd));
|
||||||
|
|
||||||
NODE_SET_METHOD(target, "writeError", WriteError);
|
NODE_SET_METHOD(target, "writeError", WriteError);
|
||||||
NODE_SET_METHOD(target, "openStdin", OpenStdin);
|
NODE_SET_METHOD(target, "openStdin", OpenStdin);
|
||||||
|
NODE_SET_METHOD(target, "isStdoutBlocking", IsStdoutBlocking);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
4
test/fixtures/echo.js
vendored
4
test/fixtures/echo.js
vendored
@ -5,9 +5,9 @@ print("hello world\r\n");
|
|||||||
var stdin = process.openStdin();
|
var stdin = process.openStdin();
|
||||||
|
|
||||||
stdin.addListener("data", function (data) {
|
stdin.addListener("data", function (data) {
|
||||||
process.stdout.write(data);
|
process.stdout.write(data.toString());
|
||||||
});
|
});
|
||||||
|
|
||||||
stdin.addListener("end", function () {
|
stdin.addListener("end", function () {
|
||||||
process.stdout.close();
|
process.stdout.end();
|
||||||
});
|
});
|
||||||
|
2
test/fixtures/stdout.js
vendored
Normal file
2
test/fixtures/stdout.js
vendored
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
var sys = require('sys');
|
||||||
|
sys.puts('test');
|
19
test/simple/test-stdout-to-file.js
Normal file
19
test/simple/test-stdout-to-file.js
Normal 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);
|
||||||
|
});
|
Loading…
x
Reference in New Issue
Block a user