config_host.mk.in                              |    1 
 config_host/config_emscripten.h.in             |   14 ++++++++
 configure.ac                                   |   18 +++++++++++
 desktop/source/app/app.cxx                     |   39 +++++++++++++++++++++++++
 external/curl/ExternalProject_curl.mk          |    1 
 external/curl/UnpackedTarball_curl.mk          |    6 +++
 external/curl/emscripten-proxy-poll.patch.0    |   20 ++++++++++++
 solenv/gbuild/platform/EMSCRIPTEN_INTEL_GCC.mk |    4 ++
 8 files changed, 103 insertions(+)

New commits:
commit 2d9f8f45be0c9bc5f56864f66a37c3cc60069fe5
Author:     Stephan Bergmann <[email protected]>
AuthorDate: Thu Aug 22 11:49:08 2024 +0200
Commit:     Stephan Bergmann <[email protected]>
CommitDate: Thu Aug 22 14:24:35 2024 +0200

    Emscripten: Experimental -sPROXY_POSIX_SOCKETS support
    
    ...see
    
<https://emscripten.org/docs/porting/networking.html#full-posix-sockets-over-websocket-proxy-server>.
    
    This requires
    
<https://github.com/stbergmann/emscripten/commit/4aff1f28b88480791236adcc6d5cb2d919ad4bf3>
    "-sPROXY_POSIX_SOCKETS: Add websocket_proxy_poll".  When configured with
    --disable-socketpair (which appears to have no negative consequences),
    external/curl appears to only call poll(2) with socket-related file 
descriptors,
    so we can use websocket_proxy_poll instead.
    
    The URL on which the websocket_to_posix_proxy process listens must be 
specified
    as Module.uno_websocket_to_posix_socket_url.
    
    Change-Id: I4ad23098b5bbc0646fa50859c0aeb9870d1cc92a
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/172243
    Reviewed-by: Stephan Bergmann <[email protected]>
    Tested-by: Jenkins

diff --git a/config_host.mk.in b/config_host.mk.in
index 15b1c2b74e9a..810abab5f4ca 100644
--- a/config_host.mk.in
+++ b/config_host.mk.in
@@ -175,6 +175,7 @@ export ENABLE_DEBUG=@ENABLE_DEBUG@
 ENABLE_DOTNET=@ENABLE_DOTNET@
 SYSTEM_DRAGONBOX=@SYSTEM_DRAGONBOX@
 SYSTEM_FROZEN=@SYSTEM_FROZEN@
+export 
ENABLE_EMSCRIPTEN_PROXY_POSIX_SOCKETS=@ENABLE_EMSCRIPTEN_PROXY_POSIX_SOCKETS@
 export ENABLE_EPOXY=@ENABLE_EPOXY@
 export ENABLE_EOT=@ENABLE_EOT@
 export ENABLE_EVOAB2=@ENABLE_EVOAB2@
diff --git a/config_host/config_emscripten.h.in 
b/config_host/config_emscripten.h.in
new file mode 100644
index 000000000000..24d1a9ca5dd8
--- /dev/null
+++ b/config_host/config_emscripten.h.in
@@ -0,0 +1,14 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; 
fill-column: 100 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#pragma once
+
+#define HAVE_EMSCRIPTEN_PROXY_POSIX_SOCKETS 0
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s 
cinkeys+=0=break: */
diff --git a/configure.ac b/configure.ac
index 2c11703cb3ff..f0fb5765abc9 100644
--- a/configure.ac
+++ b/configure.ac
@@ -2166,6 +2166,15 @@ AC_ARG_WITH(main-module,
         Default value is 'writer'.]),
 ,)
 
