Remove stray NODE_MODULE() semi-colons.
[platform/upstream/nodejs.git] / src / tty_wrap.cc
1 // Copyright Joyent, Inc. and other Node contributors.
2 //
3 // Permission is hereby granted, free of charge, to any person obtaining a
4 // copy of this software and associated documentation files (the
5 // "Software"), to deal in the Software without restriction, including
6 // without limitation the rights to use, copy, modify, merge, publish,
7 // distribute, sublicense, and/or sell copies of the Software, and to permit
8 // persons to whom the Software is furnished to do so, subject to the
9 // following conditions:
10 //
11 // The above copyright notice and this permission notice shall be included
12 // in all copies or substantial portions of the Software.
13 //
14 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
15 // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
17 // NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
18 // DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
19 // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
20 // USE OR OTHER DEALINGS IN THE SOFTWARE.
21
22 #include <node.h>
23 #include <node_buffer.h>
24 #include <req_wrap.h>
25 #include <handle_wrap.h>
26 #include <stream_wrap.h>
27
28 namespace node {
29
30 using v8::Object;
31 using v8::Handle;
32 using v8::Local;
33 using v8::Persistent;
34 using v8::Value;
35 using v8::HandleScope;
36 using v8::FunctionTemplate;
37 using v8::String;
38 using v8::Function;
39 using v8::TryCatch;
40 using v8::Context;
41 using v8::Arguments;
42 using v8::Integer;
43 using v8::Undefined;
44
45 #define UNWRAP \
46   assert(!args.Holder().IsEmpty()); \
47   assert(args.Holder()->InternalFieldCount() > 0); \
48   TTYWrap* wrap =  \
49       static_cast<TTYWrap*>(args.Holder()->GetPointerFromInternalField(0)); \
50   if (!wrap) { \
51     uv_err_t err; \
52     err.code = UV_EBADF; \
53     SetErrno(err); \
54     return scope.Close(Integer::New(-1)); \
55   }
56
57
58 class TTYWrap : StreamWrap {
59  public:
60   static void Initialize(Handle<Object> target) {
61     StreamWrap::Initialize(target);
62
63     HandleScope scope;
64
65     Local<FunctionTemplate> t = FunctionTemplate::New(New);
66     t->SetClassName(String::NewSymbol("TTY"));
67
68     t->InstanceTemplate()->SetInternalFieldCount(1);
69
70     NODE_SET_PROTOTYPE_METHOD(t, "close", HandleWrap::Close);
71     NODE_SET_PROTOTYPE_METHOD(t, "unref", HandleWrap::Unref);
72
73     NODE_SET_PROTOTYPE_METHOD(t, "readStart", StreamWrap::ReadStart);
74     NODE_SET_PROTOTYPE_METHOD(t, "readStop", StreamWrap::ReadStop);
75     NODE_SET_PROTOTYPE_METHOD(t, "write", StreamWrap::Write);
76
77     NODE_SET_PROTOTYPE_METHOD(t, "getWindowSize", TTYWrap::GetWindowSize);
78     NODE_SET_PROTOTYPE_METHOD(t, "setRawMode", SetRawMode);
79
80     NODE_SET_METHOD(target, "isTTY", IsTTY);
81     NODE_SET_METHOD(target, "guessHandleType", GuessHandleType);
82
83     target->Set(String::NewSymbol("TTY"), t->GetFunction());
84   }
85
86  private:
87   static Handle<Value> GuessHandleType(const Arguments& args) {
88     HandleScope scope;
89     int fd = args[0]->Int32Value();
90     assert(fd >= 0);
91
92     uv_handle_type t = uv_guess_handle(fd);
93
94     switch (t) {
95       case UV_TTY:
96         return scope.Close(String::New("TTY"));
97
98       case UV_NAMED_PIPE:
99         return scope.Close(String::New("PIPE"));
100
101       case UV_FILE:
102         return scope.Close(String::New("FILE"));
103
104       default:
105         assert(0);
106         return v8::Undefined();
107     }
108   }
109
110   static Handle<Value> IsTTY(const Arguments& args) {
111     HandleScope scope;
112     int fd = args[0]->Int32Value();
113     assert(fd >= 0);
114     return uv_guess_handle(fd) == UV_TTY ? v8::True() : v8::False();
115   }
116
117   static Handle<Value> GetWindowSize(const Arguments& args) {
118     HandleScope scope;
119
120     UNWRAP
121
122     int width, height;
123     int r = uv_tty_get_winsize(&wrap->handle_, &width, &height);
124
125     if (r) {
126       SetErrno(uv_last_error(uv_default_loop()));
127       return v8::Undefined();
128     }
129
130     Local<v8::Array> a = v8::Array::New(2);
131     a->Set(0, Integer::New(width));
132     a->Set(1, Integer::New(height));
133
134     return scope.Close(a);
135   }
136
137   static Handle<Value> SetRawMode(const Arguments& args) {
138     HandleScope scope;
139
140     UNWRAP
141
142     int r = uv_tty_set_mode(&wrap->handle_, args[0]->IsTrue());
143
144     if (r) {
145       SetErrno(uv_last_error(uv_default_loop()));
146     }
147
148     return scope.Close(Integer::New(r));
149   }
150
151   static Handle<Value> New(const Arguments& args) {
152     HandleScope scope;
153
154     // This constructor should not be exposed to public javascript.
155     // Therefore we assert that we are not trying to call this as a
156     // normal function.
157     assert(args.IsConstructCall());
158
159     int fd = args[0]->Int32Value();
160     assert(fd >= 0);
161
162     TTYWrap* wrap = new TTYWrap(args.This(), fd, args[1]->IsTrue());
163     assert(wrap);
164     wrap->UpdateWriteQueueSize();
165
166     return scope.Close(args.This());
167   }
168
169   TTYWrap(Handle<Object> object, int fd, bool readable)
170       : StreamWrap(object, (uv_stream_t*)&handle_) {
171     uv_tty_init(uv_default_loop(), &handle_, fd, readable);
172   }
173
174   uv_tty_t handle_;
175 };
176
177 }  // namespace node
178
179 NODE_MODULE(node_tty_wrap, node::TTYWrap::Initialize)