From 1a6e0ef42e9ca32a646cdbd104028032a722f34b Mon Sep 17 00:00:00 2001 From: Vitalii Ganzha Date: Tue, 17 Oct 2023 09:49:11 -0700 Subject: [PATCH] Update FlipperPlugin C++ code so it can be compiled for Windows Summary: I am working in Horizon Worlds and I would like to integrate Flipper with HzW app. Currently FlipperPlugin C++ code won't compile on Windows since it uses Linux-only headers like `netdb.h` and `sys/fcntl.h`, I posted here and looks like it is not currently supported: https://fb.workplace.com/groups/flippersupport/posts/1704837183330266 The problem seem to be in only in `FlipperConnectionEndpointVerifier.cpp`, and I'm updating it to make it compatible with Windows. Also apparently there's some issue with `#include` of few files and namespaces, leading to "struct redefinition" errors where `#pragma once` does not help https://fb.workplace.com/groups/474291069286180/posts/25313067014981908/ Solving it with manual #define Reviewed By: lblasa Differential Revision: D50337573 fbshipit-source-id: affdf1aee2b9dfe615227827fedf324a5f17d8b0 --- .../FlipperConnectionEndpointVerifier.cpp | 47 +++++++++++++++++-- xplat/Flipper/FlipperScheduler.h | 3 ++ xplat/Flipper/FlipperSocketProvider.h | 3 ++ 3 files changed, 50 insertions(+), 3 deletions(-) diff --git a/xplat/Flipper/FlipperConnectionEndpointVerifier.cpp b/xplat/Flipper/FlipperConnectionEndpointVerifier.cpp index 02211592a..fec09a065 100644 --- a/xplat/Flipper/FlipperConnectionEndpointVerifier.cpp +++ b/xplat/Flipper/FlipperConnectionEndpointVerifier.cpp @@ -6,16 +6,57 @@ */ #include "FlipperConnectionEndpointVerifier.h" -#include #include + +#ifdef _MSC_VER /* MSVC */ + +#include +#include +#define getsockopt(a, b, c, d, e) getsockopt(a, b, c, (char*)d, e) +typedef int socklen_t; + +#else /* !_WIN32 */ + +#include #include #include #include +using SOCKET = int; +#endif + #include namespace facebook { namespace flipper { +static bool setSocketNonBlocking(SOCKET socket) { +#ifndef _WIN32 + int flags = fcntl(socket, F_GETFL, 0); + if (flags < 0) { + return false; + } + return (fcntl(socket, F_SETFL, flags | O_NONBLOCK) == 0); +#else + // If nonBlocking = 0, blocking is enabled; + // If nonBlocking != 0, non-blocking mode is enabled. + u_long nonBlocking = 1; + int32_t nonBlockResult = ioctlsocket(socket, FIONBIO, &nonBlocking); + if (nonBlockResult != 0) { + return false; + } else { + return true; + } +#endif +} + +static void closeSocket(SOCKET socket) { +#ifndef _WIN32 + close(socket); +#else + closesocket(socket); +#endif +} + bool ConnectionEndpointVerifier::verify(const std::string& host, int port) { auto sport = std::to_string(port); @@ -31,7 +72,7 @@ bool ConnectionEndpointVerifier::verify(const std::string& host, int port) { int sfd = socket(address->ai_family, address->ai_socktype, address->ai_protocol); - fcntl(sfd, F_SETFL, O_NONBLOCK); + setSocketNonBlocking(sfd); connect(sfd, address->ai_addr, address->ai_addrlen); fd_set fdset; @@ -58,7 +99,7 @@ bool ConnectionEndpointVerifier::verify(const std::string& host, int port) { } freeaddrinfo(address); - close(sfd); + closeSocket(sfd); return listening; } diff --git a/xplat/Flipper/FlipperScheduler.h b/xplat/Flipper/FlipperScheduler.h index a8b2f545a..473ee9085 100644 --- a/xplat/Flipper/FlipperScheduler.h +++ b/xplat/Flipper/FlipperScheduler.h @@ -6,6 +6,8 @@ */ #pragma once +#ifndef _FLIPPERSCHEDULER_H_ +#define _FLIPPERSCHEDULER_H_ #include @@ -24,3 +26,4 @@ struct Scheduler { } // namespace flipper } // namespace facebook +#endif diff --git a/xplat/Flipper/FlipperSocketProvider.h b/xplat/Flipper/FlipperSocketProvider.h index 99c6e9bff..ba622e3c0 100644 --- a/xplat/Flipper/FlipperSocketProvider.h +++ b/xplat/Flipper/FlipperSocketProvider.h @@ -6,6 +6,8 @@ */ #pragma once +#ifndef _FLIPPERSOCKETPROVIDER_H_ +#define _FLIPPERSOCKETPROVIDER_H_ #include #include "FlipperScheduler.h" @@ -76,3 +78,4 @@ class FlipperSocketProvider { } // namespace flipper } // namespace facebook +#endif