Skip to content
Newer
Older
100644 293 lines (207 sloc) 7.91 KB
60818b9 @ry Add missing copyright headers
ry authored
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
ff4a9d3 @bnoordhuis core: use proper #include directives
bnoordhuis authored
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 #include "pipe_wrap.h"
cc0f608 @ry Add pipe_wrap
ry authored
28
29 namespace node {
30
31 using v8::Object;
32 using v8::Handle;
33 using v8::Local;
34 using v8::Persistent;
35 using v8::Value;
36 using v8::HandleScope;
37 using v8::FunctionTemplate;
38 using v8::String;
39 using v8::Function;
40 using v8::TryCatch;
41 using v8::Context;
42 using v8::Arguments;
43 using v8::Integer;
c7771bc set readable/writable for pipes
Igor Zinkovsky authored
44 using v8::Boolean;
cc0f608 @ry Add pipe_wrap
ry authored
45
187fe27 stdio binding + javascript to enable process.stdin.listen()
Igor Zinkovsky authored
46 Persistent<Function> pipeConstructor;
cc0f608 @ry Add pipe_wrap
ry authored
47
a26bee8 @isaacs MakeCallback: Consistent symbol usage
isaacs authored
48 static Persistent<String> onconnection_sym;
49 static Persistent<String> oncomplete_sym;
50
cc0f608 @ry Add pipe_wrap
ry authored
51
52 // TODO share with TCPWrap?
53 typedef class ReqWrap<uv_connect_t> ConnectWrap;
54
55
f01b241 @ry add wrapper for uv_spawn
ry authored
56 uv_pipe_t* PipeWrap::UVHandle() {
57 return &handle_;
58 }
cc0f608 @ry Add pipe_wrap
ry authored
59
60
296b7a5 @bnoordhuis cluster: support passing of named pipes
bnoordhuis authored
61 Local<Object> PipeWrap::Instantiate() {
62 HandleScope scope;
63 assert(!pipeConstructor.IsEmpty());
64 return scope.Close(pipeConstructor->NewInstance());
65 }
66
67
f01b241 @ry add wrapper for uv_spawn
ry authored
68 PipeWrap* PipeWrap::Unwrap(Local<Object> obj) {
69 assert(!obj.IsEmpty());
70 assert(obj->InternalFieldCount() > 0);
71 return static_cast<PipeWrap*>(obj->GetPointerFromInternalField(0));
72 }
cc0f608 @ry Add pipe_wrap
ry authored
73
74
f01b241 @ry add wrapper for uv_spawn
ry authored
75 void PipeWrap::Initialize(Handle<Object> target) {
76 StreamWrap::Initialize(target);
cc0f608 @ry Add pipe_wrap
ry authored
77
f01b241 @ry add wrapper for uv_spawn
ry authored
78 HandleScope scope;
61cda1e @ry PipeWrap should use HandleWrap::Close
ry authored
79
f01b241 @ry add wrapper for uv_spawn
ry authored
80 Local<FunctionTemplate> t = FunctionTemplate::New(New);
81 t->SetClassName(String::NewSymbol("Pipe"));
cc0f608 @ry Add pipe_wrap
ry authored
82
f01b241 @ry add wrapper for uv_spawn
ry authored
83 t->InstanceTemplate()->SetInternalFieldCount(1);
cc0f608 @ry Add pipe_wrap
ry authored
84
f01b241 @ry add wrapper for uv_spawn
ry authored
85 NODE_SET_PROTOTYPE_METHOD(t, "close", HandleWrap::Close);
7e62bc9 @ry Move process.stdout unref hack to handle_wrap.cc
ry authored
86 NODE_SET_PROTOTYPE_METHOD(t, "unref", HandleWrap::Unref);
19d43f8 @tjfontaine export HandleWrap Unref Ref in tcp/udp/timer/pipe
tjfontaine authored
87 NODE_SET_PROTOTYPE_METHOD(t, "ref", HandleWrap::Ref);
cc0f608 @ry Add pipe_wrap
ry authored
88
f01b241 @ry add wrapper for uv_spawn
ry authored
89 NODE_SET_PROTOTYPE_METHOD(t, "readStart", StreamWrap::ReadStart);
90 NODE_SET_PROTOTYPE_METHOD(t, "readStop", StreamWrap::ReadStop);
91 NODE_SET_PROTOTYPE_METHOD(t, "shutdown", StreamWrap::Shutdown);
cc0f608 @ry Add pipe_wrap
ry authored
92
0e57aaf @piscisaureus Optimize writing strings with Socket.write
piscisaureus authored
93 NODE_SET_PROTOTYPE_METHOD(t, "writeBuffer", StreamWrap::WriteBuffer);
94 NODE_SET_PROTOTYPE_METHOD(t, "writeAsciiString", StreamWrap::WriteAsciiString);
95 NODE_SET_PROTOTYPE_METHOD(t, "writeUtf8String", StreamWrap::WriteUtf8String);
b673d06 @piscisaureus Net.js: fix UCS2 write crash due to inconsistent naming
piscisaureus authored
96 NODE_SET_PROTOTYPE_METHOD(t, "writeUcs2String", StreamWrap::WriteUcs2String);
0e57aaf @piscisaureus Optimize writing strings with Socket.write
piscisaureus authored
97
f01b241 @ry add wrapper for uv_spawn
ry authored
98 NODE_SET_PROTOTYPE_METHOD(t, "bind", Bind);
99 NODE_SET_PROTOTYPE_METHOD(t, "listen", Listen);
100 NODE_SET_PROTOTYPE_METHOD(t, "connect", Connect);
caaa59c @ry Wrap uv_pipe_open, implement net.Stream(fd);
ry authored
101 NODE_SET_PROTOTYPE_METHOD(t, "open", Open);
cc0f608 @ry Add pipe_wrap
ry authored
102
99c9d19 binding for uv_pipe_pending_instances
Igor Zinkovsky authored
103 #ifdef _WIN32
104 NODE_SET_PROTOTYPE_METHOD(t, "setPendingInstances", SetPendingInstances);
105 #endif
106
f01b241 @ry add wrapper for uv_spawn
ry authored
107 pipeConstructor = Persistent<Function>::New(t->GetFunction());
cc0f608 @ry Add pipe_wrap
ry authored
108
f01b241 @ry add wrapper for uv_spawn
ry authored
109 target->Set(String::NewSymbol("Pipe"), pipeConstructor);
110 }
cc0f608 @ry Add pipe_wrap
ry authored
111
112
f01b241 @ry add wrapper for uv_spawn
ry authored
113 Handle<Value> PipeWrap::New(const Arguments& args) {
114 // This constructor should not be exposed to public javascript.
115 // Therefore we assert that we are not trying to call this as a
116 // normal function.
117 assert(args.IsConstructCall());
cc0f608 @ry Add pipe_wrap
ry authored
118
f01b241 @ry add wrapper for uv_spawn
ry authored
119 HandleScope scope;
471c570 @ry uv_write2 uv_read2_start binding
ry authored
120 PipeWrap* wrap = new PipeWrap(args.This(), args[0]->IsTrue());
f01b241 @ry add wrapper for uv_spawn
ry authored
121 assert(wrap);
cc0f608 @ry Add pipe_wrap
ry authored
122
f01b241 @ry add wrapper for uv_spawn
ry authored
123 return scope.Close(args.This());
124 }
cc0f608 @ry Add pipe_wrap
ry authored
125
126
471c570 @ry uv_write2 uv_read2_start binding
ry authored
127 PipeWrap::PipeWrap(Handle<Object> object, bool ipc)
128 : StreamWrap(object, (uv_stream_t*) &handle_) {
129 int r = uv_pipe_init(uv_default_loop(), &handle_, ipc);
f01b241 @ry add wrapper for uv_spawn
ry authored
130 assert(r == 0); // How do we proxy this error up to javascript?
131 // Suggestion: uv_pipe_init() returns void.
132 handle_.data = reinterpret_cast<void*>(this);
133 UpdateWriteQueueSize();
134 }
cc0f608 @ry Add pipe_wrap
ry authored
135
136
f01b241 @ry add wrapper for uv_spawn
ry authored
137 Handle<Value> PipeWrap::Bind(const Arguments& args) {
138 HandleScope scope;
cc0f608 @ry Add pipe_wrap
ry authored
139
45de259 @Sannis Make UNWRAP macro generic.
Sannis authored
140 UNWRAP(PipeWrap)
cc0f608 @ry Add pipe_wrap
ry authored
141
249c3c1 Avoiding unnecessary ToString() calls
ssuda authored
142 String::AsciiValue name(args[0]);
cc0f608 @ry Add pipe_wrap
ry authored
143
f01b241 @ry add wrapper for uv_spawn
ry authored
144 int r = uv_pipe_bind(&wrap->handle_, *name);
cc0f608 @ry Add pipe_wrap
ry authored
145
f01b241 @ry add wrapper for uv_spawn
ry authored
146 // Error starting the pipe.
6cc4292 @ry Display sys_errno when UV_UNKNOWN is returned
ry authored
147 if (r) SetErrno(uv_last_error(uv_default_loop()));
cc0f608 @ry Add pipe_wrap
ry authored
148
f01b241 @ry add wrapper for uv_spawn
ry authored
149 return scope.Close(Integer::New(r));
150 }
cc0f608 @ry Add pipe_wrap
ry authored
151
152
99c9d19 binding for uv_pipe_pending_instances
Igor Zinkovsky authored
153 #ifdef _WIN32
154 Handle<Value> PipeWrap::SetPendingInstances(const Arguments& args) {
155 HandleScope scope;
156
45de259 @Sannis Make UNWRAP macro generic.
Sannis authored
157 UNWRAP(PipeWrap)
99c9d19 binding for uv_pipe_pending_instances
Igor Zinkovsky authored
158
159 int instances = args[0]->Int32Value();
160
161 uv_pipe_pending_instances(&wrap->handle_, instances);
162
163 return v8::Null();
164 }
165 #endif
166
167
f01b241 @ry add wrapper for uv_spawn
ry authored
168 Handle<Value> PipeWrap::Listen(const Arguments& args) {
169 HandleScope scope;
cc0f608 @ry Add pipe_wrap
ry authored
170
45de259 @Sannis Make UNWRAP macro generic.
Sannis authored
171 UNWRAP(PipeWrap)
cc0f608 @ry Add pipe_wrap
ry authored
172
f01b241 @ry add wrapper for uv_spawn
ry authored
173 int backlog = args[0]->Int32Value();
cc0f608 @ry Add pipe_wrap
ry authored
174
f01b241 @ry add wrapper for uv_spawn
ry authored
175 int r = uv_listen((uv_stream_t*)&wrap->handle_, backlog, OnConnection);
cc0f608 @ry Add pipe_wrap
ry authored
176
f01b241 @ry add wrapper for uv_spawn
ry authored
177 // Error starting the pipe.
6cc4292 @ry Display sys_errno when UV_UNKNOWN is returned
ry authored
178 if (r) SetErrno(uv_last_error(uv_default_loop()));
cc0f608 @ry Add pipe_wrap
ry authored
179
f01b241 @ry add wrapper for uv_spawn
ry authored
180 return scope.Close(Integer::New(r));
181 }
cc0f608 @ry Add pipe_wrap
ry authored
182
183
f01b241 @ry add wrapper for uv_spawn
ry authored
184 // TODO maybe share with TCPWrap?
185 void PipeWrap::OnConnection(uv_stream_t* handle, int status) {
186 HandleScope scope;
187
188 PipeWrap* wrap = static_cast<PipeWrap*>(handle->data);
189 assert(&wrap->handle_ == (uv_pipe_t*)handle);
190
191 // We should not be getting this callback if someone as already called
192 // uv_close() on the handle.
193 assert(wrap->object_.IsEmpty() == false);
194
195 if (status != 0) {
3883f22 @bnoordhuis pipe_wrap: don't assert() on pipe accept errors
bnoordhuis authored
196 SetErrno(uv_last_error(uv_default_loop()));
197 MakeCallback(wrap->object_, "onconnection", 0, NULL);
f01b241 @ry add wrapper for uv_spawn
ry authored
198 return;
cc0f608 @ry Add pipe_wrap
ry authored
199 }
200
f01b241 @ry add wrapper for uv_spawn
ry authored
201 // Instanciate the client javascript object and handle.
202 Local<Object> client_obj = pipeConstructor->NewInstance();
cc0f608 @ry Add pipe_wrap
ry authored
203
f01b241 @ry add wrapper for uv_spawn
ry authored
204 // Unwrap the client javascript object.
205 assert(client_obj->InternalFieldCount() > 0);
206 PipeWrap* client_wrap =
207 static_cast<PipeWrap*>(client_obj->GetPointerFromInternalField(0));
cc0f608 @ry Add pipe_wrap
ry authored
208
0685707 @bnoordhuis tcp, pipe: don't assert on uv_accept() errors
bnoordhuis authored
209 if (uv_accept(handle, (uv_stream_t*)&client_wrap->handle_)) return;
cc0f608 @ry Add pipe_wrap
ry authored
210
f01b241 @ry add wrapper for uv_spawn
ry authored
211 // Successful accept. Call the onconnection callback in JavaScript land.
212 Local<Value> argv[1] = { client_obj };
a26bee8 @isaacs MakeCallback: Consistent symbol usage
isaacs authored
213 if (onconnection_sym.IsEmpty()) {
214 onconnection_sym = NODE_PSYMBOL("onconnection");
215 }
216 MakeCallback(wrap->object_, onconnection_sym, ARRAY_SIZE(argv), argv);
f01b241 @ry add wrapper for uv_spawn
ry authored
217 }
cc0f608 @ry Add pipe_wrap
ry authored
218
f01b241 @ry add wrapper for uv_spawn
ry authored
219 // TODO Maybe share this with TCPWrap?
220 void PipeWrap::AfterConnect(uv_connect_t* req, int status) {
221 ConnectWrap* req_wrap = (ConnectWrap*) req->data;
222 PipeWrap* wrap = (PipeWrap*) req->handle->data;
cc0f608 @ry Add pipe_wrap
ry authored
223
f01b241 @ry add wrapper for uv_spawn
ry authored
224 HandleScope scope;
225
226 // The wrap and request objects should still be there.
227 assert(req_wrap->object_.IsEmpty() == false);
228 assert(wrap->object_.IsEmpty() == false);
229
c7771bc set readable/writable for pipes
Igor Zinkovsky authored
230 bool readable, writable;
231
f01b241 @ry add wrapper for uv_spawn
ry authored
232 if (status) {
6cc4292 @ry Display sys_errno when UV_UNKNOWN is returned
ry authored
233 SetErrno(uv_last_error(uv_default_loop()));
c7771bc set readable/writable for pipes
Igor Zinkovsky authored
234 readable = writable = 0;
235 } else {
236 readable = uv_is_readable(req->handle) != 0;
237 writable = uv_is_writable(req->handle) != 0;
cc0f608 @ry Add pipe_wrap
ry authored
238 }
239
c7771bc set readable/writable for pipes
Igor Zinkovsky authored
240 Local<Value> argv[5] = {
f01b241 @ry add wrapper for uv_spawn
ry authored
241 Integer::New(status),
242 Local<Value>::New(wrap->object_),
c7771bc set readable/writable for pipes
Igor Zinkovsky authored
243 Local<Value>::New(req_wrap->object_),
244 Local<Value>::New(Boolean::New(readable)),
245 Local<Value>::New(Boolean::New(writable))
f01b241 @ry add wrapper for uv_spawn
ry authored
246 };
cc0f608 @ry Add pipe_wrap
ry authored
247
a26bee8 @isaacs MakeCallback: Consistent symbol usage
isaacs authored
248 if (oncomplete_sym.IsEmpty()) {
249 oncomplete_sym = NODE_PSYMBOL("oncomplete");
250 }
251 MakeCallback(req_wrap->object_, oncomplete_sym, ARRAY_SIZE(argv), argv);
cc0f608 @ry Add pipe_wrap
ry authored
252
f01b241 @ry add wrapper for uv_spawn
ry authored
253 delete req_wrap;
254 }
cc0f608 @ry Add pipe_wrap
ry authored
255
256
caaa59c @ry Wrap uv_pipe_open, implement net.Stream(fd);
ry authored
257 Handle<Value> PipeWrap::Open(const Arguments& args) {
258 HandleScope scope;
259
45de259 @Sannis Make UNWRAP macro generic.
Sannis authored
260 UNWRAP(PipeWrap)
caaa59c @ry Wrap uv_pipe_open, implement net.Stream(fd);
ry authored
261
262 int fd = args[0]->IntegerValue();
263
264 uv_pipe_open(&wrap->handle_, fd);
265
266 return scope.Close(v8::Null());
267 }
268
269
f01b241 @ry add wrapper for uv_spawn
ry authored
270 Handle<Value> PipeWrap::Connect(const Arguments& args) {
271 HandleScope scope;
cc0f608 @ry Add pipe_wrap
ry authored
272
45de259 @Sannis Make UNWRAP macro generic.
Sannis authored
273 UNWRAP(PipeWrap)
cc0f608 @ry Add pipe_wrap
ry authored
274
249c3c1 Avoiding unnecessary ToString() calls
ssuda authored
275 String::AsciiValue name(args[0]);
f01b241 @ry add wrapper for uv_spawn
ry authored
276
277 ConnectWrap* req_wrap = new ConnectWrap();
cc0f608 @ry Add pipe_wrap
ry authored
278
6545a6d make updates to work with latest libuv api changes
Igor Zinkovsky authored
279 uv_pipe_connect(&req_wrap->req_,
280 &wrap->handle_,
281 *name,
282 AfterConnect);
f01b241 @ry add wrapper for uv_spawn
ry authored
283
284 req_wrap->Dispatched();
285
6545a6d make updates to work with latest libuv api changes
Igor Zinkovsky authored
286 return scope.Close(req_wrap->object_);
f01b241 @ry add wrapper for uv_spawn
ry authored
287 }
cc0f608 @ry Add pipe_wrap
ry authored
288
289
290 } // namespace node
291
cdcb111 @bnoordhuis Remove stray NODE_MODULE() semi-colons.
bnoordhuis authored
292 NODE_MODULE(node_pipe_wrap, node::PipeWrap::Initialize)
Something went wrong with that request. Please try again.