Bind/use uv_guess_handle

This commit is contained in:
Ryan Dahl 2011-09-22 22:00:00 -07:00
parent 74b6426ec6
commit 1de156abb1
2 changed files with 91 additions and 43 deletions

View File

@ -223,12 +223,14 @@
process.__defineGetter__('stdout', function() { process.__defineGetter__('stdout', function() {
if (stdout) return stdout; if (stdout) return stdout;
var binding = process.binding('stdio'), var tty_wrap = process.binding('tty_wrap');
fd = binding.stdoutFD; var binding = process.binding('stdio');
var fd = 1;
// Note stdout._type is used for test-module-load-list.js // Note stdout._type is used for test-module-load-list.js
if (binding.isatty(fd)) { switch (tty_wrap.guessHandleType(fd)) {
case 'TTY':
var tty = NativeModule.require('tty'); var tty = NativeModule.require('tty');
stdout = new tty.WriteStream(fd); stdout = new tty.WriteStream(fd);
stdout._type = "tty"; stdout._type = "tty";
@ -239,27 +241,36 @@
stdout.on('close', function() { stdout.on('close', function() {
binding.ref(); binding.ref();
}); });
} else if (binding.isStdoutBlocking()) { break;
case 'FILE':
var fs = NativeModule.require('fs'); var fs = NativeModule.require('fs');
stdout = new fs.WriteStream(null, {fd: fd}); stdout = new fs.WriteStream(null, {fd: fd});
stdout._type = "fs"; stdout._type = "fs";
} else { break;
case 'PIPE':
var net = NativeModule.require('net'); var net = NativeModule.require('net');
stdout = new net.Stream(fd); stdout = new net.Stream(fd);
// FIXME Hack to have stdout not keep the event loop alive.
// See https://github.com/joyent/node/issues/1726
binding.unref();
stdout.on('close', function() {
binding.ref();
});
// FIXME Should probably have an option in net.Stream to create a // FIXME Should probably have an option in net.Stream to create a
// stream from an existing fd which is writable only. But for now // stream from an existing fd which is writable only. But for now
// we'll just add this hack and set the `readable` member to false. // we'll just add this hack and set the `readable` member to false.
// Test: ./node test/fixtures/echo.js < /etc/passwd // Test: ./node test/fixtures/echo.js < /etc/passwd
stdout.readable = false; stdout.readable = false;
stdout._type = "pipe"; stdout._type = "pipe";
// FIXME Hack to have stdout not keep the event loop alive.
// See https://github.com/joyent/node/issues/1726
binding.unref();
stdout.on('close', function() {
binding.ref();
});
break;
default:
// Probably an error on in uv_guess_handle()
throw new Error("Implement me. Unknown stdout file type!");
} }
// For supporting legacy API we put the FD here. // For supporting legacy API we put the FD here.
@ -280,19 +291,30 @@
process.__defineGetter__('stdin', function() { process.__defineGetter__('stdin', function() {
if (stdin) return stdin; if (stdin) return stdin;
var binding = process.binding('stdio'), var tty_wrap = process.binding('tty_wrap');
fd = binding.openStdin(); var binding = process.binding('stdio');
var fd = 0;
if (binding.isatty(fd)) { switch (tty_wrap.guessHandleType(fd)) {
case 'TTY':
var tty = NativeModule.require('tty'); var tty = NativeModule.require('tty');
stdin = new tty.ReadStream(fd); stdin = new tty.ReadStream(fd);
} else if (binding.isStdinBlocking()) { break;
case 'FILE':
var fs = NativeModule.require('fs'); var fs = NativeModule.require('fs');
stdin = new fs.ReadStream(null, {fd: fd}); stdin = new fs.ReadStream(null, {fd: fd});
} else { break;
case 'PIPE':
var net = NativeModule.require('net'); var net = NativeModule.require('net');
stdin = new net.Stream(fd); stdin = new net.Stream(fd);
stdin.readable = true; stdin.readable = true;
break;
default:
// Probably an error on in uv_guess_handle()
throw new Error("Implement me. Unknown stdin file type!");
} }
// For supporting legacy API we put the FD here. // For supporting legacy API we put the FD here.

View File

@ -54,11 +54,37 @@ class TTYWrap : StreamWrap {
NODE_SET_PROTOTYPE_METHOD(t, "setRawMode", SetRawMode); NODE_SET_PROTOTYPE_METHOD(t, "setRawMode", SetRawMode);
NODE_SET_METHOD(target, "isTTY", IsTTY); NODE_SET_METHOD(target, "isTTY", IsTTY);
NODE_SET_METHOD(target, "guessHandleType", GuessHandleType);
target->Set(String::NewSymbol("TTY"), t->GetFunction()); target->Set(String::NewSymbol("TTY"), t->GetFunction());
} }
private: private:
static Handle<Value> GuessHandleType(const Arguments& args) {
HandleScope scope;
int fd = args[0]->Int32Value();
assert(fd >= 0);
uv_handle_type t = uv_guess_handle(fd);
switch (t) {
case UV_TTY:
return String::New("TTY");
case UV_NAMED_PIPE:
return String::New("PIPE");
case UV_FILE:
return String::New("FILE");
default:
assert(0);
return v8::Undefined();
}
return uv_is_tty(fd) ? v8::True() : v8::False();
}
static Handle<Value> IsTTY(const Arguments& args) { static Handle<Value> IsTTY(const Arguments& args) {
HandleScope scope; HandleScope scope;
int fd = args[0]->Int32Value(); int fd = args[0]->Int32Value();