diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2019-08-20 20:51:52 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2019-08-20 20:51:52 +0000 |
commit | 5f29bb8a675e8f96452b632e7129113f7dec850e (patch) | |
tree | 3d3f2a0d3ad10872a4dcaba8ec8d1d20c87ab147 /source/Host/common/Socket.cpp | |
parent | 88c643b6fec27eec436c8d138fee6346e92337d6 (diff) |
Notes
Diffstat (limited to 'source/Host/common/Socket.cpp')
-rw-r--r-- | source/Host/common/Socket.cpp | 64 |
1 files changed, 46 insertions, 18 deletions
diff --git a/source/Host/common/Socket.cpp b/source/Host/common/Socket.cpp index 875291bc115f8..a89f1178e96c1 100644 --- a/source/Host/common/Socket.cpp +++ b/source/Host/common/Socket.cpp @@ -1,9 +1,8 @@ //===-- Socket.cpp ----------------------------------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// @@ -19,6 +18,9 @@ #include "lldb/Utility/RegularExpression.h" #include "llvm/ADT/STLExtras.h" +#include "llvm/Support/Errno.h" +#include "llvm/Support/Error.h" +#include "llvm/Support/WindowsError.h" #ifndef LLDB_DISABLE_POSIX #include "lldb/Host/posix/DomainSocket.h" @@ -78,6 +80,31 @@ Socket::Socket(SocketProtocol protocol, bool should_close, Socket::~Socket() { Close(); } +llvm::Error Socket::Initialize() { +#if defined(_WIN32) + auto wVersion = WINSOCK_VERSION; + WSADATA wsaData; + int err = ::WSAStartup(wVersion, &wsaData); + if (err == 0) { + if (wsaData.wVersion < wVersion) { + WSACleanup(); + return llvm::make_error<llvm::StringError>( + "WSASock version is not expected.", llvm::inconvertibleErrorCode()); + } + } else { + return llvm::errorCodeToError(llvm::mapWindowsError(::WSAGetLastError())); + } +#endif + + return llvm::Error::success(); +} + +void Socket::Terminate() { +#if defined(_WIN32) + ::WSACleanup(); +#endif +} + std::unique_ptr<Socket> Socket::Create(const SocketProtocol protocol, bool child_processes_inherit, Status &error) { @@ -124,7 +151,7 @@ Status Socket::TcpConnect(llvm::StringRef host_and_port, Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_COMMUNICATION)); if (log) log->Printf("Socket::%s (host/port = %s)", __FUNCTION__, - host_and_port.data()); + host_and_port.str().c_str()); Status error; std::unique_ptr<Socket> connect_socket( @@ -144,7 +171,7 @@ Status Socket::TcpListen(llvm::StringRef host_and_port, Predicate<uint16_t> *predicate, int backlog) { Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_CONNECTION)); if (log) - log->Printf("Socket::%s (%s)", __FUNCTION__, host_and_port.data()); + log->Printf("Socket::%s (%s)", __FUNCTION__, host_and_port.str().c_str()); Status error; std::string host_str; @@ -184,7 +211,7 @@ Status Socket::UdpConnect(llvm::StringRef host_and_port, Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_CONNECTION)); if (log) log->Printf("Socket::%s (host/port = %s)", __FUNCTION__, - host_and_port.data()); + host_and_port.str().c_str()); return UDPSocket::Connect(host_and_port, child_processes_inherit, socket); } @@ -260,8 +287,8 @@ bool Socket::DecodeHostAndPort(llvm::StringRef host_and_port, llvm::StringRef("([^:]+|\\[[0-9a-fA-F:]+.*\\]):([0-9]+)")); RegularExpression::Match regex_match(2); if (g_regex.Execute(host_and_port, ®ex_match)) { - if (regex_match.GetMatchAtIndex(host_and_port.data(), 1, host_str) && - regex_match.GetMatchAtIndex(host_and_port.data(), 2, port_str)) { + if (regex_match.GetMatchAtIndex(host_and_port, 1, host_str) && + regex_match.GetMatchAtIndex(host_and_port, 2, port_str)) { // IPv6 addresses are wrapped in [] when specified with ports if (host_str.front() == '[' && host_str.back() == ']') host_str = host_str.substr(1, host_str.size() - 2); @@ -275,7 +302,8 @@ bool Socket::DecodeHostAndPort(llvm::StringRef host_and_port, // port is too large if (error_ptr) error_ptr->SetErrorStringWithFormat( - "invalid host:port specification: '%s'", host_and_port.data()); + "invalid host:port specification: '%s'", + host_and_port.str().c_str()); return false; } } @@ -284,9 +312,7 @@ bool Socket::DecodeHostAndPort(llvm::StringRef host_and_port, // integer, representing a port with an empty host. host_str.clear(); port_str.clear(); - bool ok = false; - port = StringConvert::ToUInt32(host_and_port.data(), UINT32_MAX, 10, &ok); - if (ok && port < UINT16_MAX) { + if (to_integer(host_and_port, port, 10) && port < UINT16_MAX) { port_str = host_and_port; if (error_ptr) error_ptr->Clear(); @@ -295,7 +321,7 @@ bool Socket::DecodeHostAndPort(llvm::StringRef host_and_port, if (error_ptr) error_ptr->SetErrorStringWithFormat("invalid host:port specification: '%s'", - host_and_port.data()); + host_and_port.str().c_str()); return false; } @@ -368,8 +394,8 @@ Status Socket::Close() { Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_CONNECTION)); if (log) - log->Printf("%p Socket::Close (fd = %i)", static_cast<void *>(this), - m_socket); + log->Printf("%p Socket::Close (fd = %" PRIu64 ")", + static_cast<void *>(this), static_cast<uint64_t>(m_socket)); #if defined(_WIN32) bool success = !!closesocket(m_socket); @@ -453,9 +479,11 @@ NativeSocket Socket::AcceptSocket(NativeSocket sockfd, struct sockaddr *addr, if (!child_processes_inherit) { flags |= SOCK_CLOEXEC; } - NativeSocket fd = ::accept4(sockfd, addr, addrlen, flags); + NativeSocket fd = llvm::sys::RetryAfterSignal(-1, ::accept4, + sockfd, addr, addrlen, flags); #else - NativeSocket fd = ::accept(sockfd, addr, addrlen); + NativeSocket fd = llvm::sys::RetryAfterSignal(-1, ::accept, + sockfd, addr, addrlen); #endif if (fd == kInvalidSocketValue) SetLastError(error); |