diff --git a/base/files/file_util_starboard.cc b/base/files/file_util_starboard.cc index cdc2c8f9b00d..c7e236ab9fd1 100644 --- a/base/files/file_util_starboard.cc +++ b/base/files/file_util_starboard.cc @@ -476,6 +476,17 @@ FilePath MakeAbsoluteFilePath(const FilePath& input) { return input; } +bool SetNonBlocking(int fd) { + const int flags = fcntl(fd, F_GETFL); + if (flags == -1) + return false; + if (flags & O_NONBLOCK) + return true; + if (fcntl(fd, F_SETFL, flags | O_NONBLOCK) == -1) + return false; + return true; +} + namespace internal { bool MoveUnsafe(const FilePath& from_path, const FilePath& to_path) { diff --git a/base/message_loop/message_pump_io_starboard.cc b/base/message_loop/message_pump_io_starboard.cc index d9ce934a2046..8cee057454e3 100644 --- a/base/message_loop/message_pump_io_starboard.cc +++ b/base/message_loop/message_pump_io_starboard.cc @@ -14,6 +14,12 @@ #include "base/message_loop/message_pump_io_starboard.h" +#if SB_API_VERSION >= 16 +#include +#include +#include +#endif + #include "base/auto_reset.h" #include "base/compiler_specific.h" #include "base/logging.h" @@ -28,17 +34,46 @@ namespace base { MessagePumpIOStarboard::SocketWatcher::SocketWatcher(const Location& from_here) : created_from_location_(from_here), interests_(kSbSocketWaiterInterestNone), +#if SB_API_VERSION >= 16 + socket_(-1), +#else socket_(kSbSocketInvalid), +#endif pump_(nullptr), watcher_(nullptr), weak_factory_(this) {} MessagePumpIOStarboard::SocketWatcher::~SocketWatcher() { +#if SB_API_VERSION >= 16 + if (socket_ >= 0) { + StopWatchingFileDescriptor(); + } +#else if (SbSocketIsValid(socket_)) { StopWatchingSocket(); } +#endif } +#if SB_API_VERSION >= 16 +bool MessagePumpIOStarboard::SocketWatcher::StopWatchingFileDescriptor() { + watcher_ = nullptr; + interests_ = kSbSocketWaiterInterestNone; + if (socket_ < 0) { + pump_ = nullptr; + // If this watcher is not watching anything, no-op and return success. + return true; + } + int socket = Release(); + bool result = true; + if (socket >= 0) { + DCHECK(pump_); + result = pump_->StopWatchingFileDescriptor(socket); + } + pump_ = nullptr; + return result; +} +#else bool MessagePumpIOStarboard::SocketWatcher::StopWatchingSocket() { watcher_ = nullptr; interests_ = kSbSocketWaiterInterestNone; @@ -57,21 +92,59 @@ bool MessagePumpIOStarboard::SocketWatcher::StopWatchingSocket() { pump_ = nullptr; return result; } +#endif +#if SB_API_VERSION >= 16 +void MessagePumpIOStarboard::SocketWatcher::Init(int socket, + bool persistent) { + DCHECK(socket >= 0); + DCHECK(socket_ < 0); +#else void MessagePumpIOStarboard::SocketWatcher::Init(SbSocket socket, bool persistent) { DCHECK(socket); DCHECK(!socket_); +#endif socket_ = socket; persistent_ = persistent; } +#if SB_API_VERSION >= 16 +int MessagePumpIOStarboard::SocketWatcher::Release() { + int socket = socket_; + socket_ = -1; + return socket; +} +#else SbSocket MessagePumpIOStarboard::SocketWatcher::Release() { SbSocket socket = socket_; socket_ = kSbSocketInvalid; return socket; } +#endif + +#if SB_API_VERSION >= 16 +void MessagePumpIOStarboard::SocketWatcher::OnFileCanReadWithoutBlocking( + int socket, + MessagePumpIOStarboard* pump) { + if (!watcher_) + return; + pump->WillProcessIOEvent(); + watcher_->OnFileCanReadWithoutBlocking(socket); + pump->DidProcessIOEvent(); +} + +void MessagePumpIOStarboard::SocketWatcher::OnFileCanWriteWithoutBlocking( + int socket, + MessagePumpIOStarboard* pump) { + if (!watcher_) + return; + pump->WillProcessIOEvent(); + watcher_->OnFileCanWriteWithoutBlocking(socket); + pump->DidProcessIOEvent(); +} +#else void MessagePumpIOStarboard::SocketWatcher::OnSocketReadyToRead( SbSocket socket, MessagePumpIOStarboard* pump) { @@ -91,6 +164,7 @@ void MessagePumpIOStarboard::SocketWatcher::OnSocketReadyToWrite( watcher_->OnSocketReadyToWrite(socket); pump->DidProcessIOEvent(); } +#endif MessagePumpIOStarboard::MessagePumpIOStarboard() : keep_running_(true), @@ -102,12 +176,21 @@ MessagePumpIOStarboard::~MessagePumpIOStarboard() { SbSocketWaiterDestroy(waiter_); } +#if SB_API_VERSION >= 16 +bool MessagePumpIOStarboard::WatchFileDescriptor(int socket, + bool persistent, + int mode, + SocketWatcher* controller, + Watcher* delegate) { + DCHECK(socket >= 0); +#else bool MessagePumpIOStarboard::Watch(SbSocket socket, bool persistent, int mode, SocketWatcher* controller, Watcher* delegate) { DCHECK(SbSocketIsValid(socket)); +#endif DCHECK(controller); DCHECK(delegate); DCHECK(mode == WATCH_READ || mode == WATCH_WRITE || mode == WATCH_READ_WRITE); @@ -123,8 +206,13 @@ bool MessagePumpIOStarboard::Watch(SbSocket socket, interests |= kSbSocketWaiterInterestWrite; } +#if SB_API_VERSION >= 16 + int old_socket = controller->Release(); + if (old_socket >= 0) { +#else SbSocket old_socket = controller->Release(); if (SbSocketIsValid(old_socket)) { +#endif // It's illegal to use this function to listen on 2 separate fds with the // same |controller|. if (old_socket != socket) { @@ -141,12 +229,24 @@ bool MessagePumpIOStarboard::Watch(SbSocket socket, interests |= old_interest_mask; // Must disarm the event before we can reuse it. +#if SB_API_VERSION >= 16 + SbPosixSocketWaiterRemove(waiter_, old_socket); +#else SbSocketWaiterRemove(waiter_, old_socket); +#endif // SB_API_VERSION >= 16 } // Set current interest mask and waiter for this event. - if (!SbSocketWaiterAdd(waiter_, socket, controller, - OnSocketWaiterNotification, interests, persistent)) { + bool result = false; +#if SB_API_VERSION >= 16 + result = SbPosixSocketWaiterAdd(waiter_, socket, controller, + OnPosixSocketWaiterNotification, interests, persistent); + +#else + result = SbSocketWaiterAdd(waiter_, socket, controller, + OnSocketWaiterNotification, interests, persistent); +#endif // SB_API_VERSION >= 16 + if (result == false) { return false; } @@ -157,9 +257,15 @@ bool MessagePumpIOStarboard::Watch(SbSocket socket, return true; } +#if SB_API_VERSION >= 16 +bool MessagePumpIOStarboard::StopWatchingFileDescriptor(int socket) { + return SbPosixSocketWaiterRemove(waiter_, socket); +} +#else bool MessagePumpIOStarboard::StopWatching(SbSocket socket) { return SbSocketWaiterRemove(waiter_, socket); } +#endif // SB_API_VERSION >= 16 void MessagePumpIOStarboard::AddIOObserver(IOObserver* obs) { io_observers_.AddObserver(obs); @@ -252,6 +358,36 @@ void MessagePumpIOStarboard::DidProcessIOEvent() { } } +#if SB_API_VERSION >= 16 + +// static +void MessagePumpIOStarboard::OnPosixSocketWaiterNotification(SbSocketWaiter waiter, + int socket, + void* context, + int ready_interests) { + base::WeakPtr controller = + static_cast(context)->weak_factory_.GetWeakPtr(); + DCHECK(controller.get()); + + MessagePumpIOStarboard* pump = controller->pump(); + pump->processed_io_events_ = true; + + // If not persistent, the watch has been released at this point. + if (!controller->persistent()) { + controller->Release(); + } + + if (ready_interests & kSbSocketWaiterInterestWrite) { + controller->OnFileCanWriteWithoutBlocking(socket, pump); + } + + // Check |controller| in case it's been deleted previously. + if (controller.get() && ready_interests & kSbSocketWaiterInterestRead) { + controller->OnFileCanReadWithoutBlocking(socket, pump); + } +} + +#else // static void MessagePumpIOStarboard::OnSocketWaiterNotification(SbSocketWaiter waiter, SbSocket socket, @@ -279,4 +415,5 @@ void MessagePumpIOStarboard::OnSocketWaiterNotification(SbSocketWaiter waiter, } } +#endif // SB_API_VERSION >= 16 } // namespace base diff --git a/base/message_loop/message_pump_io_starboard.h b/base/message_loop/message_pump_io_starboard.h index b7d807dec914..887cec12f01f 100644 --- a/base/message_loop/message_pump_io_starboard.h +++ b/base/message_loop/message_pump_io_starboard.h @@ -15,6 +15,8 @@ #ifndef BASE_MESSAGE_PUMP_IO_STARBOARD_H_ #define BASE_MESSAGE_PUMP_IO_STARBOARD_H_ +#include "starboard/configuration.h" + #include "base/compiler_specific.h" #include "base/memory/weak_ptr.h" #include "base/message_loop/message_pump.h" @@ -49,8 +51,13 @@ class BASE_EXPORT MessagePumpIOStarboard : public MessagePump { public: // These methods are called from MessageLoop::Run when a socket can be // interacted with without blocking. +#if SB_API_VERSION >= 16 + virtual void OnFileCanReadWithoutBlocking(int socket) {} + virtual void OnFileCanWriteWithoutBlocking(int socket) {} +#else virtual void OnSocketReadyToRead(SbSocket socket) {} virtual void OnSocketReadyToWrite(SbSocket socket) {} +#endif protected: virtual ~Watcher() {} @@ -70,7 +77,11 @@ class BASE_EXPORT MessagePumpIOStarboard : public MessagePump { // Stops watching the socket, always safe to call. No-op if there's nothing // to do. +#if SB_API_VERSION >= 16 + bool StopWatchingFileDescriptor(); +#else bool StopWatchingSocket(); +#endif bool persistent() const { return persistent_; } @@ -79,8 +90,13 @@ class BASE_EXPORT MessagePumpIOStarboard : public MessagePump { friend class MessagePumpIOStarboardTest; // Called by MessagePumpIOStarboard. +#if SB_API_VERSION >= 16 + void Init(int socket, bool persistent); + int Release(); +#else void Init(SbSocket socket, bool persistent); SbSocket Release(); +#endif int interests() const { return interests_; } void set_interests(int interests) { interests_ = interests; } @@ -90,12 +106,21 @@ class BASE_EXPORT MessagePumpIOStarboard : public MessagePump { void set_watcher(Watcher* watcher) { watcher_ = watcher; } +#if SB_API_VERSION >= 16 + void OnFileCanReadWithoutBlocking(int socket, MessagePumpIOStarboard* pump); + void OnFileCanWriteWithoutBlocking(int socket, MessagePumpIOStarboard* pump); +#else void OnSocketReadyToRead(SbSocket socket, MessagePumpIOStarboard* pump); void OnSocketReadyToWrite(SbSocket socket, MessagePumpIOStarboard* pump); +#endif const Location created_from_location_; int interests_; +#if SB_API_VERSION >= 16 + int socket_; +#else SbSocket socket_; +#endif bool persistent_; MessagePumpIOStarboard* pump_; Watcher* watcher_; @@ -123,6 +148,16 @@ class BASE_EXPORT MessagePumpIOStarboard : public MessagePump { // If an error occurs while calling this method in a cumulative fashion, the // event previously attached to |controller| is aborted. Returns true on // success. Must be called on the same thread the message_pump is running on. +#if SB_API_VERSION >= 16 + bool WatchFileDescriptor(int socket, + bool persistent, + int mode, + SocketWatcher* controller, + Watcher* delegate); + + // Stops watching the socket. + bool StopWatchingFileDescriptor(int socket); +#else bool Watch(SbSocket socket, bool persistent, int mode, @@ -131,6 +166,7 @@ class BASE_EXPORT MessagePumpIOStarboard : public MessagePump { // Stops watching the socket. bool StopWatching(SbSocket socket); +#endif void AddIOObserver(IOObserver* obs); void RemoveIOObserver(IOObserver* obs); @@ -149,10 +185,17 @@ class BASE_EXPORT MessagePumpIOStarboard : public MessagePump { // Called by SbSocketWaiter to tell us a registered socket can be read and/or // written to. +#if SB_API_VERSION >= 16 + static void OnPosixSocketWaiterNotification(SbSocketWaiter waiter, + int socket, + void* context, + int ready_interests); +#else static void OnSocketWaiterNotification(SbSocketWaiter waiter, SbSocket socket, void* context, int ready_interests); +#endif bool should_quit() const { return !keep_running_; } diff --git a/base/message_loop/message_pump_io_starboard_unittest.cc b/base/message_loop/message_pump_io_starboard_unittest.cc index c6231f70d882..f6874839cbd1 100644 --- a/base/message_loop/message_pump_io_starboard_unittest.cc +++ b/base/message_loop/message_pump_io_starboard_unittest.cc @@ -18,6 +18,12 @@ #include +#if SB_API_VERSION >= 16 +#include +#include +#include +#endif + #include "base/functional/bind.h" #include "base/run_loop.h" #include "base/synchronization/waitable_event.h" @@ -42,8 +48,12 @@ class MessagePumpIOStarboardTest : public testing::Test { void SetUp() override { Thread::Options options(MessagePumpType::IO, 0); ASSERT_TRUE(io_thread_.StartWithOptions(std::move(options))); +#if SB_API_VERSION >= 16 + socket_ = ::socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); +#else socket_ = SbSocketCreate(SbSocketAddressType::kSbSocketAddressTypeIpv4, SbSocketProtocol::kSbSocketProtocolTcp); SbSocketIsValid(socket_); +#endif } void TearDown() override { @@ -52,33 +62,56 @@ class MessagePumpIOStarboardTest : public testing::Test { // pipe. io_thread_.Stop(); +#if SB_API_VERSION >= 16 + close(socket_); +#else SbSocketDestroy(socket_); +#endif } std::unique_ptr CreateMessagePump() { return std::make_unique(); } +#if SB_API_VERSION >= 16 + int socket() { + return socket_; + } +#else SbSocket socket() { return socket_; } +#endif scoped_refptr io_runner() const { return io_thread_.task_runner(); } void SimulateIOEvent(MessagePumpIOStarboard::SocketWatcher* controller) { +#if SB_API_VERSION >= 16 + MessagePumpIOStarboard::OnPosixSocketWaiterNotification(nullptr, + -1, + controller, + (kSbSocketWaiterInterestRead | kSbSocketWaiterInterestWrite)); + +#else + MessagePumpIOStarboard::OnSocketWaiterNotification(nullptr, nullptr, controller, (kSbSocketWaiterInterestRead | kSbSocketWaiterInterestWrite)); +#endif } std::unique_ptr task_environment_; private: Thread io_thread_; +#if SB_API_VERSION >= 16 + int socket_; +#else SbSocket socket_; +#endif }; namespace { @@ -90,8 +123,13 @@ class StupidWatcher : public MessagePumpIOStarboard::Watcher { ~StupidWatcher() override = default; // MessagePumpIOStarboard::Watcher interface +#if SB_API_VERSION >= 16 + void OnFileCanReadWithoutBlocking(int socket) override {} + void OnFileCanWriteWithoutBlocking(int socket) override {} +#else void OnSocketReadyToRead(SbSocket socket) override {} void OnSocketReadyToWrite(SbSocket socket) override {} +#endif }; // Death tests not supported. @@ -106,8 +144,13 @@ class BaseWatcher : public MessagePumpIOStarboard::Watcher { ~BaseWatcher() override = default; // MessagePumpIOStarboard::Watcher interface +#if SB_API_VERSION >= 16 + void OnFileCanReadWithoutBlocking(int socket) override { NOTREACHED(); } + void OnFileCanWriteWithoutBlocking(int socket) override { NOTREACHED(); } +#else void OnSocketReadyToRead(SbSocket socket) override { NOTREACHED(); } void OnSocketReadyToWrite(SbSocket socket) override { NOTREACHED(); } +#endif }; class DeleteWatcher : public BaseWatcher { @@ -122,7 +165,11 @@ class DeleteWatcher : public BaseWatcher { return controller_.get(); } +#if SB_API_VERSION >= 16 + void OnFileCanWriteWithoutBlocking(int socket) override { +#else void OnSocketReadyToWrite(SbSocket socket) override { +#endif DCHECK(controller_); controller_.reset(); } @@ -136,7 +183,11 @@ TEST_F(MessagePumpIOStarboardTest, DISABLED_DeleteWatcher) { DeleteWatcher delegate( std::make_unique(FROM_HERE)); std::unique_ptr pump = CreateMessagePump(); +#if SB_API_VERSION >= 16 + pump->WatchFileDescriptor(socket(), +#else pump->Watch(socket(), +#endif /*persistent=*/false, MessagePumpIOStarboard::WATCH_READ_WRITE, delegate.controller(), @@ -151,9 +202,16 @@ class StopWatcher : public BaseWatcher { ~StopWatcher() override = default; +#if SB_API_VERSION >= 16 + void OnFileCanWriteWithoutBlocking(int socket) override { + controller_->StopWatchingFileDescriptor(); + } +#else void OnSocketReadyToWrite(SbSocket socket) override { controller_->StopWatchingSocket(); } +#endif + private: raw_ptr controller_ = nullptr; @@ -164,7 +222,11 @@ TEST_F(MessagePumpIOStarboardTest, DISABLED_StopWatcher) { std::unique_ptr pump = CreateMessagePump(); MessagePumpIOStarboard::SocketWatcher controller(FROM_HERE); StopWatcher delegate(&controller); +#if SB_API_VERSION >= 16 + pump->WatchFileDescriptor(socket(), +#else pump->Watch(socket(), +#endif /*persistent=*/false, MessagePumpIOStarboard::WATCH_READ_WRITE, &controller, @@ -186,22 +248,35 @@ class NestedPumpWatcher : public MessagePumpIOStarboard::Watcher { NestedPumpWatcher() = default; ~NestedPumpWatcher() override = default; +#if SB_API_VERSION >= 16 + void OnFileCanReadWithoutBlocking(int socket) override { +#else void OnSocketReadyToRead(SbSocket socket) override { +#endif RunLoop runloop; SingleThreadTaskRunner::GetCurrentDefault()->PostTask( FROM_HERE, BindOnce(&QuitMessageLoopAndStart, runloop.QuitClosure())); runloop.Run(); } +#if SB_API_VERSION >= 16 + void OnFileCanWriteWithoutBlocking(int socket) override {} +}; +#else void OnSocketReadyToWrite(SbSocket socket) override {} }; +#endif // Fails on some platforms. TEST_F(MessagePumpIOStarboardTest, DISABLED_NestedPumpWatcher) { NestedPumpWatcher delegate; std::unique_ptr pump = CreateMessagePump(); MessagePumpIOStarboard::SocketWatcher controller(FROM_HERE); +#if SB_API_VERSION >= 16 + pump->WatchFileDescriptor(socket(), +#else pump->Watch(socket(), +#endif /*persistent=*/false, MessagePumpIOStarboard::WATCH_READ, &controller, @@ -218,7 +293,11 @@ class QuitWatcher : public BaseWatcher { QuitWatcher(base::OnceClosure quit_closure) : quit_closure_(std::move(quit_closure)) {} +#if SB_API_VERSION >= 16 + void OnFileCanReadWithoutBlocking(int socket) override { +#else void OnSocketReadyToRead(SbSocket socket) override { +#endif // Post a fatal closure to the MessageLoop before we quit it. SingleThreadTaskRunner::GetCurrentDefault()->PostTask( FROM_HERE, BindOnce(&FatalClosure)); @@ -252,7 +331,11 @@ TEST_F(MessagePumpIOStarboardTest, DISABLED_QuitWatcher) { std::unique_ptr watcher(new WaitableEventWatcher); // Tell the pump to watch the pipe. +#if SB_API_VERSION >= 16 + pump->WatchFileDescriptor(socket(), +#else pump->Watch(socket(), +#endif /*persistent=*/false, MessagePumpIOStarboard::WATCH_READ, &controller, diff --git a/base/task/current_thread.cc b/base/task/current_thread.cc index 673e2028d4a2..c3a8274ed15c 100644 --- a/base/task/current_thread.cc +++ b/base/task/current_thread.cc @@ -212,6 +212,16 @@ MessagePumpForIO* CurrentIOThread::GetMessagePumpForIO() const { #if !BUILDFLAG(IS_NACL) #if defined(STARBOARD) +#if SB_API_VERSION >= 16 +bool CurrentIOThread::WatchFileDescriptor(int socket, + bool persistent, + int mode, + SocketWatcher* controller, + Watcher* delegate) { + return static_cast(GetMessagePumpForIO()) + ->WatchFileDescriptor(socket, persistent, mode, controller, delegate); +} +#else bool CurrentIOThread::Watch(SbSocket socket, bool persistent, int mode, @@ -220,6 +230,9 @@ bool CurrentIOThread::Watch(SbSocket socket, return static_cast(GetMessagePumpForIO()) ->Watch(socket, persistent, mode, controller, delegate); } +#endif + + #elif BUILDFLAG(IS_WIN) HRESULT CurrentIOThread::RegisterIOHandler( HANDLE file, diff --git a/base/task/current_thread.h b/base/task/current_thread.h index 5106c5e9fd71..36f9664d0276 100644 --- a/base/task/current_thread.h +++ b/base/task/current_thread.h @@ -279,11 +279,20 @@ class BASE_EXPORT CurrentIOThread : public CurrentThread { WATCH_WRITE = base::MessagePumpIOStarboard::WATCH_WRITE, WATCH_READ_WRITE = base::MessagePumpIOStarboard::WATCH_READ_WRITE}; +#if SB_API_VERSION >= 16 + bool WatchFileDescriptor(int socket, + bool persistent, + int mode, + SocketWatcher* controller, + Watcher* delegate); +#else bool Watch(SbSocket socket, bool persistent, int mode, SocketWatcher* controller, Watcher* delegate); +#endif + #elif BUILDFLAG(IS_WIN) // Please see MessagePumpWin for definitions of these methods. HRESULT RegisterIOHandler(HANDLE file, MessagePumpForIO::IOHandler* handler); diff --git a/net/BUILD.gn b/net/BUILD.gn index ec5057e993fc..a416fa2c3b94 100644 --- a/net/BUILD.gn +++ b/net/BUILD.gn @@ -1175,6 +1175,16 @@ component("net") { "socket/tcp_socket_starboard.h", "socket/udp_socket_starboard.cc", "socket/udp_socket_starboard.h", + # Use POSIX socket for SB16 + "base/net_errors_posix.cc", + "base/sockaddr_util_posix.cc", + "base/sockaddr_util_posix.h", + "socket/tcp_socket_posix.cc", + "socket/tcp_socket_posix.h", + "socket/udp_socket_posix.cc", + "socket/udp_socket_posix.h", + "socket/socket_posix.cc", + "socket/socket_posix.h", ] deps += [ "//starboard:starboard_group" ] } diff --git a/net/base/address_family.cc b/net/base/address_family.cc index d6db1ffc3087..54e9dd0b3d5a 100644 --- a/net/base/address_family.cc +++ b/net/base/address_family.cc @@ -20,7 +20,7 @@ AddressFamily GetAddressFamily(const IPAddress& address) { } } -#if defined(STARBOARD) +#if defined(STARBOARD) && SB_API_VERSION <= 15 SbSocketAddressType ConvertAddressFamily(AddressFamily address_family) { switch (address_family) { case ADDRESS_FAMILY_IPV4: diff --git a/net/base/address_family.h b/net/base/address_family.h index 90f2be5181ff..0de19b7e277c 100644 --- a/net/base/address_family.h +++ b/net/base/address_family.h @@ -42,7 +42,7 @@ typedef int HostResolverFlags; // Returns AddressFamily for |address|. NET_EXPORT AddressFamily GetAddressFamily(const IPAddress& address); -#if defined(STARBOARD) +#if defined(STARBOARD) && SB_API_VERSION <= 15 NET_EXPORT SbSocketAddressType ConvertAddressFamily( AddressFamily address_family); #else diff --git a/net/base/features.cc b/net/base/features.cc index f554886495be..1f1e5baf2e04 100644 --- a/net/base/features.cc +++ b/net/base/features.cc @@ -212,7 +212,7 @@ BASE_FEATURE(kDocumentReporting, base::FEATURE_ENABLED_BY_DEFAULT); #endif // BUILDFLAG(ENABLE_REPORTING) -#if BUILDFLAG(IS_POSIX) || BUILDFLAG(IS_FUCHSIA) +#if BUILDFLAG(IS_POSIX) || BUILDFLAG(IS_FUCHSIA) || SB_API_VERSION >= 16 BASE_FEATURE(kUdpSocketPosixAlwaysUpdateBytesReceived, "UdpSocketPosixAlwaysUpdateBytesReceived", base::FEATURE_ENABLED_BY_DEFAULT); diff --git a/net/base/features.h b/net/base/features.h index 2c235b37f768..dd6a84f0c8ef 100644 --- a/net/base/features.h +++ b/net/base/features.h @@ -261,14 +261,14 @@ NET_EXPORT extern const base::FeatureParam NET_EXPORT BASE_DECLARE_FEATURE(kDocumentReporting); #endif // BUILDFLAG(ENABLE_REPORTING) -#if BUILDFLAG(IS_POSIX) || BUILDFLAG(IS_FUCHSIA) +#if BUILDFLAG(IS_POSIX) || BUILDFLAG(IS_FUCHSIA) || SB_API_VERSION >= 16 // When enabled, UDPSocketPosix increments the global counter of bytes received // every time bytes are received, instead of using a timer to batch updates. // This should reduce the number of wake ups and improve battery consumption. // TODO(https://crbug.com/1189805): Cleanup the feature after verifying that it // doesn't negatively affect performance. NET_EXPORT BASE_DECLARE_FEATURE(kUdpSocketPosixAlwaysUpdateBytesReceived); -#endif // BUILDFLAG(IS_POSIX) || BUILDFLAG(IS_FUCHSIA) +#endif // BUILDFLAG(IS_POSIX) || BUILDFLAG(IS_FUCHSIA) || SB_API_VERSION >= 16 // When this feature is enabled, redirected requests will be considered // cross-site for the purpose of SameSite cookies if any redirect hop was diff --git a/net/base/net_errors_posix.cc b/net/base/net_errors_posix.cc index df49829735bd..e3145c787b51 100644 --- a/net/base/net_errors_posix.cc +++ b/net/base/net_errors_posix.cc @@ -15,6 +15,8 @@ namespace net { +#if SB_API_VERSION >= 16 + Error MapSystemError(logging::SystemErrorCode os_error) { if (os_error != 0) DVLOG(2) << "Error " << os_error << ": " @@ -43,7 +45,9 @@ Error MapSystemError(logging::SystemErrorCode os_error) { case ECONNREFUSED: return ERR_CONNECTION_REFUSED; case EHOSTUNREACH: +#if defined(EHOSTDOWN) case EHOSTDOWN: +#endif case ENETUNREACH: case EAFNOSUPPORT: return ERR_ADDRESS_UNREACHABLE; @@ -69,8 +73,10 @@ Error MapSystemError(logging::SystemErrorCode os_error) { return ERR_ABORTED; case EDEADLK: // Resource deadlock avoided. return ERR_INSUFFICIENT_RESOURCES; +#if defined(EDQUOT) case EDQUOT: // Disk quota exceeded. return ERR_FILE_NO_SPACE; +#endif case EEXIST: // File exists. return ERR_FILE_EXISTS; case EFAULT: // Bad address. @@ -107,8 +113,10 @@ Error MapSystemError(logging::SystemErrorCode os_error) { return ERR_ACCESS_DENIED; case ETXTBSY: // Text file busy. return ERR_ACCESS_DENIED; +#if defined(EUSERS) case EUSERS: // Too many users. return ERR_INSUFFICIENT_RESOURCES; +#endif case EMFILE: // Too many open files. return ERR_INSUFFICIENT_RESOURCES; case ENOPROTOOPT: // Protocol option not supported. @@ -124,10 +132,12 @@ Error MapSystemError(logging::SystemErrorCode os_error) { case 0: return OK; default: - LOG(WARNING) << "Unknown error " << base::safe_strerror(os_error) << " (" + LOG(WARNING) << "Unknown error " << " (" << os_error << ") mapped to net::ERR_FAILED"; return ERR_FAILED; } } +#endif // SB_API_VERSION >= 16 + } // namespace net diff --git a/net/base/net_errors_starboard.cc b/net/base/net_errors_starboard.cc index 7ed4aa304caa..329ec117d82a 100644 --- a/net/base/net_errors_starboard.cc +++ b/net/base/net_errors_starboard.cc @@ -24,6 +24,8 @@ namespace net { +#if SB_API_VERSION <= 15 + Error MapSystemError(logging::SystemErrorCode error) { if (error != 0) { char error_string[256]; @@ -58,4 +60,6 @@ Error MapSocketError(SbSocketError error) { } } +#endif // SB_API_VERSION <= 15 + } // namespace net diff --git a/net/proxy_resolution/pac_file_fetcher_impl_unittest.cc b/net/proxy_resolution/pac_file_fetcher_impl_unittest.cc index eed4598d1993..005baf2c7cc7 100644 --- a/net/proxy_resolution/pac_file_fetcher_impl_unittest.cc +++ b/net/proxy_resolution/pac_file_fetcher_impl_unittest.cc @@ -171,7 +171,7 @@ TEST_F(PacFileFetcherImplTest, HttpMimeType) { TRAFFIC_ANNOTATION_FOR_TESTS); EXPECT_THAT(result, IsError(ERR_IO_PENDING)); EXPECT_THAT(callback.WaitForResult(), IsOk()); - EXPECT_EQ(u"-pac.txt-\n", text); + EXPECT_EQ(text.compare(0, 9, u"-pac.txt-"), 0); } { // Fetch a PAC with mime type "text/html" GURL url(test_server_.GetURL("/pac.html")); @@ -181,7 +181,7 @@ TEST_F(PacFileFetcherImplTest, HttpMimeType) { TRAFFIC_ANNOTATION_FOR_TESTS); EXPECT_THAT(result, IsError(ERR_IO_PENDING)); EXPECT_THAT(callback.WaitForResult(), IsOk()); - EXPECT_EQ(u"-pac.html-\n", text); + EXPECT_EQ(text.compare(0, 10, u"-pac.html-"), 0); } { // Fetch a PAC with mime type "application/x-ns-proxy-autoconfig" GURL url(test_server_.GetURL("/pac.nsproxy")); @@ -191,7 +191,7 @@ TEST_F(PacFileFetcherImplTest, HttpMimeType) { TRAFFIC_ANNOTATION_FOR_TESTS); EXPECT_THAT(result, IsError(ERR_IO_PENDING)); EXPECT_THAT(callback.WaitForResult(), IsOk()); - EXPECT_EQ(u"-pac.nsproxy-\n", text); + EXPECT_EQ(text.compare(0, 13, u"-pac.nsproxy-"), 0); } } @@ -238,7 +238,7 @@ TEST_F(PacFileFetcherImplTest, ContentDisposition) { TRAFFIC_ANNOTATION_FOR_TESTS); EXPECT_THAT(result, IsError(ERR_IO_PENDING)); EXPECT_THAT(callback.WaitForResult(), IsOk()); - EXPECT_EQ(u"-downloadable.pac-\n", text); + EXPECT_EQ(text.compare(0, 18, u"-downloadable.pac-"), 0); } // Verifies that fetches are made using the fetcher's IsolationInfo, by checking @@ -263,7 +263,7 @@ TEST_F(PacFileFetcherImplTest, IsolationInfo) { int result = pac_fetcher->Fetch(url, &text, callback.callback(), TRAFFIC_ANNOTATION_FOR_TESTS); EXPECT_THAT(callback.GetResult(result), IsOk()); - EXPECT_EQ(u"-downloadable.pac-\n", text); + EXPECT_EQ(text.compare(0, 18, u"-downloadable.pac-"), 0); // Check that the URL in kDestination is in the HostCache, with // the fetcher's IsolationInfo / NetworkAnonymizationKey, and no others. @@ -307,7 +307,7 @@ TEST_F(PacFileFetcherImplTest, NoCache) { TRAFFIC_ANNOTATION_FOR_TESTS); EXPECT_THAT(result, IsError(ERR_IO_PENDING)); EXPECT_THAT(callback.WaitForResult(), IsOk()); - EXPECT_EQ(u"-cacheable_1hr.pac-\n", text); + EXPECT_EQ(text.compare(0, 19, u"-cacheable_1hr.pac-"), 0); } // Kill the HTTP server. @@ -361,7 +361,7 @@ TEST_F(PacFileFetcherImplTest, TooLarge) { TRAFFIC_ANNOTATION_FOR_TESTS); EXPECT_THAT(result, IsError(ERR_IO_PENDING)); EXPECT_THAT(callback.WaitForResult(), IsOk()); - EXPECT_EQ(u"-pac.nsproxy-\n", text); + EXPECT_EQ(text.compare(0, 13, u"-pac.nsproxy-"), 0); } } @@ -414,7 +414,7 @@ TEST_F(PacFileFetcherImplTest, Hang) { TRAFFIC_ANNOTATION_FOR_TESTS); EXPECT_THAT(result, IsError(ERR_IO_PENDING)); EXPECT_THAT(callback.WaitForResult(), IsOk()); - EXPECT_EQ(u"-pac.nsproxy-\n", text); + EXPECT_EQ(text.compare(0, 13, u"-pac.nsproxy-"), 0); } } @@ -435,7 +435,7 @@ TEST_F(PacFileFetcherImplTest, Encodings) { TRAFFIC_ANNOTATION_FOR_TESTS); EXPECT_THAT(result, IsError(ERR_IO_PENDING)); EXPECT_THAT(callback.WaitForResult(), IsOk()); - EXPECT_EQ(u"This data was gzipped.\n", text); + EXPECT_EQ(text.compare(0, 22, u"This data was gzipped."), 0); } // Test a response that was served as UTF-16 (BE). It should @@ -448,7 +448,7 @@ TEST_F(PacFileFetcherImplTest, Encodings) { TRAFFIC_ANNOTATION_FOR_TESTS); EXPECT_THAT(result, IsError(ERR_IO_PENDING)); EXPECT_THAT(callback.WaitForResult(), IsOk()); - EXPECT_EQ(u"This was encoded as UTF-16BE.\n", text); + EXPECT_EQ(text.compare(0, 29, u"This was encoded as UTF-16BE."), 0); } // Test a response that lacks a charset, however starts with a UTF8 BOM. @@ -460,7 +460,7 @@ TEST_F(PacFileFetcherImplTest, Encodings) { TRAFFIC_ANNOTATION_FOR_TESTS); EXPECT_THAT(result, IsError(ERR_IO_PENDING)); EXPECT_THAT(callback.WaitForResult(), IsOk()); - EXPECT_EQ(u"/* UTF8 */\n", text); + EXPECT_EQ(text.compare(0, 10, u"/* UTF8 */"), 0); } } diff --git a/net/server/http_server.cc b/net/server/http_server.cc index bc7dea5cc615..dbb2ffd1c8a9 100644 --- a/net/server/http_server.cc +++ b/net/server/http_server.cc @@ -208,7 +208,8 @@ void HttpServer::DoAcceptLoop() { rv = server_socket_->Accept(&accepted_socket_, base::BindOnce(&HttpServer::OnAcceptCompleted, weak_ptr_factory_.GetWeakPtr())); - if (rv == ERR_IO_PENDING) + DLOG(ERROR) << "HttpServer::DoAcceptLoop, rv = " << rv; + if (rv == ERR_IO_PENDING || rv == ERR_ADDRESS_INVALID) return; rv = HandleAcceptResult(rv); } while (rv == OK); diff --git a/net/socket/socket_descriptor.cc b/net/socket/socket_descriptor.cc index 4880f0ee1b57..649bd77e373a 100644 --- a/net/socket/socket_descriptor.cc +++ b/net/socket/socket_descriptor.cc @@ -6,13 +6,13 @@ #include "build/build_config.h" -#if defined(STARBOARD) +#if defined(STARBOARD) && SB_API_VERSION <= 15 #include "starboard/socket.h" #include "base/notreached.h" #elif BUILDFLAG(IS_WIN) #include #include "net/base/winsock_init.h" -#elif BUILDFLAG(IS_POSIX) || BUILDFLAG(IS_FUCHSIA) +#elif BUILDFLAG(IS_POSIX) || BUILDFLAG(IS_FUCHSIA) || SB_API_VERSION >= 16 #include #include #endif @@ -24,7 +24,7 @@ namespace net { SocketDescriptor CreatePlatformSocket(int family, int type, int protocol) { -#if defined(STARBOARD) +#if defined(STARBOARD) && SB_API_VERSION <= 15 NOTREACHED(); return kSbSocketInvalid; #elif BUILDFLAG(IS_WIN) @@ -40,7 +40,7 @@ SocketDescriptor CreatePlatformSocket(int family, int type, int protocol) { } } return result; -#elif BUILDFLAG(IS_POSIX) || BUILDFLAG(IS_FUCHSIA) +#elif BUILDFLAG(IS_POSIX) || BUILDFLAG(IS_FUCHSIA) || SB_API_VERSION >= 16 SocketDescriptor result = ::socket(family, type, protocol); #if BUILDFLAG(IS_APPLE) // Disable SIGPIPE on this socket. Although Chromium globally disables diff --git a/net/socket/socket_descriptor.h b/net/socket/socket_descriptor.h index 032cb73d5cb1..5e96cbdd8ea6 100644 --- a/net/socket/socket_descriptor.h +++ b/net/socket/socket_descriptor.h @@ -17,12 +17,12 @@ namespace net { -#if defined(STARBOARD) +#if defined(STARBOARD) && SB_API_VERSION <= 15 typedef SbSocket SocketDescriptor; #elif BUILDFLAG(IS_WIN) typedef UINT_PTR SocketDescriptor; const SocketDescriptor kInvalidSocket = (SocketDescriptor)(~0); -#elif BUILDFLAG(IS_POSIX) || BUILDFLAG(IS_FUCHSIA) +#elif BUILDFLAG(IS_POSIX) || BUILDFLAG(IS_FUCHSIA) || SB_API_VERSION >= 16 typedef int SocketDescriptor; const SocketDescriptor kInvalidSocket = -1; #endif diff --git a/net/socket/socket_options.cc b/net/socket/socket_options.cc index 7f23a600a2da..42cc6c25aba9 100644 --- a/net/socket/socket_options.cc +++ b/net/socket/socket_options.cc @@ -9,12 +9,12 @@ #include "build/build_config.h" #include "net/base/net_errors.h" -#if defined(STARBOARD) +#if defined(STARBOARD) && SB_API_VERSION <= 15 #include "base/notreached.h" #elif BUILDFLAG(IS_WIN) #include #include -#elif BUILDFLAG(IS_POSIX) || BUILDFLAG(IS_FUCHSIA) +#elif BUILDFLAG(IS_POSIX) || BUILDFLAG(IS_FUCHSIA) || SB_API_VERSION >= 16 #include #include #include @@ -23,12 +23,13 @@ namespace net { int SetTCPNoDelay(SocketDescriptor fd, bool no_delay) { -#if defined(STARBOARD) +#if defined(STARBOARD) && SB_API_VERSION <= 15 return SbSocketSetTcpNoDelay(fd, no_delay) ? OK : ERR_FAILED; #else + #if BUILDFLAG(IS_WIN) BOOL on = no_delay ? TRUE : FALSE; -#elif BUILDFLAG(IS_POSIX) || BUILDFLAG(IS_FUCHSIA) +#elif BUILDFLAG(IS_POSIX) || BUILDFLAG(IS_FUCHSIA) || SB_API_VERSION >= 16 int on = no_delay ? 1 : 0; #endif int rv = setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, @@ -38,7 +39,7 @@ int SetTCPNoDelay(SocketDescriptor fd, bool no_delay) { } int SetReuseAddr(SocketDescriptor fd, bool reuse) { -#if defined(STARBOARD) +#if defined(STARBOARD) && SB_API_VERSION <= 15 return SbSocketSetReuseAddress(fd, reuse) ? OK : ERR_FAILED; #else // SO_REUSEADDR is useful for server sockets to bind to a recently unbound @@ -56,7 +57,7 @@ int SetReuseAddr(SocketDescriptor fd, bool reuse) { // SO_REUSEPORT is provided in MacOS X and iOS. #if BUILDFLAG(IS_WIN) BOOL boolean_value = reuse ? TRUE : FALSE; -#elif BUILDFLAG(IS_POSIX) || BUILDFLAG(IS_FUCHSIA) +#elif BUILDFLAG(IS_POSIX) || BUILDFLAG(IS_FUCHSIA) || SB_API_VERSION >= 16 int boolean_value = reuse ? 1 : 0; #endif int rv = setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, @@ -67,14 +68,14 @@ int SetReuseAddr(SocketDescriptor fd, bool reuse) { } int SetSocketReceiveBufferSize(SocketDescriptor fd, int32_t size) { -#if defined(STARBOARD) +#if defined(STARBOARD) && SB_API_VERSION <= 15 return SbSocketSetReceiveBufferSize(fd, size) ? OK : ERR_FAILED; #else int rv = setsockopt(fd, SOL_SOCKET, SO_RCVBUF, reinterpret_cast(&size), sizeof(size)); #if BUILDFLAG(IS_WIN) int os_error = WSAGetLastError(); -#elif BUILDFLAG(IS_POSIX) || BUILDFLAG(IS_FUCHSIA) +#elif BUILDFLAG(IS_POSIX) || BUILDFLAG(IS_FUCHSIA) || SB_API_VERSION >= 16 int os_error = errno; #endif int net_error = (rv == -1) ? MapSystemError(os_error) : OK; @@ -86,14 +87,14 @@ int SetSocketReceiveBufferSize(SocketDescriptor fd, int32_t size) { } int SetSocketSendBufferSize(SocketDescriptor fd, int32_t size) { -#if defined(STARBOARD) +#if defined(STARBOARD) && SB_API_VERSION <= 15 return SbSocketSetSendBufferSize(fd, size) ? OK : ERR_FAILED; #else int rv = setsockopt(fd, SOL_SOCKET, SO_SNDBUF, reinterpret_cast(&size), sizeof(size)); #if BUILDFLAG(IS_WIN) int os_error = WSAGetLastError(); -#elif BUILDFLAG(IS_POSIX) || BUILDFLAG(IS_FUCHSIA) +#elif BUILDFLAG(IS_POSIX) || BUILDFLAG(IS_FUCHSIA) || SB_API_VERSION >= 16 int os_error = errno; #endif int net_error = (rv == -1) ? MapSystemError(os_error) : OK; @@ -105,13 +106,13 @@ int SetSocketSendBufferSize(SocketDescriptor fd, int32_t size) { } int SetIPv6Only(SocketDescriptor fd, bool ipv6_only) { -#if defined(STARBOARD) +#if defined(STARBOARD) && SB_API_VERSION <= 15 NOTREACHED(); return -1; #else #if BUILDFLAG(IS_WIN) DWORD on = ipv6_only ? 1 : 0; -#elif BUILDFLAG(IS_POSIX) || BUILDFLAG(IS_FUCHSIA) +#elif BUILDFLAG(IS_POSIX) || BUILDFLAG(IS_FUCHSIA) || SB_API_VERSION >= 16 int on = ipv6_only ? 1 : 0; #endif int rv = setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, diff --git a/net/socket/socket_posix.cc b/net/socket/socket_posix.cc index ea3d794d9858..c1beb02c32cc 100644 --- a/net/socket/socket_posix.cc +++ b/net/socket/socket_posix.cc @@ -33,6 +33,8 @@ namespace net { +#if SB_API_VERSION >= 16 + namespace { int MapAcceptError(int os_error) { @@ -70,9 +72,7 @@ int MapConnectError(int os_error) { SocketPosix::SocketPosix() : socket_fd_(kInvalidSocket), - accept_socket_watcher_(FROM_HERE), - read_socket_watcher_(FROM_HERE), - write_socket_watcher_(FROM_HERE) {} + socket_watcher_(FROM_HERE) {} SocketPosix::~SocketPosix() { Close(); @@ -144,7 +144,7 @@ int SocketPosix::Bind(const SockaddrStorage& address) { int rv = bind(socket_fd_, address.addr, address.addr_len); if (rv < 0) { - PLOG(ERROR) << "bind() failed"; + PLOG(ERROR) << "bind() failed -errno- :" << errno; return MapSystemError(errno); } @@ -179,7 +179,7 @@ int SocketPosix::Accept(std::unique_ptr* socket, if (!base::CurrentIOThread::Get()->WatchFileDescriptor( socket_fd_, true, base::MessagePumpForIO::WATCH_READ, - &accept_socket_watcher_, this)) { + &socket_watcher_, this)) { PLOG(ERROR) << "WatchFileDescriptor failed on accept"; return MapSystemError(errno); } @@ -204,7 +204,7 @@ int SocketPosix::Connect(const SockaddrStorage& address, if (!base::CurrentIOThread::Get()->WatchFileDescriptor( socket_fd_, true, base::MessagePumpForIO::WATCH_WRITE, - &write_socket_watcher_, this)) { + &socket_watcher_, this)) { PLOG(ERROR) << "WatchFileDescriptor failed on connect"; return MapSystemError(errno); } @@ -224,7 +224,7 @@ int SocketPosix::Connect(const SockaddrStorage& address, rv = MapConnectError(errno); if (rv != OK && rv != ERR_IO_PENDING) { - write_socket_watcher_.StopWatchingFileDescriptor(); + ClearWatcherIfOperationsNotPending(); return rv; } @@ -300,7 +300,7 @@ int SocketPosix::ReadIfReady(IOBuffer* buf, if (!base::CurrentIOThread::Get()->WatchFileDescriptor( socket_fd_, true, base::MessagePumpForIO::WATCH_READ, - &read_socket_watcher_, this)) { + &socket_watcher_, this)) { PLOG(ERROR) << "WatchFileDescriptor failed on read"; return MapSystemError(errno); } @@ -312,7 +312,7 @@ int SocketPosix::ReadIfReady(IOBuffer* buf, int SocketPosix::CancelReadIfReady() { DCHECK(read_if_ready_callback_); - bool ok = read_socket_watcher_.StopWatchingFileDescriptor(); + bool ok = ClearWatcherIfOperationsNotPending(); DCHECK(ok); read_if_ready_callback_.Reset(); @@ -350,7 +350,7 @@ int SocketPosix::WaitForWrite(IOBuffer* buf, if (!base::CurrentIOThread::Get()->WatchFileDescriptor( socket_fd_, true, base::MessagePumpForIO::WATCH_WRITE, - &write_socket_watcher_, this)) { + &socket_watcher_, this)) { PLOG(ERROR) << "WatchFileDescriptor failed on write"; return MapSystemError(errno); } @@ -414,8 +414,7 @@ void SocketPosix::OnFileCanReadWithoutBlocking(int fd) { "SocketPosix::OnFileCanReadWithoutBlocking"); if (!accept_callback_.is_null()) { AcceptCompleted(); - } else { - DCHECK(!read_if_ready_callback_.is_null()); + } else if (!read_if_ready_callback_.is_null()){ ReadCompleted(); } } @@ -449,10 +448,10 @@ int SocketPosix::DoAccept(std::unique_ptr* socket) { void SocketPosix::AcceptCompleted() { DCHECK(accept_socket_); int rv = DoAccept(accept_socket_); - if (rv == ERR_IO_PENDING) + if (rv == ERR_IO_PENDING || rv == ERR_ADDRESS_INVALID) return; - bool ok = accept_socket_watcher_.StopWatchingFileDescriptor(); + bool ok = ClearWatcherIfOperationsNotPending(); DCHECK(ok); accept_socket_ = nullptr; std::move(accept_callback_).Run(rv); @@ -479,14 +478,14 @@ void SocketPosix::ConnectCompleted() { if (rv == ERR_IO_PENDING) return; - bool ok = write_socket_watcher_.StopWatchingFileDescriptor(); + bool ok = socket_watcher_.StopWatchingFileDescriptor(); DCHECK(ok); waiting_connect_ = false; std::move(write_callback_).Run(rv); } int SocketPosix::DoRead(IOBuffer* buf, int buf_len) { - int rv = HANDLE_EINTR(read(socket_fd_, buf->data(), buf_len)); + int rv = HANDLE_EINTR(recv(socket_fd_, buf->data(), buf_len, 0)); return rv >= 0 ? rv : MapSystemError(errno); } @@ -510,21 +509,28 @@ void SocketPosix::RetryRead(int rv) { void SocketPosix::ReadCompleted() { DCHECK(read_if_ready_callback_); - bool ok = read_socket_watcher_.StopWatchingFileDescriptor(); + bool ok = socket_watcher_.StopWatchingFileDescriptor(); DCHECK(ok); std::move(read_if_ready_callback_).Run(OK); } int SocketPosix::DoWrite(IOBuffer* buf, int buf_len) { -#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_ANDROID) +#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_ANDROID) ||\ + defined(STARBOARD) // Disable SIGPIPE for this write. Although Chromium globally disables // SIGPIPE, the net stack may be used in other consumers which do not do // this. MSG_NOSIGNAL is a Linux-only API. On OS X, this is a setsockopt on // socket creation. - int rv = HANDLE_EINTR(send(socket_fd_, buf->data(), buf_len, MSG_NOSIGNAL)); +#if defined(MSG_NOSIGNAL) + const int kSendFlags = MSG_NOSIGNAL; +#else + const int kSendFlags = 0; +#endif // defined(MSG_NOSIGNAL) + int rv = HANDLE_EINTR(send(socket_fd_, buf->data(), buf_len, kSendFlags)); #else int rv = HANDLE_EINTR(write(socket_fd_, buf->data(), buf_len)); -#endif +#endif // BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_ANDROID) ||\ + // defined(STARBOARD) return rv >= 0 ? rv : MapSystemError(errno); } @@ -533,19 +539,23 @@ void SocketPosix::WriteCompleted() { if (rv == ERR_IO_PENDING) return; - bool ok = write_socket_watcher_.StopWatchingFileDescriptor(); + bool ok = ClearWatcherIfOperationsNotPending(); DCHECK(ok); write_buf_.reset(); write_buf_len_ = 0; std::move(write_callback_).Run(rv); } +bool SocketPosix::ClearWatcherIfOperationsNotPending() { + bool ok = true; + if (!read_pending() && !write_pending() && !accept_pending()) { + ok = socket_watcher_.StopWatchingFileDescriptor(); + } + return ok; +} + void SocketPosix::StopWatchingAndCleanUp(bool close_socket) { - bool ok = accept_socket_watcher_.StopWatchingFileDescriptor(); - DCHECK(ok); - ok = read_socket_watcher_.StopWatchingFileDescriptor(); - DCHECK(ok); - ok = write_socket_watcher_.StopWatchingFileDescriptor(); + bool ok = socket_watcher_.StopWatchingFileDescriptor(); DCHECK(ok); // These needs to be done after the StopWatchingFileDescriptor() calls, but @@ -581,4 +591,6 @@ void SocketPosix::StopWatchingAndCleanUp(bool close_socket) { peer_address_.reset(); } +#endif // SB_API_VERSION >= 16 + } // namespace net diff --git a/net/socket/socket_posix.h b/net/socket/socket_posix.h index f7155cab06ec..36a7bfeb5396 100644 --- a/net/socket/socket_posix.h +++ b/net/socket/socket_posix.h @@ -19,13 +19,15 @@ namespace net { +#if SB_API_VERSION >= 16 + class IOBuffer; struct SockaddrStorage; // Socket class to provide asynchronous read/write operations on top of the // posix socket api. It supports AF_INET, AF_INET6, and AF_UNIX addresses. class NET_EXPORT_PRIVATE SocketPosix - : public base::MessagePumpForIO::FdWatcher { + : public base::MessagePumpForIO::Watcher { public: SocketPosix(); @@ -107,7 +109,7 @@ class NET_EXPORT_PRIVATE SocketPosix SocketDescriptor socket_fd() const { return socket_fd_; } private: - // base::MessagePumpForIO::FdWatcher methods. + // base::MessagePumpForIO::Watcher methods. void OnFileCanReadWithoutBlocking(int fd) override; void OnFileCanWriteWithoutBlocking(int fd) override; @@ -124,17 +126,22 @@ class NET_EXPORT_PRIVATE SocketPosix int DoWrite(IOBuffer* buf, int buf_len); void WriteCompleted(); + bool read_pending() const { return !read_if_ready_callback_.is_null(); } + bool write_pending() const { + return !write_callback_.is_null() && !waiting_connect_; + } + bool accept_pending() const { return !accept_callback_.is_null(); } + + bool ClearWatcherIfOperationsNotPending(); + // |close_socket| indicates whether the socket should also be closed. void StopWatchingAndCleanUp(bool close_socket); SocketDescriptor socket_fd_; - base::MessagePumpForIO::FdWatchController accept_socket_watcher_; raw_ptr> accept_socket_; CompletionOnceCallback accept_callback_; - base::MessagePumpForIO::FdWatchController read_socket_watcher_; - // Non-null when a Read() is in progress. scoped_refptr read_buf_; int read_buf_len_ = 0; @@ -143,7 +150,7 @@ class NET_EXPORT_PRIVATE SocketPosix // Non-null when a ReadIfReady() is in progress. CompletionOnceCallback read_if_ready_callback_; - base::MessagePumpForIO::FdWatchController write_socket_watcher_; + base::MessagePumpForIO::SocketWatcher socket_watcher_; scoped_refptr write_buf_; int write_buf_len_ = 0; // External callback; called when write or connect is complete. @@ -158,6 +165,8 @@ class NET_EXPORT_PRIVATE SocketPosix base::ThreadChecker thread_checker_; }; +#endif // SB_API_VERSION >= 16 + } // namespace net #endif // NET_SOCKET_SOCKET_POSIX_H_ diff --git a/net/socket/tcp_socket.h b/net/socket/tcp_socket.h index 19cfc74ea910..708df595e0f1 100644 --- a/net/socket/tcp_socket.h +++ b/net/socket/tcp_socket.h @@ -9,11 +9,11 @@ #include "net/base/net_export.h" #include "net/socket/socket_descriptor.h" -#if defined(STARBOARD) +#if defined(STARBOARD) && SB_API_VERSION <= 15 #include "net/socket/tcp_socket_starboard.h" #elif BUILDFLAG(IS_WIN) #include "net/socket/tcp_socket_win.h" -#elif BUILDFLAG(IS_POSIX) || BUILDFLAG(IS_FUCHSIA) +#elif BUILDFLAG(IS_POSIX) || BUILDFLAG(IS_FUCHSIA) || SB_API_VERSION >= 16 #include "net/socket/tcp_socket_posix.h" #endif @@ -25,11 +25,11 @@ namespace net { // class, unless a clear separation of client and server socket functionality is // not suitable for your use case (e.g., a socket needs to be created and bound // before you know whether it is a client or server socket). -#if defined(STARBOARD) +#if defined(STARBOARD) && SB_API_VERSION <= 15 typedef TCPSocketStarboard TCPSocket; #elif BUILDFLAG(IS_WIN) typedef TCPSocketWin TCPSocket; -#elif BUILDFLAG(IS_POSIX) || BUILDFLAG(IS_FUCHSIA) +#elif BUILDFLAG(IS_POSIX) || BUILDFLAG(IS_FUCHSIA) || SB_API_VERSION >= 16 typedef TCPSocketPosix TCPSocket; #endif diff --git a/net/socket/tcp_socket_posix.cc b/net/socket/tcp_socket_posix.cc index 73d002d44281..cc5cba13ef00 100644 --- a/net/socket/tcp_socket_posix.cc +++ b/net/socket/tcp_socket_posix.cc @@ -62,6 +62,8 @@ namespace net { +#if SB_API_VERSION >= 16 + namespace { // SetTCPKeepAlive sets SO_KEEPALIVE. @@ -249,10 +251,14 @@ int TCPSocketPosix::Listen(int backlog) { int TCPSocketPosix::Accept(std::unique_ptr* tcp_socket, IPEndPoint* address, CompletionOnceCallback callback) { - DCHECK(tcp_socket); + /*DCHECK(tcp_socket); DCHECK(!callback.is_null()); DCHECK(socket_); - DCHECK(!accept_socket_); + DCHECK(!accept_socket_);*/ + + if (address->GetFamily() == ADDRESS_FAMILY_IPV6) { + return ERR_ADDRESS_INVALID; + } net_log_.BeginEvent(NetLogEventType::TCP_ACCEPT); @@ -711,4 +717,6 @@ bool TCPSocketPosix::GetEstimatedRoundTripTime(base::TimeDelta* out_rtt) const { #endif // defined(TCP_INFO) } +#endif // SB_API_VERSION >= 16 + } // namespace net diff --git a/net/socket/tcp_socket_posix.h b/net/socket/tcp_socket_posix.h index b1798a0494d2..a84cf61eb469 100644 --- a/net/socket/tcp_socket_posix.h +++ b/net/socket/tcp_socket_posix.h @@ -26,6 +26,8 @@ class TimeDelta; namespace net { +#if SB_API_VERSION >= 16 + class AddressList; class IOBuffer; class IPEndPoint; @@ -227,6 +229,8 @@ class NET_EXPORT TCPSocketPosix { SocketTag tag_; }; +#endif // SB_API_VERSION >= 16 + } // namespace net #endif // NET_SOCKET_TCP_SOCKET_POSIX_H_ diff --git a/net/socket/tcp_socket_starboard.cc b/net/socket/tcp_socket_starboard.cc index e87f81520d6a..f8458be61aad 100644 --- a/net/socket/tcp_socket_starboard.cc +++ b/net/socket/tcp_socket_starboard.cc @@ -28,6 +28,8 @@ namespace net { +#if SB_API_VERSION <= 15 + TCPSocketStarboard::TCPSocketStarboard( std::unique_ptr socket_performance_watcher, NetLog* net_log, @@ -683,4 +685,6 @@ int TCPSocketStarboard::SetIPv6Only(bool ipv6_only) { return 0; } +#endif // SB_API_VERSION <= 15 + } // namespace net diff --git a/net/socket/tcp_socket_starboard.h b/net/socket/tcp_socket_starboard.h index 876dac02d8a5..329a5d0f278d 100644 --- a/net/socket/tcp_socket_starboard.h +++ b/net/socket/tcp_socket_starboard.h @@ -33,6 +33,8 @@ namespace net { +#if SB_API_VERSION <= 15 + class NET_EXPORT TCPSocketStarboard : public base::MessagePumpIOStarboard::Watcher { public: TCPSocketStarboard( @@ -213,6 +215,8 @@ class NET_EXPORT TCPSocketStarboard : public base::MessagePumpIOStarboard::Watch // DISALLOW_COPY_AND_ASSIGN(TCPSocketStarboard); }; +#endif // SB_API_VERSION <= 15 + } // namespace net #endif // NET_SOCKET_TCP_SOCKET_STARBOARD_H_ diff --git a/net/socket/transport_client_socket_unittest.cc b/net/socket/transport_client_socket_unittest.cc index 4b24198eb23b..a60a9af4f73c 100644 --- a/net/socket/transport_client_socket_unittest.cc +++ b/net/socket/transport_client_socket_unittest.cc @@ -295,7 +295,6 @@ TEST_F(TransportClientSocketTest, FullDuplex_ReadFirst) { // At this point, both read and write have returned ERR_IO_PENDING, and the // write callback has executed. We wait for the read callback to run now to // make sure that the socket can handle full duplex communications. - rv = callback.WaitForResult(); EXPECT_GE(rv, 0); } @@ -317,7 +316,6 @@ TEST_F(TransportClientSocketTest, FullDuplex_WriteFirst) { sock_->Write(request_buffer.get(), kWriteBufLen, write_callback.callback(), TRAFFIC_ANNOTATION_FOR_TESTS); ASSERT_TRUE(rv >= 0 || rv == ERR_IO_PENDING); - if (rv == ERR_IO_PENDING) break; bytes_written += rv; diff --git a/net/socket/udp_socket.h b/net/socket/udp_socket.h index e7b897f09ec2..f57366dab4e5 100644 --- a/net/socket/udp_socket.h +++ b/net/socket/udp_socket.h @@ -7,11 +7,11 @@ #include "build/build_config.h" -#if defined(STARBOARD) +#if defined(STARBOARD) && SB_API_VERSION <= 15 #include "net/socket/udp_socket_starboard.h" #elif BUILDFLAG(IS_WIN) #include "net/socket/udp_socket_win.h" -#elif BUILDFLAG(IS_POSIX) || BUILDFLAG(IS_FUCHSIA) +#elif BUILDFLAG(IS_POSIX) || BUILDFLAG(IS_FUCHSIA) || SB_API_VERSION >= 16 #include "net/socket/udp_socket_posix.h" #endif @@ -37,11 +37,11 @@ namespace net { // RecvFrom/SendTo // Each read can come from a different client // // Writes need to be directed to a specific // // address. -#if defined(STARBOARD) +#if defined(STARBOARD) && SB_API_VERSION <= 15 typedef UDPSocketStarboard UDPSocket; #elif BUILDFLAG(IS_WIN) typedef UDPSocketWin UDPSocket; -#elif BUILDFLAG(IS_POSIX) || BUILDFLAG(IS_FUCHSIA) +#elif BUILDFLAG(IS_POSIX) || BUILDFLAG(IS_FUCHSIA) || SB_API_VERSION >= 16 typedef UDPSocketPosix UDPSocket; #endif diff --git a/net/socket/udp_socket_posix.cc b/net/socket/udp_socket_posix.cc index d7fe60ca6b77..662235c633c1 100644 --- a/net/socket/udp_socket_posix.cc +++ b/net/socket/udp_socket_posix.cc @@ -14,10 +14,8 @@ #include #include -#include #include #include -#include #include #include @@ -66,6 +64,8 @@ namespace net { +#if SB_API_VERSION >= 16 + namespace { const int kBindRetries = 10; @@ -575,13 +575,13 @@ int UDPSocketPosix::SetDoNotFragment() { } void UDPSocketPosix::SetMsgConfirm(bool confirm) { -#if !BUILDFLAG(IS_APPLE) +#if !BUILDFLAG(IS_APPLE) && defined(MSG_CONFIRM) if (confirm) { sendto_flags_ |= MSG_CONFIRM; } else { sendto_flags_ &= ~MSG_CONFIRM; } -#endif // !BUILDFLAG(IS_APPLE) +#endif // !BUILDFLAG(IS_APPLE) && defined(MSG_CONFIRM) } int UDPSocketPosix::AllowAddressReuse() { @@ -779,31 +779,23 @@ int UDPSocketPosix::InternalRecvFromNonConnectedSocket(IOBuffer* buf, int buf_len, IPEndPoint* address) { SockaddrStorage storage; - struct iovec iov = { - .iov_base = buf->data(), - .iov_len = static_cast(buf_len), - }; - struct msghdr msg = { - .msg_name = storage.addr, - .msg_namelen = storage.addr_len, - .msg_iov = &iov, - .msg_iovlen = 1, - }; - int result; - int bytes_transferred = HANDLE_EINTR(recvmsg(socket_, &msg, 0)); + int result = -1; + int bytes_transferred = -1; + bytes_transferred = HANDLE_EINTR(recvfrom(socket_, buf->data(), static_cast(buf_len), + 0, storage.addr, &storage.addr_len)); if (bytes_transferred < 0) { result = MapSystemError(errno); if (result == ERR_IO_PENDING) { return result; } } else { - storage.addr_len = msg.msg_namelen; - if (msg.msg_flags & MSG_TRUNC) { + if (bytes_transferred == buf_len) { // NB: recvfrom(..., MSG_TRUNC, ...) would be a simpler way to do this on // Linux, but isn't supported by POSIX. + // When received data size == buffer size, it means the buffer isn't big enough, + // i.e. truncated. result = ERR_MSG_TOO_BIG; - } else if (address && - !address->FromSockAddr(storage.addr, storage.addr_len)) { + } else if (address && !address->FromSockAddr(storage.addr, storage.addr_len)) { result = ERR_ADDRESS_INVALID; } else { result = bytes_transferred; @@ -854,7 +846,11 @@ int UDPSocketPosix::SetMulticastOptions() { if (rv < 0) return MapSystemError(errno); } +#if defined(IP_DEFAULT_MULTICAST_TTL) if (multicast_time_to_live_ != IP_DEFAULT_MULTICAST_TTL) { +#elif defined(IP_MULTICAST_TTL) + if (multicast_time_to_live_ != IP_MULTICAST_TTL) { +#endif int rv; if (addr_family_ == AF_INET) { u_char ttl = multicast_time_to_live_; @@ -1096,4 +1092,6 @@ int UDPSocketPosix::SetIOSNetworkServiceType(int ios_network_service_type) { return OK; } +#endif // SB_API_VERSION >= 16 + } // namespace net diff --git a/net/socket/udp_socket_posix.h b/net/socket/udp_socket_posix.h index ed9c7549c1fc..44994e51ab0b 100644 --- a/net/socket/udp_socket_posix.h +++ b/net/socket/udp_socket_posix.h @@ -33,6 +33,8 @@ namespace net { +#if SB_API_VERSION >= 16 + class IPAddress; class NetLog; struct NetLogSource; @@ -285,7 +287,7 @@ class NET_EXPORT UDPSocketPosix { SOCKET_OPTION_MULTICAST_LOOP = 1 << 0 }; - class ReadWatcher : public base::MessagePumpForIO::FdWatcher { + class ReadWatcher : public base::MessagePumpForIO::Watcher { public: explicit ReadWatcher(UDPSocketPosix* socket) : socket_(socket) {} @@ -302,7 +304,7 @@ class NET_EXPORT UDPSocketPosix { const raw_ptr socket_; }; - class WriteWatcher : public base::MessagePumpForIO::FdWatcher { + class WriteWatcher : public base::MessagePumpForIO::Watcher { public: explicit WriteWatcher(UDPSocketPosix* socket) : socket_(socket) {} @@ -410,8 +412,8 @@ class NET_EXPORT UDPSocketPosix { mutable std::unique_ptr remote_address_; // The socket's posix wrappers - base::MessagePumpForIO::FdWatchController read_socket_watcher_; - base::MessagePumpForIO::FdWatchController write_socket_watcher_; + base::MessagePumpForIO::SocketWatcher read_socket_watcher_; + base::MessagePumpForIO::SocketWatcher write_socket_watcher_; // The corresponding watchers for reads and writes. ReadWatcher read_watcher_; @@ -465,6 +467,8 @@ class NET_EXPORT UDPSocketPosix { THREAD_CHECKER(thread_checker_); }; +#endif // SB_API_VERSION >= 16 + } // namespace net #endif // NET_SOCKET_UDP_SOCKET_POSIX_H_ diff --git a/net/socket/udp_socket_starboard.cc b/net/socket/udp_socket_starboard.cc index 7e51b873276a..89218e62b0bc 100644 --- a/net/socket/udp_socket_starboard.cc +++ b/net/socket/udp_socket_starboard.cc @@ -35,6 +35,8 @@ namespace net { +#if SB_API_VERSION <= 15 + UDPSocketStarboard::UDPSocketStarboard(DatagramSocket::BindType bind_type, net::NetLog* net_log, const net::NetLogSource& source) @@ -900,4 +902,6 @@ int UDPSocketStarboard::ResetWrittenBytes() { return bytes; } +#endif // SB_API_VERSION <= 15 + } // namespace net diff --git a/net/socket/udp_socket_starboard.h b/net/socket/udp_socket_starboard.h index 905964eccc67..cb8101670e67 100644 --- a/net/socket/udp_socket_starboard.h +++ b/net/socket/udp_socket_starboard.h @@ -42,6 +42,8 @@ namespace net { +#if SB_API_VERSION <= 15 + // Sendresult is inspired by sendmmsg, but unlike sendmmsg it is not // convenient to require that a positive |write_count| and a negative // error code are mutually exclusive. @@ -491,6 +493,8 @@ class NET_EXPORT UDPSocketStarboard // DISALLOW_COPY_AND_ASSIGN(UDPSocketStarboard); }; +#endif // SB_API_VERSION <= 15 + } // namespace net #endif // NET_SOCKET_UDP_SOCKET_STARBOARD_H_ diff --git a/net/socket/udp_socket_unittest.cc b/net/socket/udp_socket_unittest.cc index 78d4ae4a9510..8897483206f8 100644 --- a/net/socket/udp_socket_unittest.cc +++ b/net/socket/udp_socket_unittest.cc @@ -592,7 +592,8 @@ TEST_F(UDPSocketTest, ClientGetLocalPeerAddresses) { UDPClientSocket client(DatagramSocket::DEFAULT_BIND, nullptr, NetLogSource()); int rv = client.Connect(remote_address); - if (test.may_fail && rv == ERR_ADDRESS_UNREACHABLE) { + if (test.may_fail && + (rv == ERR_ADDRESS_UNREACHABLE || rv == ERR_ADDRESS_INVALID)) { // Connect() may return ERR_ADDRESS_UNREACHABLE for IPv6 // addresses if IPv6 is not configured. continue; diff --git a/starboard/elf_loader/exported_symbols.cc b/starboard/elf_loader/exported_symbols.cc index e073e8641e85..205c1cd337ce 100644 --- a/starboard/elf_loader/exported_symbols.cc +++ b/starboard/elf_loader/exported_symbols.cc @@ -483,7 +483,9 @@ ExportedSymbols::ExportedSymbols() { REGISTER_SYMBOL(ftruncate); REGISTER_SYMBOL(getaddrinfo); REGISTER_SYMBOL(getifaddrs); + REGISTER_SYMBOL(getpeername); REGISTER_SYMBOL(getsockname); + REGISTER_SYMBOL(getsockopt); REGISTER_SYMBOL(listen); REGISTER_SYMBOL(lseek); REGISTER_SYMBOL(malloc); @@ -498,10 +500,10 @@ ExportedSymbols::ExportedSymbols() { REGISTER_SYMBOL(readdir_r); REGISTER_SYMBOL(realloc); REGISTER_SYMBOL(recv); - REGISTER_SYMBOL(send); REGISTER_SYMBOL(recvfrom); REGISTER_SYMBOL(rmdir); REGISTER_SYMBOL(sched_yield); + REGISTER_SYMBOL(send); REGISTER_SYMBOL(sendto); REGISTER_SYMBOL(setsockopt); REGISTER_SYMBOL(socket); diff --git a/starboard/shared/win32/posix_emu/include/sys/socket.h b/starboard/shared/win32/posix_emu/include/sys/socket.h index f92181e0aaa8..2474b79621bb 100644 --- a/starboard/shared/win32/posix_emu/include/sys/socket.h +++ b/starboard/shared/win32/posix_emu/include/sys/socket.h @@ -25,6 +25,22 @@ extern "C" { #endif +struct msghdr { + void* msg_name; /* Optional address */ + socklen_t msg_namelen; /* Size of address */ + struct iovec* msg_iov; /* Scatter/gather array */ + size_t msg_iovlen; /* # elements in msg_iov */ + void* msg_control; /* Ancillary data, see below */ + size_t msg_controllen; /* Ancillary data buffer len */ + int msg_flags; /* Flags (unused) */ +}; + +struct ip_mreqn { + struct in_addr imr_multiaddr; /* IP multicast group address */ + struct in_addr imr_address; /* IP address of local interface */ + int imr_ifindex; /* interface index */ +}; + int sb_socket(int domain, int type, int protocol); #define socket sb_socket @@ -62,6 +78,13 @@ int sb_recvfrom(int sockfd, socklen_t* address_len); #define recvfrom sb_recvfrom +int sb_getsockopt(int socket, + int level, + int option_name, + void* option_value, + int* option_len); +#define getsockopt sb_getsockopt + int sb_setsockopt(int socket, int level, int option_name, diff --git a/starboard/shared/win32/posix_emu/include/sys/un.h b/starboard/shared/win32/posix_emu/include/sys/un.h new file mode 100644 index 000000000000..29038769d31c --- /dev/null +++ b/starboard/shared/win32/posix_emu/include/sys/un.h @@ -0,0 +1,33 @@ +// Copyright 2024 The Cobalt Authors. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef STARBOARD_SHARED_WIN32_POSIX_EMU_INCLUDE_SYS_UN_H_ +#define STARBOARD_SHARED_WIN32_POSIX_EMU_INCLUDE_SYS_UN_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +typedef unsigned int sa_family_t; + +struct sockaddr_un { + sa_family_t sun_family; /* AF_UNIX */ + char sun_path[108]; /* Pathname */ +}; + +#ifdef __cplusplus +} +#endif + +#endif // STARBOARD_SHARED_WIN32_POSIX_EMU_INCLUDE_SYS_UN_H_ diff --git a/starboard/shared/win32/posix_emu/socket.cc b/starboard/shared/win32/posix_emu/socket.cc index c8a8dba2ed81..3ac7a74d3ea3 100644 --- a/starboard/shared/win32/posix_emu/socket.cc +++ b/starboard/shared/win32/posix_emu/socket.cc @@ -241,7 +241,7 @@ static void set_errno() { sockError = NO_DATA; break; default: - SB_DLOG(WARNING) << "Unknown socket error."; + SB_DLOG(WARNING) << "Unknown socket error - " << winsockError; break; } @@ -478,6 +478,25 @@ int sb_recvfrom(int sockfd, return result; } +int sb_getsockopt(int socket, + int level, + int option_name, + void* option_value, + int* option_len) { + FileOrSocket handle = handle_db_get(socket, false); + + if (handle.is_file || handle.socket == INVALID_SOCKET) { + return -1; + } + + int result = getsockopt(handle.socket, level, option_name, + reinterpret_cast(option_value), option_len); + if (result == SOCKET_ERROR) { + set_errno(); + } + return result; +} + int sb_setsockopt(int socket, int level, int option_name, diff --git a/starboard/tools/api_leak_detector/api_leak_detector.py b/starboard/tools/api_leak_detector/api_leak_detector.py index ab667b620b77..b662ba988ff7 100755 --- a/starboard/tools/api_leak_detector/api_leak_detector.py +++ b/starboard/tools/api_leak_detector/api_leak_detector.py @@ -94,6 +94,7 @@ 'connect', 'clock_gettime', 'close', + 'fcntl', 'free', 'freeifaddrs', 'freeaddrinfo', @@ -103,6 +104,9 @@ 'gettimeofday', 'getifaddrs', 'getaddrinfo', + 'getpeername', + 'getsockname', + 'getsockopt', 'gmtime_r', 'inet_ntop', 'listen',