+if test "$_os" = Emscripten; then
+    AC_ARG_ENABLE(emscripten-proxy-posix-sockets,
+        AS_HELP_STRING([--enable-emscripten-proxy-posix-sockets],
+            [Enable experimental Emscripten support for full POSIX sockets 
over WebSocket proxy
+             server (-sPROXY_POSIX_SOCKETS).]))
+else
+    enable_emscripten_proxy_posix_sockets=
+fi
+
 AC_ARG_ENABLE(xmlhelp,
     AS_HELP_STRING([--disable-xmlhelp],
         [Disable XML help support]),
@@ -4238,6 +4247,14 @@ AC_SUBST(ENABLE_WASM_STRIP)
 AC_SUBST(ENABLE_WASM_STRIP_WRITER)
 AC_SUBST(ENABLE_WASM_STRIP_CALC)
 
+if test "$enable_emscripten_proxy_posix_sockets" = yes; then
+    ENABLE_EMSCRIPTEN_PROXY_POSIX_SOCKETS=TRUE
+    AC_DEFINE(HAVE_EMSCRIPTEN_PROXY_POSIX_SOCKETS)
+else
+    ENABLE_EMSCRIPTEN_PROXY_POSIX_SOCKETS=
+fi
+AC_SUBST(ENABLE_EMSCRIPTEN_PROXY_POSIX_SOCKETS)
+
 # Use -isystem (gcc) if possible, to avoid warnings in 3rd party headers.
 # NOTE: must _not_ be used for bundled external libraries!
 ISYSTEM=
@@ -15697,6 +15714,7 @@ AC_CONFIG_HEADERS([config_host/config_cairo_canvas.h])
 AC_CONFIG_HEADERS([config_host/config_cairo_rgba.h])
 AC_CONFIG_HEADERS([config_host/config_cxxabi.h])
 AC_CONFIG_HEADERS([config_host/config_dbus.h])
+AC_CONFIG_HEADERS([config_host/config_emscripten.h])
 AC_CONFIG_HEADERS([config_host/config_features.h])
 AC_CONFIG_HEADERS([config_host/config_feature_desktop.h])
 AC_CONFIG_HEADERS([config_host/config_feature_opencl.h])
diff --git a/desktop/source/app/app.cxx b/desktop/source/app/app.cxx
index 2a52f9843f75..a4ce4c965d3a 100644
--- a/desktop/source/app/app.cxx
+++ b/desktop/source/app/app.cxx
@@ -18,6 +18,7 @@
  */
 
 #include <memory>
+#include <config_emscripten.h>
 #include <config_features.h>
 #include <config_feature_desktop.h>
 #include <config_feature_opencl.h>
@@ -150,6 +151,15 @@
 #define GETPID getpid
 #endif
 
+#if HAVE_EMSCRIPTEN_PROXY_POSIX_SOCKETS
+#include <stdexcept>
+#include <string>
+#include <emscripten/posix_socket.h>
+#include <emscripten/threading.h>
+#include <emscripten/val.h>
+#include <emscripten/websocket.h>
+#endif
+
 #include <strings.hxx>
 
 using namespace ::com::sun::star::awt;
@@ -547,6 +557,35 @@ void Desktop::Init()
         RequestHandler::Disable();
     }
     pSignalHandler = osl_addSignalHandler(SalMainPipeExchangeSignal_impl, 
nullptr);
+
+#if HAVE_EMSCRIPTEN_PROXY_POSIX_SOCKETS
+    {
+        auto const val = 
emscripten::val::module_property("uno_websocket_to_posix_socket_url");
+        if (val.isUndefined()) {
+            throw std::runtime_error("Module.uno_websocket_to_posix_socket_url 
is undefined");
+        } else {
+            auto const url = val.as<std::string>();
+            if (url.find('
+                throw std::runtime_error(
+                    "Module.uno_websocket_to_posix_socket_url contains 
embedded NUL");
+            }
+            SAL_INFO("desktop.app", "connecting to <" << url << ">");
+            static auto const socket = 
emscripten_init_websocket_to_posix_socket_bridge(
+                url.c_str());
+            // 0 is CONNECTING, 1 is OPEN, see
+            // <https://websockets.spec.whatwg.org/#websocket-ready-state>:
+            unsigned short readyState = 0;
+            do {
+                emscripten_websocket_get_ready_state(socket, &readyState);
+                emscripten_thread_sleep(100);
+            } while (readyState == 0);
+            if (readyState != 1) {
+                throw std::runtime_error("could not connect to <" + url + ">");
+            }
+            SAL_INFO("desktop.app", "connected to <" << url << ">");
+        }
+    }
+#endif
 }
 
 void Desktop::InitFinished()
diff --git a/external/curl/ExternalProject_curl.mk 
b/external/curl/ExternalProject_curl.mk
index 9d39e62e6fd3..45aa6d561389 100644
--- a/external/curl/ExternalProject_curl.mk
+++ b/external/curl/ExternalProject_curl.mk
@@ -65,6 +65,7 @@ $(call gb_ExternalProject_get_state_target,curl,build):
                        $(if $(filter 
MACOSX,$(OS)),--prefix=/@.__________________________________________________OOO)
 \
                        $(if $(filter MACOSX,$(OS)),CFLAGS='$(CFLAGS) \
                                
-mmacosx-version-min=$(MACOSX_DEPLOYMENT_TARGET)') \
+                       $(if 
$(ENABLE_EMSCRIPTEN_PROXY_POSIX_SOCKETS),--disable-socketpair) \
                        $(if $(filter -fsanitize=undefined,$(CC)),CC='$(CC) 
-fno-sanitize=function') \
                        CPPFLAGS='$(curl_CPPFLAGS)' \
                        CFLAGS="$(gb_CFLAGS) $(call 
gb_ExternalProject_get_build_flags,curl)" \
diff --git a/external/curl/UnpackedTarball_curl.mk 
b/external/curl/UnpackedTarball_curl.mk
index 4412857d36a0..4f21212eff8d 100644
--- a/external/curl/UnpackedTarball_curl.mk
+++ b/external/curl/UnpackedTarball_curl.mk
@@ -33,4 +33,10 @@ $(eval $(call gb_UnpackedTarball_add_patches,curl, \
 ))
 endif
 
+ifeq ($(ENABLE_EMSCRIPTEN_PROXY_POSIX_SOCKETS),TRUE)
+$(eval $(call gb_UnpackedTarball_add_patches,curl, \
+    external/curl/emscripten-proxy-poll.patch.0 \
+))
+endif
+
 # vim: set noet sw=4 ts=4:
diff --git a/external/curl/emscripten-proxy-poll.patch.0 
b/external/curl/emscripten-proxy-poll.patch.0
new file mode 100644
index 000000000000..ac1f4a84d25c
--- /dev/null
+++ b/external/curl/emscripten-proxy-poll.patch.0
@@ -0,0 +1,20 @@
+--- lib/select.c
++++ lib/select.c
+@@ -51,6 +51,8 @@
+ #include "curl_printf.h"
+ #include "curl_memory.h"
+ #include "memdebug.h"
++
++int websocket_proxy_poll(struct pollfd *fds, nfds_t nfds, int timeout);
+ 
+ /*
+  * Internal function used for waiting a specific amount of ms
+@@ -318,7 +320,7 @@
+     pending_ms = -1;
+   else
+     pending_ms = 0;
+-  r = poll(ufds, nfds, pending_ms);
++  r = websocket_proxy_poll(ufds, nfds, pending_ms);
+   if(r <= 0) {
+     if((r == -1) && (SOCKERRNO == EINTR))
+       /* make EINTR from select or poll not a "lethal" error */
diff --git a/solenv/gbuild/platform/EMSCRIPTEN_INTEL_GCC.mk 
b/solenv/gbuild/platform/EMSCRIPTEN_INTEL_GCC.mk
index 268d2dbf932e..416cdbc4c1a4 100644
--- a/solenv/gbuild/platform/EMSCRIPTEN_INTEL_GCC.mk
+++ b/solenv/gbuild/platform/EMSCRIPTEN_INTEL_GCC.mk
@@ -26,6 +26,10 @@ gb_EMSCRIPTEN_LDFLAGS += -sSTACK_SIZE=131072 
-sDEFAULT_PTHREAD_STACK_SIZE=65536
 gb_EMSCRIPTEN_LDFLAGS += --bind -s FORCE_FILESYSTEM=1 -s WASM_BIGINT=1 -s 
ERROR_ON_UNDEFINED_SYMBOLS=1 -s FETCH=1 -s ASSERTIONS=1 -s EXIT_RUNTIME=0 -s 
EXPORTED_RUNTIME_METHODS=["UTF16ToString","stringToUTF16","UTF8ToString","ccall","cwrap","addOnPreMain","addOnPostRun","registerType","throwBindingError"$(if
 $(ENABLE_QT6),$(COMMA)"callMain"$(COMMA)"specialHTMLTargets")]
 gb_EMSCRIPTEN_QTDEFS := -DQT_NO_LINKED_LIST -DQT_NO_JAVA_STYLE_ITERATORS 
-DQT_NO_EXCEPTIONS -DQT_NO_DEBUG -DQT_WIDGETS_LIB -DQT_GUI_LIB -DQT_CORE_LIB
 
+ifeq ($(ENABLE_EMSCRIPTEN_PROXY_POSIX_SOCKETS),TRUE)
+gb_EMSCRIPTEN_LDFLAGS += -sPROXY_POSIX_SOCKETS -lwebsocket.js
+endif
+
 gb_Executable_EXT := .html
 gb_EMSCRIPTEN_EXCEPT = -fwasm-exceptions -s SUPPORT_LONGJMP=wasm
 

Reply via email to