Bug Summary

File:out/../src/stream_wrap.cc
Warning:line 373, column 7
Value stored to 'written' is never read

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-unknown-linux-gnu -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name stream_wrap.cc -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=cplusplus -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model pic -pic-level 2 -pic-is-pie -mframe-pointer=all -fmath-errno -ffp-contract=on -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/home/maurizio/node-v18.6.0/out -resource-dir /usr/local/lib/clang/16.0.0 -D V8_DEPRECATION_WARNINGS -D V8_IMMINENT_DEPRECATION_WARNINGS -D _GLIBCXX_USE_CXX11_ABI=1 -D NODE_OPENSSL_CONF_NAME=nodejs_conf -D NODE_OPENSSL_HAS_QUIC -D __STDC_FORMAT_MACROS -D OPENSSL_NO_PINSHARED -D OPENSSL_THREADS -D NODE_ARCH="x64" -D NODE_PLATFORM="linux" -D NODE_WANT_INTERNALS=1 -D V8_DEPRECATION_WARNINGS=1 -D NODE_OPENSSL_SYSTEM_CERT_PATH="" -D NODE_USE_NODE_CODE_CACHE=1 -D HAVE_INSPECTOR=1 -D NODE_ENABLE_LARGE_CODE_PAGES=1 -D __POSIX__ -D NODE_USE_V8_PLATFORM=1 -D NODE_HAVE_I18N_SUPPORT=1 -D HAVE_OPENSSL=1 -D OPENSSL_API_COMPAT=0x10100000L -D UCONFIG_NO_SERVICE=1 -D U_ENABLE_DYLOAD=0 -D U_STATIC_IMPLEMENTATION=1 -D U_HAVE_STD_STRING=1 -D UCONFIG_NO_BREAK_ITERATION=0 -D _LARGEFILE_SOURCE -D _FILE_OFFSET_BITS=64 -D _POSIX_C_SOURCE=200112 -D NGHTTP2_STATICLIB -D NDEBUG -D OPENSSL_USE_NODELETE -D L_ENDIAN -D OPENSSL_BUILDING_OPENSSL -D AES_ASM -D BSAES_ASM -D CMLL_ASM -D ECP_NISTZ256_ASM -D GHASH_ASM -D KECCAK1600_ASM -D MD5_ASM -D OPENSSL_BN_ASM_GF2m -D OPENSSL_BN_ASM_MONT -D OPENSSL_BN_ASM_MONT5 -D OPENSSL_CPUID_OBJ -D OPENSSL_IA32_SSE2 -D PADLOCK_ASM -D POLY1305_ASM -D SHA1_ASM -D SHA256_ASM -D SHA512_ASM -D VPAES_ASM -D WHIRLPOOL_ASM -D X25519_ASM -D OPENSSL_PIC -D NGTCP2_STATICLIB -D NGHTTP3_STATICLIB -I ../src -I /home/maurizio/node-v18.6.0/out/Release/obj/gen -I /home/maurizio/node-v18.6.0/out/Release/obj/gen/include -I /home/maurizio/node-v18.6.0/out/Release/obj/gen/src -I ../deps/googletest/include -I ../deps/histogram/src -I ../deps/uvwasi/include -I ../deps/v8/include -I ../deps/icu-small/source/i18n -I ../deps/icu-small/source/common -I ../deps/zlib -I ../deps/llhttp/include -I ../deps/cares/include -I ../deps/uv/include -I ../deps/nghttp2/lib/includes -I ../deps/brotli/c/include -I ../deps/openssl/openssl/include -I ../deps/openssl/openssl/crypto/include -I ../deps/openssl/config/archs/linux-x86_64/asm/include -I ../deps/openssl/config/archs/linux-x86_64/asm -I ../deps/ngtcp2 -I ../deps/ngtcp2/ngtcp2/lib/includes -I ../deps/ngtcp2/ngtcp2/crypto/includes -I ../deps/ngtcp2/nghttp3/lib/includes -internal-isystem /usr/lib/gcc/x86_64-redhat-linux/8/../../../../include/c++/8 -internal-isystem /usr/lib/gcc/x86_64-redhat-linux/8/../../../../include/c++/8/x86_64-redhat-linux -internal-isystem /usr/lib/gcc/x86_64-redhat-linux/8/../../../../include/c++/8/backward -internal-isystem /usr/local/lib/clang/16.0.0/include -internal-isystem /usr/local/include -internal-isystem /usr/lib/gcc/x86_64-redhat-linux/8/../../../../x86_64-redhat-linux/include -internal-externc-isystem /include -internal-externc-isystem /usr/include -O3 -Wno-unused-parameter -Wno-unused-parameter -std=gnu++17 -fdeprecated-macro -fdebug-compilation-dir=/home/maurizio/node-v18.6.0/out -ferror-limit 19 -fno-rtti -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /tmp/scan-build-2022-08-22-142216-507842-1 -x c++ ../src/stream_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 "stream_wrap.h"
23#include "stream_base-inl.h"
24
25#include "env-inl.h"
26#include "handle_wrap.h"
27#include "node_buffer.h"
28#include "node_errors.h"
29#include "node_external_reference.h"
30#include "pipe_wrap.h"
31#include "req_wrap-inl.h"
32#include "tcp_wrap.h"
33#include "udp_wrap.h"
34#include "util-inl.h"
35
36#include <cstring> // memcpy()
37#include <climits> // INT_MAX
38
39
40namespace node {
41
42using errors::TryCatchScope;
43using v8::Context;
44using v8::DontDelete;
45using v8::EscapableHandleScope;
46using v8::FunctionCallbackInfo;
47using v8::FunctionTemplate;
48using v8::HandleScope;
49using v8::JustVoid;
50using v8::Local;
51using v8::Maybe;
52using v8::MaybeLocal;
53using v8::Nothing;
54using v8::Object;
55using v8::PropertyAttribute;
56using v8::ReadOnly;
57using v8::Signature;
58using v8::Value;
59
60void IsConstructCallCallback(const FunctionCallbackInfo<Value>& args) {
61 CHECK(args.IsConstructCall())do { if (__builtin_expect(!!(!(args.IsConstructCall())), 0)) {
do { static const node::AssertionInfo args = { "../src/stream_wrap.cc"
":" "61", "args.IsConstructCall()", __PRETTY_FUNCTION__ }; node
::Assert(args); } while (0); } } while (0)
;
62 StreamReq::ResetObject(args.This());
63}
64
65void LibuvStreamWrap::Initialize(Local<Object> target,
66 Local<Value> unused,
67 Local<Context> context,
68 void* priv) {
69 Environment* env = Environment::GetCurrent(context);
70
71 Local<FunctionTemplate> sw =
72 FunctionTemplate::New(env->isolate(), IsConstructCallCallback);
73 sw->InstanceTemplate()->SetInternalFieldCount(StreamReq::kInternalFieldCount);
74
75 // we need to set handle and callback to null,
76 // so that those fields are created and functions
77 // do not become megamorphic
78 // Fields:
79 // - oncomplete
80 // - callback
81 // - handle
82 sw->InstanceTemplate()->Set(
83 env->oncomplete_string(),
84 v8::Null(env->isolate()));
85 sw->InstanceTemplate()->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "callback"),
86 v8::Null(env->isolate()));
87 sw->InstanceTemplate()->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "handle"),
88 v8::Null(env->isolate()));
89
90 sw->Inherit(AsyncWrap::GetConstructorTemplate(env));
91
92 env->SetConstructorFunction(target, "ShutdownWrap", sw);
93 env->set_shutdown_wrap_template(sw->InstanceTemplate());
94
95 Local<FunctionTemplate> ww =
96 FunctionTemplate::New(env->isolate(), IsConstructCallCallback);
97 ww->InstanceTemplate()->SetInternalFieldCount(
98 StreamReq::kInternalFieldCount);
99 ww->Inherit(AsyncWrap::GetConstructorTemplate(env));
100 env->SetConstructorFunction(target, "WriteWrap", ww);
101 env->set_write_wrap_template(ww->InstanceTemplate());
102
103 NODE_DEFINE_CONSTANT(target, kReadBytesOrError)do { v8::Isolate* isolate = target->GetIsolate(); v8::Local
<v8::Context> context = isolate->GetCurrentContext()
; v8::Local<v8::String> constant_name = v8::String::NewFromUtf8
(isolate, "kReadBytesOrError", v8::NewStringType::kInternalized
).ToLocalChecked(); v8::Local<v8::Number> constant_value
= v8::Number::New(isolate, static_cast<double>(kReadBytesOrError
)); v8::PropertyAttribute constant_attributes = static_cast<
v8::PropertyAttribute>(v8::ReadOnly | v8::DontDelete); (target
)->DefineOwnProperty(context, constant_name, constant_value
, constant_attributes).Check(); } while (0)
;
104 NODE_DEFINE_CONSTANT(target, kArrayBufferOffset)do { v8::Isolate* isolate = target->GetIsolate(); v8::Local
<v8::Context> context = isolate->GetCurrentContext()
; v8::Local<v8::String> constant_name = v8::String::NewFromUtf8
(isolate, "kArrayBufferOffset", v8::NewStringType::kInternalized
).ToLocalChecked(); v8::Local<v8::Number> constant_value
= v8::Number::New(isolate, static_cast<double>(kArrayBufferOffset
)); v8::PropertyAttribute constant_attributes = static_cast<
v8::PropertyAttribute>(v8::ReadOnly | v8::DontDelete); (target
)->DefineOwnProperty(context, constant_name, constant_value
, constant_attributes).Check(); } while (0)
;
105 NODE_DEFINE_CONSTANT(target, kBytesWritten)do { v8::Isolate* isolate = target->GetIsolate(); v8::Local
<v8::Context> context = isolate->GetCurrentContext()
; v8::Local<v8::String> constant_name = v8::String::NewFromUtf8
(isolate, "kBytesWritten", v8::NewStringType::kInternalized).
ToLocalChecked(); v8::Local<v8::Number> constant_value =
v8::Number::New(isolate, static_cast<double>(kBytesWritten
)); v8::PropertyAttribute constant_attributes = static_cast<
v8::PropertyAttribute>(v8::ReadOnly | v8::DontDelete); (target
)->DefineOwnProperty(context, constant_name, constant_value
, constant_attributes).Check(); } while (0)
;
106 NODE_DEFINE_CONSTANT(target, kLastWriteWasAsync)do { v8::Isolate* isolate = target->GetIsolate(); v8::Local
<v8::Context> context = isolate->GetCurrentContext()
; v8::Local<v8::String> constant_name = v8::String::NewFromUtf8
(isolate, "kLastWriteWasAsync", v8::NewStringType::kInternalized
).ToLocalChecked(); v8::Local<v8::Number> constant_value
= v8::Number::New(isolate, static_cast<double>(kLastWriteWasAsync
)); v8::PropertyAttribute constant_attributes = static_cast<
v8::PropertyAttribute>(v8::ReadOnly | v8::DontDelete); (target
)->DefineOwnProperty(context, constant_name, constant_value
, constant_attributes).Check(); } while (0)
;
107 target->Set(context, FIXED_ONE_BYTE_STRING(env->isolate(), "streamBaseState"),
108 env->stream_base_state().GetJSArray()).Check();
109}
110
111void LibuvStreamWrap::RegisterExternalReferences(
112 ExternalReferenceRegistry* registry) {
113 registry->Register(IsConstructCallCallback);
114 registry->Register(GetWriteQueueSize);
115 registry->Register(SetBlocking);
116 StreamBase::RegisterExternalReferences(registry);
117}
118
119LibuvStreamWrap::LibuvStreamWrap(Environment* env,
120 Local<Object> object,
121 uv_stream_t* stream,
122 AsyncWrap::ProviderType provider)
123 : HandleWrap(env,
124 object,
125 reinterpret_cast<uv_handle_t*>(stream),
126 provider),
127 StreamBase(env),
128 stream_(stream) {
129 StreamBase::AttachToObject(object);
130}
131
132
133Local<FunctionTemplate> LibuvStreamWrap::GetConstructorTemplate(
134 Environment* env) {
135 Local<FunctionTemplate> tmpl = env->libuv_stream_wrap_ctor_template();
136 if (tmpl.IsEmpty()) {
137 tmpl = env->NewFunctionTemplate(nullptr);
138 tmpl->SetClassName(
139 FIXED_ONE_BYTE_STRING(env->isolate(), "LibuvStreamWrap"));
140 tmpl->Inherit(HandleWrap::GetConstructorTemplate(env));
141 tmpl->InstanceTemplate()->SetInternalFieldCount(
142 StreamBase::kInternalFieldCount);
143 Local<FunctionTemplate> get_write_queue_size =
144 FunctionTemplate::New(env->isolate(),
145 GetWriteQueueSize,
146 Local<Value>(),
147 Signature::New(env->isolate(), tmpl));
148 tmpl->PrototypeTemplate()->SetAccessorProperty(
149 env->write_queue_size_string(),
150 get_write_queue_size,
151 Local<FunctionTemplate>(),
152 static_cast<PropertyAttribute>(ReadOnly | DontDelete));
153 env->SetProtoMethod(tmpl, "setBlocking", SetBlocking);
154 StreamBase::AddMethods(env, tmpl);
155 env->set_libuv_stream_wrap_ctor_template(tmpl);
156 }
157 return tmpl;
158}
159
160
161LibuvStreamWrap* LibuvStreamWrap::From(Environment* env, Local<Object> object) {
162 Local<FunctionTemplate> sw = env->libuv_stream_wrap_ctor_template();
163 CHECK(!sw.IsEmpty() && sw->HasInstance(object))do { if (__builtin_expect(!!(!(!sw.IsEmpty() && sw->
HasInstance(object))), 0)) { do { static const node::AssertionInfo
args = { "../src/stream_wrap.cc" ":" "163", "!sw.IsEmpty() && sw->HasInstance(object)"
, __PRETTY_FUNCTION__ }; node::Assert(args); } while (0); } }
while (0)
;
164 return Unwrap<LibuvStreamWrap>(object);
165}
166
167
168int LibuvStreamWrap::GetFD() {
169#ifdef _WIN32
170 return fd_;
171#else
172 int fd = -1;
173 if (stream() != nullptr)
174 uv_fileno(reinterpret_cast<uv_handle_t*>(stream()), &fd);
175 return fd;
176#endif
177}
178
179
180bool LibuvStreamWrap::IsAlive() {
181 return HandleWrap::IsAlive(this);
182}
183
184
185bool LibuvStreamWrap::IsClosing() {
186 return uv_is_closing(reinterpret_cast<uv_handle_t*>(stream()));
187}
188
189
190AsyncWrap* LibuvStreamWrap::GetAsyncWrap() {
191 return static_cast<AsyncWrap*>(this);
192}
193
194
195bool LibuvStreamWrap::IsIPCPipe() {
196 return is_named_pipe_ipc();
197}
198
199int LibuvStreamWrap::ReadStart() {
200 return uv_read_start(
201 stream(),
202 [](uv_handle_t* handle, size_t suggested_size, uv_buf_t* buf) {
203 static_cast<LibuvStreamWrap*>(handle->data)
204 ->OnUvAlloc(suggested_size, buf);
205 },
206 [](uv_stream_t* stream, ssize_t nread, const uv_buf_t* buf) {
207 LibuvStreamWrap* wrap = static_cast<LibuvStreamWrap*>(stream->data);
208 TryCatchScope try_catch(wrap->env());
209 try_catch.SetVerbose(true);
210 wrap->OnUvRead(nread, buf);
211 });
212}
213
214
215int LibuvStreamWrap::ReadStop() {
216 return uv_read_stop(stream());
217}
218
219
220void LibuvStreamWrap::OnUvAlloc(size_t suggested_size, uv_buf_t* buf) {
221 HandleScope scope(env()->isolate());
222 Context::Scope context_scope(env()->context());
223
224 *buf = EmitAlloc(suggested_size);
225}
226
227template <class WrapType>
228static MaybeLocal<Object> AcceptHandle(Environment* env,
229 LibuvStreamWrap* parent) {
230 static_assert(std::is_base_of<LibuvStreamWrap, WrapType>::value ||
231 std::is_base_of<UDPWrap, WrapType>::value,
232 "Can only accept stream handles");
233
234 EscapableHandleScope scope(env->isolate());
235 Local<Object> wrap_obj;
236
237 if (!WrapType::Instantiate(env, parent, WrapType::SOCKET).ToLocal(&wrap_obj))
238 return Local<Object>();
239
240 HandleWrap* wrap = Unwrap<HandleWrap>(wrap_obj);
241 CHECK_NOT_NULL(wrap)do { if (__builtin_expect(!!(!((wrap) != nullptr)), 0)) { do {
static const node::AssertionInfo args = { "../src/stream_wrap.cc"
":" "241", "(wrap) != nullptr", __PRETTY_FUNCTION__ }; node::
Assert(args); } while (0); } } while (0)
;
242 uv_stream_t* stream = reinterpret_cast<uv_stream_t*>(wrap->GetHandle());
243 CHECK_NOT_NULL(stream)do { if (__builtin_expect(!!(!((stream) != nullptr)), 0)) { do
{ static const node::AssertionInfo args = { "../src/stream_wrap.cc"
":" "243", "(stream) != nullptr", __PRETTY_FUNCTION__ }; node
::Assert(args); } while (0); } } while (0)
;
244
245 if (uv_accept(parent->stream(), stream))
246 ABORT()node::Abort();
247
248 return scope.Escape(wrap_obj);
249}
250
251Maybe<void> LibuvStreamWrap::OnUvRead(ssize_t nread, const uv_buf_t* buf) {
252 HandleScope scope(env()->isolate());
253 Context::Scope context_scope(env()->context());
254 uv_handle_type type = UV_UNKNOWN_HANDLE;
255
256 if (is_named_pipe_ipc() &&
257 uv_pipe_pending_count(reinterpret_cast<uv_pipe_t*>(stream())) > 0) {
258 type = uv_pipe_pending_type(reinterpret_cast<uv_pipe_t*>(stream()));
259 }
260
261 // We should not be getting this callback if someone has already called
262 // uv_close() on the handle.
263 CHECK_EQ(persistent().IsEmpty(), false)do { if (__builtin_expect(!!(!((persistent().IsEmpty()) == (false
))), 0)) { do { static const node::AssertionInfo args = { "../src/stream_wrap.cc"
":" "263", "(persistent().IsEmpty()) == (false)", __PRETTY_FUNCTION__
}; node::Assert(args); } while (0); } } while (0)
;
264
265 if (nread > 0) {
266 MaybeLocal<Object> pending_obj;
267
268 if (type == UV_TCP) {
269 pending_obj = AcceptHandle<TCPWrap>(env(), this);
270 } else if (type == UV_NAMED_PIPE) {
271 pending_obj = AcceptHandle<PipeWrap>(env(), this);
272 } else if (type == UV_UDP) {
273 pending_obj = AcceptHandle<UDPWrap>(env(), this);
274 } else {
275 CHECK_EQ(type, UV_UNKNOWN_HANDLE)do { if (__builtin_expect(!!(!((type) == (UV_UNKNOWN_HANDLE))
), 0)) { do { static const node::AssertionInfo args = { "../src/stream_wrap.cc"
":" "275", "(type) == (UV_UNKNOWN_HANDLE)", __PRETTY_FUNCTION__
}; node::Assert(args); } while (0); } } while (0)
;
276 }
277
278 Local<Object> local_pending_obj;
279 if (type != UV_UNKNOWN_HANDLE &&
280 (!pending_obj.ToLocal(&local_pending_obj) ||
281 object()
282 ->Set(env()->context(),
283 env()->pending_handle_string(),
284 local_pending_obj)
285 .IsNothing())) {
286 return Nothing<void>();
287 }
288 }
289
290 EmitRead(nread, *buf);
291 return JustVoid();
292}
293
294void LibuvStreamWrap::GetWriteQueueSize(
295 const FunctionCallbackInfo<Value>& info) {
296 LibuvStreamWrap* wrap;
297 ASSIGN_OR_RETURN_UNWRAP(&wrap, info.This())do { *&wrap = static_cast<typename std::remove_reference
<decltype(*&wrap)>::type>( BaseObject::FromJSObject
(info.This())); if (*&wrap == nullptr) return ; } while (
0)
;
298
299 if (wrap->stream() == nullptr) {
300 info.GetReturnValue().Set(0);
301 return;
302 }
303
304 uint32_t write_queue_size = wrap->stream()->write_queue_size;
305 info.GetReturnValue().Set(write_queue_size);
306}
307
308
309void LibuvStreamWrap::SetBlocking(const FunctionCallbackInfo<Value>& args) {
310 LibuvStreamWrap* wrap;
311 ASSIGN_OR_RETURN_UNWRAP(&wrap, args.Holder())do { *&wrap = static_cast<typename std::remove_reference
<decltype(*&wrap)>::type>( BaseObject::FromJSObject
(args.Holder())); if (*&wrap == nullptr) return ; } while
(0)
;
312
313 CHECK_GT(args.Length(), 0)do { if (__builtin_expect(!!(!((args.Length()) > (0))), 0)
) { do { static const node::AssertionInfo args = { "../src/stream_wrap.cc"
":" "313", "(args.Length()) > (0)", __PRETTY_FUNCTION__ }
; node::Assert(args); } while (0); } } while (0)
;
314 if (!wrap->IsAlive())
315 return args.GetReturnValue().Set(UV_EINVAL);
316
317 bool enable = args[0]->IsTrue();
318 args.GetReturnValue().Set(uv_stream_set_blocking(wrap->stream(), enable));
319}
320
321typedef SimpleShutdownWrap<ReqWrap<uv_shutdown_t>> LibuvShutdownWrap;
322typedef SimpleWriteWrap<ReqWrap<uv_write_t>> LibuvWriteWrap;
323
324ShutdownWrap* LibuvStreamWrap::CreateShutdownWrap(Local<Object> object) {
325 return new LibuvShutdownWrap(this, object);
326}
327
328WriteWrap* LibuvStreamWrap::CreateWriteWrap(Local<Object> object) {
329 return new LibuvWriteWrap(this, object);
330}
331
332
333int LibuvStreamWrap::DoShutdown(ShutdownWrap* req_wrap_) {
334 LibuvShutdownWrap* req_wrap = static_cast<LibuvShutdownWrap*>(req_wrap_);
335 return req_wrap->Dispatch(uv_shutdown, stream(), AfterUvShutdown);
336}
337
338
339void LibuvStreamWrap::AfterUvShutdown(uv_shutdown_t* req, int status) {
340 LibuvShutdownWrap* req_wrap = static_cast<LibuvShutdownWrap*>(
341 LibuvShutdownWrap::from_req(req));
342 CHECK_NOT_NULL(req_wrap)do { if (__builtin_expect(!!(!((req_wrap) != nullptr)), 0)) {
do { static const node::AssertionInfo args = { "../src/stream_wrap.cc"
":" "342", "(req_wrap) != nullptr", __PRETTY_FUNCTION__ }; node
::Assert(args); } while (0); } } while (0)
;
343 HandleScope scope(req_wrap->env()->isolate());
344 Context::Scope context_scope(req_wrap->env()->context());
345 req_wrap->Done(status);
346}
347
348
349// NOTE: Call to this function could change both `buf`'s and `count`'s
350// values, shifting their base and decrementing their length. This is
351// required in order to skip the data that was successfully written via
352// uv_try_write().
353int LibuvStreamWrap::DoTryWrite(uv_buf_t** bufs, size_t* count) {
354 int err;
355 size_t written;
356 uv_buf_t* vbufs = *bufs;
357 size_t vcount = *count;
358
359 err = uv_try_write(stream(), vbufs, vcount);
360 if (err == UV_ENOSYS || err == UV_EAGAIN)
361 return 0;
362 if (err < 0)
363 return err;
364
365 // Slice off the buffers: skip all written buffers and slice the one that
366 // was partially written.
367 written = err;
368 for (; vcount > 0; vbufs++, vcount--) {
369 // Slice
370 if (vbufs[0].len > written) {
371 vbufs[0].base += written;
372 vbufs[0].len -= written;
373 written = 0;
Value stored to 'written' is never read
374 break;
375
376 // Discard
377 } else {
378 written -= vbufs[0].len;
379 }
380 }
381
382 *bufs = vbufs;
383 *count = vcount;
384
385 return 0;
386}
387
388
389int LibuvStreamWrap::DoWrite(WriteWrap* req_wrap,
390 uv_buf_t* bufs,
391 size_t count,
392 uv_stream_t* send_handle) {
393 LibuvWriteWrap* w = static_cast<LibuvWriteWrap*>(req_wrap);
394 return w->Dispatch(uv_write2,
395 stream(),
396 bufs,
397 count,
398 send_handle,
399 AfterUvWrite);
400}
401
402
403
404void LibuvStreamWrap::AfterUvWrite(uv_write_t* req, int status) {
405 LibuvWriteWrap* req_wrap = static_cast<LibuvWriteWrap*>(
406 LibuvWriteWrap::from_req(req));
407 CHECK_NOT_NULL(req_wrap)do { if (__builtin_expect(!!(!((req_wrap) != nullptr)), 0)) {
do { static const node::AssertionInfo args = { "../src/stream_wrap.cc"
":" "407", "(req_wrap) != nullptr", __PRETTY_FUNCTION__ }; node
::Assert(args); } while (0); } } while (0)
;
408 HandleScope scope(req_wrap->env()->isolate());
409 Context::Scope context_scope(req_wrap->env()->context());
410 req_wrap->Done(status);
411}
412
413} // namespace node
414
415NODE_MODULE_CONTEXT_AWARE_INTERNAL(stream_wrap,static node::node_module _module = { 108, NM_F_INTERNAL, nullptr
, "../src/stream_wrap.cc", nullptr, (node::addon_context_register_func
)(node::LibuvStreamWrap::Initialize), "stream_wrap", nullptr,
nullptr}; void _register_stream_wrap() { node_module_register
(&_module); }
416 node::LibuvStreamWrap::Initialize)static node::node_module _module = { 108, NM_F_INTERNAL, nullptr
, "../src/stream_wrap.cc", nullptr, (node::addon_context_register_func
)(node::LibuvStreamWrap::Initialize), "stream_wrap", nullptr,
nullptr}; void _register_stream_wrap() { node_module_register
(&_module); }
417NODE_MODULE_EXTERNAL_REFERENCE(void _register_external_reference_stream_wrap( node::ExternalReferenceRegistry
* registry) { node::LibuvStreamWrap::RegisterExternalReferences
(registry); }
418 stream_wrap, node::LibuvStreamWrap::RegisterExternalReferences)void _register_external_reference_stream_wrap( node::ExternalReferenceRegistry
* registry) { node::LibuvStreamWrap::RegisterExternalReferences
(registry); }