Skip to content

Commit

Permalink
src: store fd for libuv streams on Windows
Browse files Browse the repository at this point in the history
On Windows, we can't just look up a FD for libuv streams and
return it in `GetFD()`.
However, we do sometimes construct streams from their FDs;
in those cases, it should be okay to store the value on a class field.

PR-URL: #19377
Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl>
Reviewed-By: James M Snell <jasnell@gmail.com>
  • Loading branch information
addaleax committed May 14, 2018
1 parent c8fe8e8 commit 97d939a
Show file tree
Hide file tree
Showing 5 changed files with 25 additions and 2 deletions.
1 change: 1 addition & 0 deletions src/pipe_wrap.cc
Original file line number Diff line number Diff line change
Expand Up @@ -204,6 +204,7 @@ void PipeWrap::Open(const FunctionCallbackInfo<Value>& args) {
int fd = args[0]->Int32Value();

int err = uv_pipe_open(&wrap->handle_, fd);
wrap->set_fd(fd);

if (err != 0)
env->isolate()->ThrowException(UVException(err, "uv_pipe_open"));
Expand Down
6 changes: 4 additions & 2 deletions src/stream_wrap.cc
Original file line number Diff line number Diff line change
Expand Up @@ -115,12 +115,14 @@ void LibuvStreamWrap::AddMethods(Environment* env,


int LibuvStreamWrap::GetFD() {
#ifdef _WIN32
return fd_;
#else
int fd = -1;
#if !defined(_WIN32)
if (stream() != nullptr)
uv_fileno(reinterpret_cast<uv_handle_t*>(stream()), &fd);
#endif
return fd;
#endif
}


Expand Down
18 changes: 18 additions & 0 deletions src/stream_wrap.h
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,14 @@ class LibuvStreamWrap : public HandleWrap, public StreamBase {
v8::Local<v8::FunctionTemplate> target,
int flags = StreamBase::kFlagNone);

protected:
inline void set_fd(int fd) {
#ifdef _WIN32
fd_ = fd;
#endif
}


private:
static void GetWriteQueueSize(
const v8::FunctionCallbackInfo<v8::Value>& info);
Expand All @@ -101,6 +109,16 @@ class LibuvStreamWrap : public HandleWrap, public StreamBase {
static void AfterUvShutdown(uv_shutdown_t* req, int status);

uv_stream_t* const stream_;

#ifdef _WIN32
// We don't always have an FD that we could look up on the stream_
// object itself on Windows. However, for some cases, we open handles
// using FDs; In that case, we can store and provide the value.
// This became necessary because it allows to detect situations
// where multiple handles refer to the same stdio FDs (in particular,
// a possible IPC channel and a regular process.std??? stream).
int fd_ = -1;
#endif
};


Expand Down
1 change: 1 addition & 0 deletions src/tcp_wrap.cc
Original file line number Diff line number Diff line change
Expand Up @@ -212,6 +212,7 @@ void TCPWrap::Open(const FunctionCallbackInfo<Value>& args) {
args.GetReturnValue().Set(UV_EBADF));
int fd = static_cast<int>(args[0]->IntegerValue());
uv_tcp_open(&wrap->handle_, fd);
wrap->set_fd(fd);
}


Expand Down
1 change: 1 addition & 0 deletions src/tty_wrap.cc
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,7 @@ TTYWrap::TTYWrap(Environment* env,
reinterpret_cast<uv_stream_t*>(&handle_),
AsyncWrap::PROVIDER_TTYWRAP) {
*init_err = uv_tty_init(env->event_loop(), &handle_, fd, readable);
set_fd(fd);
if (*init_err != 0)
MarkAsUninitialized();
}
Expand Down

0 comments on commit 97d939a

Please sign in to comment.