GCC Code Coverage Report
Directory: ../ Exec Total Coverage
File: /home/node-core-coverage/node-core-coverage/workdir/node/out/../src/pipe_wrap.cc Lines: 95 96 99.0 %
Date: 2016-09-05 Branches: 20 36 55.6 %

Line Branch Exec Source
1
#include "pipe_wrap.h"
2
3
#include "async-wrap.h"
4
#include "connection_wrap.h"
5
#include "env.h"
6
#include "env-inl.h"
7
#include "handle_wrap.h"
8
#include "node.h"
9
#include "node_buffer.h"
10
#include "node_wrap.h"
11
#include "connect_wrap.h"
12
#include "stream_wrap.h"
13
#include "util-inl.h"
14
#include "util.h"
15
16
namespace node {
17
18
using v8::Boolean;
19
using v8::Context;
20
using v8::EscapableHandleScope;
21
using v8::External;
22
using v8::Function;
23
using v8::FunctionCallbackInfo;
24
using v8::FunctionTemplate;
25
using v8::HandleScope;
26
using v8::Integer;
27
using v8::Local;
28
using v8::Object;
29
using v8::Value;
30
31
32
11
Local<Object> PipeWrap::Instantiate(Environment* env, AsyncWrap* parent) {
33
22
  EscapableHandleScope handle_scope(env->isolate());
34
22
  CHECK_EQ(false, env->pipe_constructor_template().IsEmpty());
35
11
  Local<Function> constructor = env->pipe_constructor_template()->GetFunction();
36
11
  CHECK_EQ(false, constructor.IsEmpty());
37
22
  Local<Value> ptr = External::New(env->isolate(), parent);
38
  Local<Object> instance =
39
22
      constructor->NewInstance(env->context(), 1, &ptr).ToLocalChecked();
40
22
  return handle_scope.Escape(instance);
41
}
42
43
44
1576
void PipeWrap::Initialize(Local<Object> target,
45
                          Local<Value> unused,
46
                          Local<Context> context) {
47
1576
  Environment* env = Environment::GetCurrent(context);
48
49
3152
  Local<FunctionTemplate> t = env->NewFunctionTemplate(New);
50
1576
  t->SetClassName(FIXED_ONE_BYTE_STRING(env->isolate(), "Pipe"));
51
3152
  t->InstanceTemplate()->SetInternalFieldCount(1);
52
53
1576
  env->SetProtoMethod(t, "close", HandleWrap::Close);
54
1576
  env->SetProtoMethod(t, "unref", HandleWrap::Unref);
55
1576
  env->SetProtoMethod(t, "ref", HandleWrap::Ref);
56
1576
  env->SetProtoMethod(t, "hasRef", HandleWrap::HasRef);
57
58
1576
  StreamWrap::AddMethods(env, t);
59
60
1576
  env->SetProtoMethod(t, "bind", Bind);
61
1576
  env->SetProtoMethod(t, "listen", Listen);
62
1576
  env->SetProtoMethod(t, "connect", Connect);
63
1576
  env->SetProtoMethod(t, "open", Open);
64
65
#ifdef _WIN32
66
  env->SetProtoMethod(t, "setPendingInstances", SetPendingInstances);
67
#endif
68
69
4728
  target->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "Pipe"), t->GetFunction());
70
1576
  env->set_pipe_constructor_template(t);
71
72
  // Create FunctionTemplate for PipeConnectWrap.
73
14
  auto constructor = [](const FunctionCallbackInfo<Value>& args) {
74
14
    CHECK(args.IsConstructCall());
75
28
  };
76
3152
  auto cwt = FunctionTemplate::New(env->isolate(), constructor);
77
3152
  cwt->InstanceTemplate()->SetInternalFieldCount(1);
78
1576
  cwt->SetClassName(FIXED_ONE_BYTE_STRING(env->isolate(), "PipeConnectWrap"));
79
6304
  target->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "PipeConnectWrap"),
80
1576
              cwt->GetFunction());
81
1576
}
82
83
84
1971
void PipeWrap::New(const FunctionCallbackInfo<Value>& args) {
85
  // This constructor should not be exposed to public javascript.
86
  // Therefore we assert that we are not trying to call this as a
87
  // normal function.
88
1971
  CHECK(args.IsConstructCall());
89
1971
  Environment* env = Environment::GetCurrent(args);
90
1971
  if (args[0]->IsExternal()) {
91
22
    void* ptr = args[0].As<External>()->Value();
92
11
    new PipeWrap(env, args.This(), false, static_cast<AsyncWrap*>(ptr));
93
  } else {
94
3920
    new PipeWrap(env, args.This(), args[0]->IsTrue(), nullptr);
95
  }
96
1971
}
97
98
99
1971
PipeWrap::PipeWrap(Environment* env,
100
                   Local<Object> object,
101
                   bool ipc,
102
                   AsyncWrap* parent)
