Skip to content
This repository has been archived by the owner on Apr 22, 2023. It is now read-only.

Commit

Permalink
Add TTYWrap
Browse files Browse the repository at this point in the history
  • Loading branch information
ry committed Sep 20, 2011
1 parent 6b98a63 commit c1ae6ea
Show file tree
Hide file tree
Showing 5 changed files with 119 additions and 0 deletions.
1 change: 1 addition & 0 deletions node.gyp
Expand Up @@ -93,6 +93,7 @@
'src/stream_wrap.cc',
'src/tcp_wrap.cc',
'src/timer_wrap.cc',
'src/tty_wrap.cc',
'src/process_wrap.cc',
'src/v8_typed_array.cc',
'src/udp_wrap.cc',
Expand Down
1 change: 1 addition & 0 deletions src/node_extensions.h
Expand Up @@ -49,6 +49,7 @@ NODE_EXT_LIST_ITEM(node_udp_wrap)
NODE_EXT_LIST_ITEM(node_pipe_wrap)
NODE_EXT_LIST_ITEM(node_cares_wrap)
NODE_EXT_LIST_ITEM(node_stdio_wrap)
NODE_EXT_LIST_ITEM(node_tty_wrap)
NODE_EXT_LIST_ITEM(node_process_wrap)

NODE_EXT_LIST_END
Expand Down
85 changes: 85 additions & 0 deletions src/tty_wrap.cc
@@ -0,0 +1,85 @@
#include <node.h>
#include <node_buffer.h>
#include <req_wrap.h>
#include <handle_wrap.h>
#include <stream_wrap.h>

namespace node {

using v8::Object;
using v8::Handle;
using v8::Local;
using v8::Persistent;
using v8::Value;
using v8::HandleScope;
using v8::FunctionTemplate;
using v8::String;
using v8::Function;
using v8::TryCatch;
using v8::Context;
using v8::Arguments;
using v8::Integer;
using v8::Undefined;


class TTYWrap : StreamWrap {
public:
static void Initialize(Handle<Object> target) {
StreamWrap::Initialize(target);

HandleScope scope;

Local<FunctionTemplate> t = FunctionTemplate::New(New);
t->SetClassName(String::NewSymbol("TTY"));

t->InstanceTemplate()->SetInternalFieldCount(1);

NODE_SET_PROTOTYPE_METHOD(t, "close", HandleWrap::Close);

NODE_SET_PROTOTYPE_METHOD(t, "readStart", StreamWrap::ReadStart);
NODE_SET_PROTOTYPE_METHOD(t, "readStop", StreamWrap::ReadStop);
NODE_SET_PROTOTYPE_METHOD(t, "write", StreamWrap::Write);
NODE_SET_PROTOTYPE_METHOD(t, "write", StreamWrap::Write);

NODE_SET_METHOD(target, "isTTY", IsTTY);

target->Set(String::NewSymbol("TTY"), t->GetFunction());
}

private:
static Handle<Value> IsTTY(const Arguments& args) {
HandleScope scope;
int fd = args[0]->Int32Value();
assert(fd >= 0);
return uv_is_tty(fd) ? v8::True() : v8::False();
}

static Handle<Value> New(const Arguments& args) {
HandleScope scope;

// This constructor should not be exposed to public javascript.
// Therefore we assert that we are not trying to call this as a
// normal function.
assert(args.IsConstructCall());

int fd = args[0]->Int32Value();
assert(fd >= 0);

TTYWrap* wrap = new TTYWrap(args.This(), fd);
assert(wrap);
wrap->UpdateWriteQueueSize();

return scope.Close(args.This());
}

TTYWrap(Handle<Object> object, int fd)
: StreamWrap(object, (uv_stream_t*)&handle_) {
uv_tty_init(uv_default_loop(), &handle_, fd);
}

uv_tty_t handle_;
};

} // namespace node

NODE_MODULE(node_tty_wrap, node::TTYWrap::Initialize);
31 changes: 31 additions & 0 deletions test/simple/test-tty-wrap.js
@@ -0,0 +1,31 @@
var common = require('../common');
var assert = require('assert');

var TTY = process.binding('tty_wrap').TTY;
var isTTY = process.binding('tty_wrap').isTTY;

if (isTTY(1) == false) {
console.error("fd 1 is not a tty. skipping test.");
process.exit(0);
}

var handle = new TTY(1);
var callbacks = 0;

var req1 = handle.write(Buffer("hello world\n"));
req1.oncomplete = function() {
callbacks++;
};

var req2 = handle.write(Buffer("hello world\n"));
req2.oncomplete = function() {
callbacks++;
};

handle.close();

process.on('exit', function() {
assert.equal(2, callbacks);
});


1 change: 1 addition & 0 deletions wscript
Expand Up @@ -889,6 +889,7 @@ def build(bld):
src/pipe_wrap.cc
src/cares_wrap.cc
src/stdio_wrap.cc
src/tty_wrap.cc
src/process_wrap.cc
src/v8_typed_array.cc
"""
Expand Down

0 comments on commit c1ae6ea

Please sign in to comment.