diff --git a/td/telegram/cli.cpp b/td/telegram/cli.cpp index 4da07972..8eae1c19 100644 --- a/td/telegram/cli.cpp +++ b/td/telegram/cli.cpp @@ -30,6 +30,7 @@ #include "td/utils/port/FileFd.h" #include "td/utils/port/signals.h" #include "td/utils/port/Stat.h" +#include "td/utils/port/StdStreams.h" #include "td/utils/port/thread_local.h" #include "td/utils/ScopeGuard.h" #include "td/utils/Slice.h" @@ -183,6 +184,9 @@ class CliLog : public LogInterface { void append(CSlice slice, int log_level) override { #ifdef USE_READLINE deactivate_readline(); + SCOPE_EXIT { + reactivate_readline(); + }; #endif if (log_level == VERBOSITY_NAME(PLAIN)) { #if TD_WINDOWS @@ -193,9 +197,6 @@ class CliLog : public LogInterface { } else { default_log_interface->append(slice, log_level); } -#ifdef USE_READLINE - reactivate_readline(); -#endif } void rotate() override { } @@ -634,13 +635,14 @@ class CliClient final : public Actor { #if TD_WINDOWS stdin_reader_.reset(); #else + unsubscribe(stdin_.get_poll_info().get_pollable_fd_ref()); is_stdin_reader_stopped_ = true; #endif yield(); } #ifdef USE_READLINE - Fd stdin_; + FileFd stdin_; #else using StreamConnection = BufferedFd; StreamConnection stdin_; @@ -787,19 +789,18 @@ class CliClient final : public Actor { }; stdin_reader_ = create_actor_on_scheduler("stdin_reader", stdin_id, actor_shared(this, 1)); #else - Fd::Stdin().set_is_blocking(false).ensure(); + detail::set_native_socket_is_blocking(Stdin().get_native_fd(), false).ensure(); #ifdef USE_READLINE deactivate_readline(); rl_callback_handler_install(prompt, cb_linehandler); rl_attempted_completion_function = tg_cli_completion; reactivate_readline(); - stdin_ = Fd::Stdin().clone(); + stdin_ = std::move(Stdin()); #else - stdin_ = StreamConnection(Fd::Stdin().clone()); + stdin_ = StreamConnection(std::move(Stdin())); #endif - stdin_.get_fd().set_observer(this); - subscribe(stdin_, Fd::Read); + subscribe(stdin_.get_poll_info().extract_pollable_fd(this), PollFlags::Read()); #endif if (get_chat_list_) { @@ -3405,7 +3406,7 @@ class CliClient final : public Actor { #ifdef USE_READLINE if (can_read(stdin_)) { rl_callback_read_char(); - stdin_.get_fd().clear_flags(Fd::Read); + stdin_.get_poll_info().clear_flags(PollFlags::Read()); } #else auto r = stdin_.flush_read(); diff --git a/tdutils/CMakeLists.txt b/tdutils/CMakeLists.txt index 1318320c..5e11dbb4 100644 --- a/tdutils/CMakeLists.txt +++ b/tdutils/CMakeLists.txt @@ -42,6 +42,7 @@ set(TDUTILS_SOURCE td/utils/port/sleep.cpp td/utils/port/SocketFd.cpp td/utils/port/Stat.cpp + td/utils/port/StdStreams.cpp td/utils/port/thread_local.cpp td/utils/port/wstring_convert.cpp @@ -104,6 +105,7 @@ set(TDUTILS_SOURCE td/utils/port/sleep.h td/utils/port/SocketFd.h td/utils/port/Stat.h + td/utils/port/StdStreams.h td/utils/port/thread.h td/utils/port/thread_local.h td/utils/port/UdpSocketFd.h diff --git a/tdutils/td/utils/logging.cpp b/tdutils/td/utils/logging.cpp index 1ee6664e..a8cef318 100644 --- a/tdutils/td/utils/logging.cpp +++ b/tdutils/td/utils/logging.cpp @@ -7,7 +7,7 @@ #include "td/utils/logging.h" #include "td/utils/port/Clocks.h" -#include "td/utils/port/FileFd.h" +#include "td/utils/port/StdStreams.h" #include "td/utils/port/thread_local.h" #include "td/utils/Slice.h" #include "td/utils/Time.h" @@ -119,18 +119,6 @@ TsCerr::TsCerr() { TsCerr::~TsCerr() { exitCritical(); } -namespace { -FileFd &Stderr() { - static FileFd res = FileFd::from_native_fd(NativeFd( -#if TD_PORT_POSIX - 2 -#elif TD_PORT_WINDOWS - GetStdHandle(STD_ERROR_HANDLE) -#endif - , true)).move_as_ok(); - return res; -} -} // namespace TsCerr &TsCerr::operator<<(Slice slice) { auto &fd = Stderr(); if (fd.empty()) { diff --git a/tdutils/td/utils/port/StdStreams.cpp b/tdutils/td/utils/port/StdStreams.cpp new file mode 100644 index 00000000..2160364b --- /dev/null +++ b/tdutils/td/utils/port/StdStreams.cpp @@ -0,0 +1,47 @@ +// +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2018 +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +#include "td/utils/port/StdStreams.h" + +namespace td { + +namespace { +template +FileFd create(T handle) { + return FileFd::from_native_fd(NativeFd(handle, true)).move_as_ok(); +} +} // namespace +FileFd &Stdin() { + static FileFd res = create( +#if TD_PORT_POSIX + 0 +#elif TD_PORT_WINDOWS + GetStdHandle(STD_INPUT_HANDLE) +#endif + ); + return res; +} +FileFd &Stdout() { + static FileFd res = create( +#if TD_PORT_POSIX + 1 +#elif TD_PORT_WINDOWS + GetStdHandle(STD_OUTPUT_HANDLE) +#endif + ); + return res; +} +FileFd &Stderr() { + static FileFd res = create( +#if TD_PORT_POSIX + 2 +#elif TD_PORT_WINDOWS + GetStdHandle(STD_ERROR_HANDLE) +#endif + ); + return res; +} +} // namespace td diff --git a/tdutils/td/utils/port/StdStreams.h b/tdutils/td/utils/port/StdStreams.h new file mode 100644 index 00000000..36e21394 --- /dev/null +++ b/tdutils/td/utils/port/StdStreams.h @@ -0,0 +1,16 @@ +// +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2018 +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +#pragma once +#include "td/utils/port/FileFd.h" + +namespace td { + +FileFd &Stdin(); +FileFd &Stdout(); +FileFd &Stderr(); + +} // namespace td