103
    : ConnectionWrap(env,
104
                     object,
105
                     AsyncWrap::PROVIDER_PIPEWRAP,
106
1971
                     parent) {
107
3942
  int r = uv_pipe_init(env->event_loop(), &handle_, ipc);
108
1971
  CHECK_EQ(r, 0);  // How do we proxy this error up to javascript?
109
                   // Suggestion: uv_pipe_init() returns void.
110
1971
  UpdateWriteQueueSize();
111
1971
}
112
113
114
16
void PipeWrap::Bind(const FunctionCallbackInfo<Value>& args) {
115
  PipeWrap* wrap;
116
16
  ASSIGN_OR_RETURN_UNWRAP(&wrap, args.Holder());
117
48
  node::Utf8Value name(args.GetIsolate(), args[0]);
118
16
  int err = uv_pipe_bind(&wrap->handle_, *name);
119
32
  args.GetReturnValue().Set(err);
120
}
121
122
123
#ifdef _WIN32
124
void PipeWrap::SetPendingInstances(const FunctionCallbackInfo<Value>& args) {
125
  PipeWrap* wrap;
126
  ASSIGN_OR_RETURN_UNWRAP(&wrap, args.Holder());
127
  int instances = args[0]->Int32Value();
128
  uv_pipe_pending_instances(&wrap->handle_, instances);
129
}
130
#endif
131
132
133
15
void PipeWrap::Listen(const FunctionCallbackInfo<Value>& args) {
134
  PipeWrap* wrap;
135
15
  ASSIGN_OR_RETURN_UNWRAP(&wrap, args.Holder());
136
15
  int backlog = args[0]->Int32Value();
137
15
  int err = uv_listen(reinterpret_cast<uv_stream_t*>(&wrap->handle_),
138
                      backlog,
139
15
                      OnConnection);
140
30
  args.GetReturnValue().Set(err);
141
}
142
143
144
// TODO(bnoordhuis) Maybe share this with TCPWrap?
145
14
void PipeWrap::AfterConnect(uv_connect_t* req, int status) {
146
14
  ConnectWrap* req_wrap = static_cast<ConnectWrap*>(req->data);
147
14
  PipeWrap* wrap = static_cast<PipeWrap*>(req->handle->data);
148
14
  CHECK_EQ(req_wrap->env(), wrap->env());
149
14
  Environment* env = wrap->env();
150
151
28
  HandleScope handle_scope(env->isolate());
152
42
  Context::Scope context_scope(env->context());
153
154
  // The wrap and request objects should still be there.
155
28
  CHECK_EQ(req_wrap->persistent().IsEmpty(), false);
156
28
  CHECK_EQ(wrap->persistent().IsEmpty(), false);
157
158
  bool readable, writable;
159
160
14
  if (status) {
161
    readable = writable = 0;
162
  } else {
163
10
    readable = uv_is_readable(req->handle) != 0;
164
10
    writable = uv_is_writable(req->handle) != 0;
165
  }
166
167
28
  Local<Object> req_wrap_obj = req_wrap->object();
168
  Local<Value> argv[5] = {
169
    Integer::New(env->isolate(), status),
170
    wrap->object(),
171
    req_wrap_obj,
172
    Boolean::New(env->isolate(), readable),
173
    Boolean::New(env->isolate(), writable)
174
126
  };
175
176
28
  req_wrap->MakeCallback(env->oncomplete_string(), arraysize(argv), argv);
177
178
14
  delete req_wrap;
179
14
}
180
181
182
572
void PipeWrap::Open(const FunctionCallbackInfo<Value>& args) {
183
572
  Environment* env = Environment::GetCurrent(args);
184
185
  PipeWrap* wrap;
186
572
  ASSIGN_OR_RETURN_UNWRAP(&wrap, args.Holder());
187
188
572
  int fd = args[0]->Int32Value();
189
190
572
  int err = uv_pipe_open(&wrap->handle_, fd);
191
192
572
  if (err != 0)
193
    env->isolate()->ThrowException(UVException(err, "uv_pipe_open"));
194
}
195
196
197
14
void PipeWrap::Connect(const FunctionCallbackInfo<Value>& args) {
198
14
  Environment* env = Environment::GetCurrent(args);
199
200
  PipeWrap* wrap;
201
14
  ASSIGN_OR_RETURN_UNWRAP(&wrap, args.Holder());
202
203
14
  CHECK(args[0]->IsObject());
204
28
  CHECK(args[1]->IsString());
205
206
28
  Local<Object> req_wrap_obj = args[0].As<Object>();
207
28
  node::Utf8Value name(env->isolate(), args[1]);
208
209
  ConnectWrap* req_wrap =
210
14
      new ConnectWrap(env, req_wrap_obj, AsyncWrap::PROVIDER_PIPECONNECTWRAP);
211
14
  uv_pipe_connect(&req_wrap->req_,
212
                  &wrap->handle_,
213
14
                  *name,
214
14
                  AfterConnect);
215
28
  req_wrap->Dispatched();
216
217
28
  args.GetReturnValue().Set(0);  // uv_pipe_connect() doesn't return errors.
218
}
219
220
221
}  // namespace node
222
223
1632
NODE_MODULE_CONTEXT_AWARE_BUILTIN(pipe_wrap, node::PipeWrap::Initialize)