diff --git a/CMake/GeneratePkgConfig.cmake b/CMake/GeneratePkgConfig.cmake new file mode 100644 index 000000000..bbba7a27f --- /dev/null +++ b/CMake/GeneratePkgConfig.cmake @@ -0,0 +1,80 @@ +function(get_relative_link OUTPUT PATH) + if (PATH MATCHES "^[$]<[$]:") + set(${OUTPUT} "" PARENT_SCOPE) + return() + endif() + string(REGEX REPLACE "^[$]<[$]>:(.*)>$" "\\1" PATH "${PATH}") + + get_filename_component(NAME "${PATH}" NAME_WE) + if (IS_ABSOLUTE ${PATH}) + get_filename_component(DIRECTORY_NAME "${PATH}" DIRECTORY) + if (WIN32) + set(${OUTPUT} "-l\"${DIRECTORY_NAME}/${NAME}\"" PARENT_SCOPE) + else() + get_filename_component(FULL_NAME "${PATH}" NAME) + set(${OUTPUT} "-L\"${DIRECTORY_NAME}\" -l:${FULL_NAME}" PARENT_SCOPE) + endif() + return() + endif() + + if (NOT WIN32 AND NAME MATCHES "^lib") + string(REGEX REPLACE "^lib" "-l" LINK "${NAME}") + elseif (NAME MATCHES "^-") + set(LINK "${NAME}") + else() + string(CONCAT LINK "-l" "${NAME}") + endif() + set(${OUTPUT} "${LINK}" PARENT_SCOPE) +endfunction() + +function(generate_pkgconfig TARGET DESCRIPTION) + # message("Generating pkg-config for ${TARGET}") + get_filename_component(PREFIX "${CMAKE_INSTALL_PREFIX}" REALPATH) + + get_target_property(LIST "${TARGET}" LINK_LIBRARIES) + set(REQS "") + set(LIBS "") + foreach (LIB ${LIST}) + if (TARGET "${LIB}") + set(HAS_REQS 1) + list(APPEND REQS "${LIB}") + else() + set(HAS_LIBS 1) + get_relative_link(LINK "${LIB}") + if (NOT LINK EQUAL "") + list(APPEND LIBS "${LINK}") + endif() + endif() + endforeach() + + if (HAS_REQS) + set(REQUIRES "") + foreach (REQ ${REQS}) + set(REQUIRES "${REQUIRES} ${REQ}") + endforeach() + set(REQUIRES "Requires.private:${REQUIRES}\n") + endif() + if (HAS_LIBS) + set(LIBRARIES "") + list(REVERSE LIBS) + list(REMOVE_DUPLICATES LIBS) + foreach (LIB ${LIBS}) + set(LIBRARIES " ${LIB}${LIBRARIES}") + endforeach() + set(LIBRARIES "Libs.private:${LIBRARIES}\n") + endif() + + file(MAKE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/pkgconfig") + file(GENERATE OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/pkgconfig/${TARGET}.pc" CONTENT +"prefix=${PREFIX} + +Name: ${TARGET} +Description: ${DESCRIPTION} +Version: ${PROJECT_VERSION} + +CFlags: -I\"\${prefix}/${CMAKE_INSTALL_INCLUDEDIR}\" +Libs: -L\"\${prefix}/${CMAKE_INSTALL_LIBDIR}\" -l${TARGET} +${REQUIRES}${LIBRARIES}") + + install(FILES "${CMAKE_CURRENT_BINARY_DIR}/pkgconfig/${TARGET}.pc" DESTINATION "${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}/pkgconfig") +endfunction() diff --git a/CMakeLists.txt b/CMakeLists.txt index d730861cd..f3ecec8c9 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -988,6 +988,28 @@ install(TARGETS tdjson TdJson tdjson_static TdJsonStatic tdjson_private tdclient INCLUDES DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}" ) +# generate pkg-config files +include(GeneratePkgConfig) + +generate_pkgconfig(tdutils "Telegram Library - Utils") +generate_pkgconfig(tdactor "Telegram Library - Actor") +generate_pkgconfig(tdnet "Telegram Library - Net") +generate_pkgconfig(tdsqlite "Telegram Library - SQLite") +generate_pkgconfig(tddb "Telegram Library - Database") +if (MEMPROF) + # generate_pkgconfig(memprof "memprof - simple library for memory usage profiling") +endif() +generate_pkgconfig(tdcore "Telegram Library - Core") +generate_pkgconfig(tdclient "Telegram Library - C++ Interface") +if (TD_ENABLE_DOTNET) + # generate_pkgconfig(tddotnet "Telegram Library - C# Interface") +endif() +# generate_pkgconfig(tdc "Telegram Library - C interface") +generate_pkgconfig(tdapi "Telegram Library - API") +generate_pkgconfig(tdjson_private "Telegram Library - JSON interface (private)") +generate_pkgconfig(tdjson "Telegram Library - JSON interface (shared)") +generate_pkgconfig(tdjson_static "Telegram Library - JSON interface (static)") + install(EXPORT TdTargets FILE TdTargets.cmake NAMESPACE Td:: diff --git a/example/cpp/td_example.cpp b/example/cpp/td_example.cpp index 962be64c2..1b8d7859f 100644 --- a/example/cpp/td_example.cpp +++ b/example/cpp/td_example.cpp @@ -257,7 +257,7 @@ class TdExample { [this](td_api::authorizationStateWaitPassword &) { std::cout << "Enter authentication password: " << std::flush; std::string password; - std::cin >> password; + std::getline(std::cin, line); send_query(td_api::make_object(password), create_authentication_query_handler()); }, diff --git a/example/java/org/drinkless/tdlib/Client.java b/example/java/org/drinkless/tdlib/Client.java index d95196f17..e8bed6787 100644 --- a/example/java/org/drinkless/tdlib/Client.java +++ b/example/java/org/drinkless/tdlib/Client.java @@ -149,6 +149,7 @@ public final class Client { if (isClosed) { updateHandlers.remove(clientId); // there will be no more updates defaultExceptionHandlers.remove(clientId); // ignore further exceptions + clientCount.decrementAndGet(); } } @@ -164,6 +165,7 @@ public final class Client { private static final ConcurrentHashMap updateHandlers = new ConcurrentHashMap(); private static final ConcurrentHashMap handlers = new ConcurrentHashMap(); private static final AtomicLong currentQueryId = new AtomicLong(); + private static final AtomicLong clientCount = new AtomicLong(); private static final ResponseReceiver responseReceiver = new ResponseReceiver(); @@ -178,6 +180,7 @@ public final class Client { } private Client(ResultHandler updateHandler, ExceptionHandler updateExceptionHandler, ExceptionHandler defaultExceptionHandler) { + clientCount.incrementAndGet(); nativeClientId = createNativeClient(); if (updateHandler != null) { updateHandlers.put(nativeClientId, new Handler(updateHandler, updateExceptionHandler)); diff --git a/td/telegram/ContactsManager.cpp b/td/telegram/ContactsManager.cpp index 2c8cb5714..cdba858ec 100644 --- a/td/telegram/ContactsManager.cpp +++ b/td/telegram/ContactsManager.cpp @@ -2905,6 +2905,7 @@ ContactsManager::ContactsManager(Td *td, ActorShared<> parent) : td_(td), parent G()->shared_config().set_option_integer("telegram_service_notifications_chat_id", DialogId(get_service_notifications_user_id()).get()); G()->shared_config().set_option_integer("replies_bot_chat_id", DialogId(get_replies_bot_user_id()).get()); + G()->shared_config().set_option_integer("group_anonymous_bot_user_id", get_anonymous_bot_user_id().get()); if (G()->parameters().use_chat_info_db) { auto next_contacts_sync_date_string = G()->td_db()->get_binlog_pmc()->get("next_contacts_sync_date"); diff --git a/td/telegram/MessagesManager.cpp b/td/telegram/MessagesManager.cpp index 9e4bdbd1d..bbbdd9960 100644 --- a/td/telegram/MessagesManager.cpp +++ b/td/telegram/MessagesManager.cpp @@ -12521,8 +12521,8 @@ MessagesManager::MessageInfo MessagesManager::parse_telegram_api_message( } message_info.date = message->date_; message_info.flags = message->flags_; - auto reply_to_message_id = MessageId( - ServerMessageId(message_info.reply_header == nullptr ? 0 : message_info.reply_header->reply_to_msg_id_)); + auto reply_to_message_id = + MessageId(ServerMessageId(message->reply_to_ == nullptr ? 0 : message->reply_to_->reply_to_msg_id_)); message_info.content = get_action_message_content(td_, std::move(message->action_), message_info.dialog_id, reply_to_message_id); break; @@ -12565,9 +12565,9 @@ std::pair> MessagesManager::creat } if (!is_broadcast_channel(dialog_id) && td_->auth_manager_->is_bot()) { if (dialog_id == sender_dialog_id) { - sender_user_id = td_->contacts_manager_->add_anonymous_bot_user(); + td_->contacts_manager_->add_anonymous_bot_user(); } else { - sender_user_id = td_->contacts_manager_->add_service_notifications_user(); + td_->contacts_manager_->add_service_notifications_user(); } } } @@ -19590,7 +19590,6 @@ void MessagesManager::do_read_history_on_server(DialogId dialog_id) { Dialog *d = get_dialog(dialog_id); CHECK(d != nullptr); - CHECK(!d->updated_read_history_message_ids.empty()); for (auto top_thread_message_id : d->updated_read_history_message_ids) { if (!top_thread_message_id.is_valid()) { diff --git a/td/telegram/RequestActor.h b/td/telegram/RequestActor.h index cec5f8240..0f0fdaf8e 100644 --- a/td/telegram/RequestActor.h +++ b/td/telegram/RequestActor.h @@ -51,7 +51,7 @@ class RequestActor : public Actor { CHECK(future.get_state() == FutureActor::State::Waiting); if (--tries_left_ == 0) { future.close(); - do_send_error(Status::Error(400, "Requested data is inaccessible")); + do_send_error(Status::Error(500, "Requested data is inaccessible")); return stop(); } diff --git a/td/telegram/net/NetQueryStats.h b/td/telegram/net/NetQueryStats.h index c8a7ff469..144d407cb 100644 --- a/td/telegram/net/NetQueryStats.h +++ b/td/telegram/net/NetQueryStats.h @@ -41,7 +41,7 @@ class NetQueryStats { void dump_pending_network_queries(); private: - NetQueryCounter::Counter count_; + NetQueryCounter::Counter count_{0}; std::atomic use_list_{true}; TsList list_; }; diff --git a/td/tl/TlObject.h b/td/tl/TlObject.h index 9cf698ebc..85b540f1b 100644 --- a/td/tl/TlObject.h +++ b/td/tl/TlObject.h @@ -115,10 +115,10 @@ class unique_ptr { } explicit unique_ptr(T *ptr) noexcept : ptr_(ptr) { } - template ::value>> + template ::value>::type> unique_ptr(unique_ptr &&other) noexcept : ptr_(static_cast(other.release())) { } - template ::value>> + template ::value>::type> unique_ptr &operator=(unique_ptr &&other) noexcept { reset(static_cast(other.release())); return *this; diff --git a/tdnet/CMakeLists.txt b/tdnet/CMakeLists.txt index 306da0c67..fb0319855 100644 --- a/tdnet/CMakeLists.txt +++ b/tdnet/CMakeLists.txt @@ -52,11 +52,11 @@ set(TDNET_SOURCE add_library(tdnet STATIC ${TDNET_SOURCE}) target_include_directories(tdnet PUBLIC $) target_include_directories(tdnet SYSTEM PRIVATE $) -target_link_libraries(tdnet PUBLIC tdutils tdactor PRIVATE ${CMAKE_DL_LIBS} ${ZLIB_LIBRARIES}) +target_link_libraries(tdnet PUBLIC tdutils tdactor) if (NOT EMSCRIPTEN) target_link_libraries(tdnet PRIVATE ${OPENSSL_SSL_LIBRARY}) endif() -target_link_libraries(tdnet PRIVATE ${OPENSSL_CRYPTO_LIBRARY}) +target_link_libraries(tdnet PRIVATE ${OPENSSL_CRYPTO_LIBRARY} ${CMAKE_DL_LIBS} ${ZLIB_LIBRARIES}) if (WIN32) if (MINGW) diff --git a/tdtl/td/tl/tl_generate.cpp b/tdtl/td/tl/tl_generate.cpp index 71ef03c89..9e3647431 100644 --- a/tdtl/td/tl/tl_generate.cpp +++ b/tdtl/td/tl/tl_generate.cpp @@ -483,7 +483,6 @@ void write_tl(const tl_config &config, tl_outputer &out, const TL_writer &w) { std::size_t types_n = config.get_type_count(); std::size_t functions_n = config.get_function_count(); - bool found_complex = false; for (std::size_t type = 0; type < types_n; type++) { tl_type *t = config.get_type_by_num(type); assert(t->constructors_num == t->constructors.size()); @@ -491,7 +490,6 @@ void write_tl(const tl_config &config, tl_outputer &out, const TL_writer &w) { if (t->name == "Type") { assert(t->id == ID_VAR_TYPE); t->flags |= FLAG_COMPLEX; - found_complex = true; } continue; } @@ -529,7 +527,6 @@ void write_tl(const tl_config &config, tl_outputer &out, const TL_writer &w) { b.exist_var_num != -1) { if (!w.is_built_in_complex_type(t->name)) { t->flags |= FLAG_COMPLEX; - found_complex = true; } } else { assert(b_arg_type == NODE_TYPE_TYPE); @@ -549,14 +546,13 @@ void write_tl(const tl_config &config, tl_outputer &out, const TL_writer &w) { if (main_type == NODE_TYPE_VAR_TYPE) { if (!w.is_built_in_complex_type(t->name)) { t->flags |= FLAG_COMPLEX; - found_complex = true; } } } } - while (found_complex) { - found_complex = false; + while (true) { + bool found_complex = false; for (std::size_t type = 0; type < types_n; type++) { tl_type *t = config.get_type_by_num(type); if (t->constructors_num == 0 || w.is_built_in_complex_type(t->name)) { // built-in dummy or complex types @@ -576,6 +572,9 @@ void write_tl(const tl_config &config, tl_outputer &out, const TL_writer &w) { // std::fprintf(stderr, "Found complex %s\n", t->name.c_str()); } } + if (!found_complex) { + break; + } } std::set request_types; diff --git a/tdutils/td/utils/port/SocketFd.cpp b/tdutils/td/utils/port/SocketFd.cpp index 3b0bcba08..feab6676d 100644 --- a/tdutils/td/utils/port/SocketFd.cpp +++ b/tdutils/td/utils/port/SocketFd.cpp @@ -384,17 +384,37 @@ class SocketFdImpl { const NativeFd &get_native_fd() const { return info.native_fd(); } + Result writev(Span slices) { int native_fd = get_native_fd().socket(); - auto write_res = - detail::skip_eintr([&] { return ::writev(native_fd, slices.begin(), narrow_cast(slices.size())); }); + TRY_RESULT(slices_size, narrow_cast_safe(slices.size())); + auto write_res = detail::skip_eintr([&] { +#ifdef MSG_NOSIGNAL + msghdr msg; + memset(&msg, 0, sizeof(msg)); + msg.msg_iov = const_cast(slices.begin()); + msg.msg_iovlen = slices_size; + return sendmsg(native_fd, &msg, MSG_NOSIGNAL); +#else + return ::writev(native_fd, slices.begin(), slices_size); +#endif + }); return write_finish(write_res); } + Result write(Slice slice) { int native_fd = get_native_fd().socket(); - auto write_res = detail::skip_eintr([&] { return ::write(native_fd, slice.begin(), slice.size()); }); + auto write_res = detail::skip_eintr([&] { + return +#ifdef MSG_NOSIGNAL + send(native_fd, slice.begin(), slice.size(), MSG_NOSIGNAL); +#else + ::write(native_fd, slice.begin(), slice.size()); +#endif + }); return write_finish(write_res); } + Result write_finish(ssize_t write_res) { auto write_errno = errno; if (write_res >= 0) { @@ -538,6 +558,17 @@ Status init_socket_options(NativeFd &native_fd) { setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, reinterpret_cast(&flags), sizeof(flags)); setsockopt(sock, SOL_SOCKET, SO_KEEPALIVE, reinterpret_cast(&flags), sizeof(flags)); setsockopt(sock, IPPROTO_TCP, TCP_NODELAY, reinterpret_cast(&flags), sizeof(flags)); +#if TD_PORT_POSIX +#ifndef MSG_NOSIGNAL // Darwin + +#ifdef SO_NOSIGPIPE + setsockopt(sock, SOL_SOCKET, SO_NOSIGPIPE, reinterpret_cast(&flags), sizeof(flags)); +#else +#warning "Failed to suppress SIGPIPE signals. Use signal(SIGPIPE, SIG_IGN) to suppress them." +#endif + +#endif +#endif // TODO: SO_REUSEADDR, SO_KEEPALIVE, TCP_NODELAY, SO_SNDBUF, SO_RCVBUF, TCP_QUICKACK, SO_LINGER return Status::OK(); diff --git a/tdutils/td/utils/port/UdpSocketFd.cpp b/tdutils/td/utils/port/UdpSocketFd.cpp index 8ba885be0..aa146b6a4 100644 --- a/tdutils/td/utils/port/UdpSocketFd.cpp +++ b/tdutils/td/utils/port/UdpSocketFd.cpp @@ -47,7 +47,7 @@ class UdpSocketReceiveHelper { public: void to_native(const UdpMessage &message, WSAMSG &message_header) { socklen_t addr_len{narrow_cast(sizeof(addr_))}; - message_header.name = reinterpret_cast(&addr_); + message_header.name = reinterpret_cast(&addr_); message_header.namelen = addr_len; buf_.buf = const_cast(message.data.as_slice().begin()); buf_.len = narrow_cast(message.data.size()); @@ -59,8 +59,7 @@ class UdpSocketReceiveHelper { } void from_native(WSAMSG &message_header, size_t message_size, UdpMessage &message) { - message.address.init_sockaddr(reinterpret_cast(message_header.name), message_header.namelen) - .ignore(); + message.address.init_sockaddr(reinterpret_cast(message_header.name), message_header.namelen).ignore(); message.error = Status::OK(); if ((message_header.dwFlags & (MSG_TRUNC | MSG_CTRUNC)) != 0) { @@ -82,7 +81,7 @@ class UdpSocketReceiveHelper { class UdpSocketSendHelper { public: void to_native(const UdpMessage &message, WSAMSG &message_header) { - message_header.name = const_cast(message.address.get_sockaddr()); + message_header.name = const_cast(message.address.get_sockaddr()); message_header.namelen = narrow_cast(message.address.get_sockaddr_len()); buf_.buf = const_cast(message.data.as_slice().begin()); buf_.len = narrow_cast(message.data.size()); @@ -373,7 +372,7 @@ void UdpSocketFdImplDeleter::operator()(UdpSocketFdImpl *impl) { class UdpSocketReceiveHelper { public: - void to_native(const UdpSocketFd::InboundMessage &message, struct msghdr &message_header) { + void to_native(const UdpSocketFd::InboundMessage &message, msghdr &message_header) { socklen_t addr_len{narrow_cast(sizeof(addr_))}; message_header.msg_name = &addr_; @@ -387,22 +386,22 @@ class UdpSocketReceiveHelper { message_header.msg_flags = 0; } - void from_native(struct msghdr &message_header, size_t message_size, UdpSocketFd::InboundMessage &message) { + void from_native(msghdr &message_header, size_t message_size, UdpSocketFd::InboundMessage &message) { #if TD_LINUX - struct cmsghdr *cmsg; - struct sock_extended_err *ee = nullptr; + cmsghdr *cmsg; + sock_extended_err *ee = nullptr; for (cmsg = CMSG_FIRSTHDR(&message_header); cmsg != nullptr; cmsg = CMSG_NXTHDR(&message_header, cmsg)) { if (cmsg->cmsg_type == IP_PKTINFO && cmsg->cmsg_level == IPPROTO_IP) { - //auto *pi = reinterpret_cast(CMSG_DATA(cmsg)); + //auto *pi = reinterpret_cast(CMSG_DATA(cmsg)); } else if (cmsg->cmsg_type == IPV6_PKTINFO && cmsg->cmsg_level == IPPROTO_IPV6) { - //auto *pi = reinterpret_cast(CMSG_DATA(cmsg)); + //auto *pi = reinterpret_cast(CMSG_DATA(cmsg)); } else if ((cmsg->cmsg_type == IP_RECVERR && cmsg->cmsg_level == IPPROTO_IP) || (cmsg->cmsg_type == IPV6_RECVERR && cmsg->cmsg_level == IPPROTO_IPV6)) { - ee = reinterpret_cast(CMSG_DATA(cmsg)); + ee = reinterpret_cast(CMSG_DATA(cmsg)); } } if (ee != nullptr) { - auto *addr = reinterpret_cast(SO_EE_OFFENDER(ee)); + auto *addr = reinterpret_cast(SO_EE_OFFENDER(ee)); IPAddress address; address.init_sockaddr(addr).ignore(); if (message.from != nullptr) { @@ -417,8 +416,7 @@ class UdpSocketReceiveHelper { } #endif if (message.from != nullptr) { - message.from - ->init_sockaddr(reinterpret_cast(message_header.msg_name), message_header.msg_namelen) + message.from->init_sockaddr(reinterpret_cast(message_header.msg_name), message_header.msg_namelen) .ignore(); } if (message.error) { @@ -439,14 +437,14 @@ class UdpSocketReceiveHelper { private: std::array control_buf_; sockaddr_storage addr_; - struct iovec io_vec_; + iovec io_vec_; }; class UdpSocketSendHelper { public: - void to_native(const UdpSocketFd::OutboundMessage &message, struct msghdr &message_header) { + void to_native(const UdpSocketFd::OutboundMessage &message, msghdr &message_header) { CHECK(message.to != nullptr && message.to->is_valid()); - message_header.msg_name = const_cast(message.to->get_sockaddr()); + message_header.msg_name = const_cast(message.to->get_sockaddr()); message_header.msg_namelen = narrow_cast(message.to->get_sockaddr_len()); io_vec_.iov_base = const_cast(message.data.begin()); io_vec_.iov_len = message.data.size(); @@ -459,7 +457,7 @@ class UdpSocketSendHelper { } private: - struct iovec io_vec_; + iovec io_vec_; }; class UdpSocketFdImpl { @@ -495,7 +493,7 @@ class UdpSocketFdImpl { #endif } - struct msghdr message_header; + msghdr message_header; detail::UdpSocketReceiveHelper helper; helper.to_native(message, message_header); @@ -549,7 +547,7 @@ class UdpSocketFdImpl { Status send_message(const UdpSocketFd::OutboundMessage &message, bool &is_sent) { is_sent = false; - struct msghdr message_header; + msghdr message_header; detail::UdpSocketSendHelper helper; helper.to_native(message, message_header); @@ -651,11 +649,11 @@ class UdpSocketFdImpl { #if TD_HAS_MMSG Status send_messages_fast(Span messages, size_t &cnt) { //struct mmsghdr { - // struct msghdr msg_hdr; [> Message header <] + // msghdr msg_hdr; [> Message header <] // unsigned int msg_len; [> Number of bytes transmitted <] //}; - struct std::array helpers; - struct std::array headers; + std::array helpers; + std::array headers; size_t to_send = min(messages.size(), headers.size()); for (size_t i = 0; i < to_send; i++) { helpers[i].to_native(messages[i], headers[i].msg_hdr); @@ -702,11 +700,11 @@ class UdpSocketFdImpl { #endif } //struct mmsghdr { - // struct msghdr msg_hdr; [> Message header <] + // msghdr msg_hdr; [> Message header <] // unsigned int msg_len; [> Number of bytes transmitted <] //}; - struct std::array helpers; - struct std::array headers; + std::array helpers; + std::array headers; size_t to_receive = min(messages.size(), headers.size()); for (size_t i = 0; i < to_receive; i++) { helpers[i].to_native(messages[i], headers[i].msg_hdr); diff --git a/tdutils/td/utils/port/detail/EventFdLinux.cpp b/tdutils/td/utils/port/detail/EventFdLinux.cpp index 8de405592..04521fc0b 100644 --- a/tdutils/td/utils/port/detail/EventFdLinux.cpp +++ b/tdutils/td/utils/port/detail/EventFdLinux.cpp @@ -67,7 +67,7 @@ void EventFdLinux::release() { auto native_fd = impl_->info.native_fd().fd(); auto result = [&]() -> Result { - auto write_res = detail::skip_eintr([&] { return ::write(native_fd, slice.begin(), slice.size()); }); + auto write_res = detail::skip_eintr([&] { return write(native_fd, slice.begin(), slice.size()); }); auto write_errno = errno; if (write_res >= 0) { return narrow_cast(write_res); diff --git a/test/tdclient.cpp b/test/tdclient.cpp index f1a58b8bc..5217b33d8 100644 --- a/test/tdclient.cpp +++ b/test/tdclient.cpp @@ -992,7 +992,7 @@ TEST(Client, Close) { td::thread receive_thread([&] { auto max_continue_send = td::Random::fast_bool() ? 0 : 1000; while (true) { - auto response = client.receive(100.0); + auto response = client.receive(10.0); if (response.object == nullptr) { if (!stop_send) { stop_send = true; @@ -1056,7 +1056,7 @@ TEST(Client, ManagerClose) { auto max_continue_send = td::Random::fast_bool() ? 0 : 1000; bool can_stop_send = false; while (true) { - auto response = client_manager.receive(100.0); + auto response = client_manager.receive(10.0); if (response.object == nullptr) { if (!stop_send) { can_stop_send = true;