From ae484c85e2ee2a8abc68053aa1f21d2e4390da8f Mon Sep 17 00:00:00 2001 From: reimai Date: Tue, 25 Mar 2025 16:40:21 +0300 Subject: [PATCH 1/2] fix getting a free socket on macos --- .../frontend/SocketBasedPluginFrontend.scala | 33 +++++++++++++++---- 1 file changed, 27 insertions(+), 6 deletions(-) diff --git a/bridge/src/main/scala/protocbridge/frontend/SocketBasedPluginFrontend.scala b/bridge/src/main/scala/protocbridge/frontend/SocketBasedPluginFrontend.scala index 6d1dd59..dc177ed 100644 --- a/bridge/src/main/scala/protocbridge/frontend/SocketBasedPluginFrontend.scala +++ b/bridge/src/main/scala/protocbridge/frontend/SocketBasedPluginFrontend.scala @@ -1,22 +1,25 @@ package protocbridge.frontend +import protocbridge.frontend.SocketBasedPluginFrontend.getFreeSocket import protocbridge.{ExtraEnv, ProtocCodeGenerator} -import java.net.ServerSocket +import java.net.{InetAddress, ServerSocket} import java.nio.file.{Files, Path} import scala.concurrent.ExecutionContext.Implicits.global import scala.concurrent.{Future, blocking} + /** PluginFrontend for Windows and macOS where a server socket is used. - */ + */ abstract class SocketBasedPluginFrontend extends PluginFrontend { + case class InternalState(serverSocket: ServerSocket, shellScript: Path) override def prepare( - plugin: ProtocCodeGenerator, - env: ExtraEnv - ): (Path, InternalState) = { - val ss = new ServerSocket(0) // Bind to any available port. + plugin: ProtocCodeGenerator, + env: ExtraEnv + ): (Path, InternalState) = { + val ss = getFreeSocket() val sh = createShellScript(ss.getLocalPort) Future { @@ -49,3 +52,21 @@ abstract class SocketBasedPluginFrontend extends PluginFrontend { protected def createShellScript(port: Int): Path } + + +object SocketBasedPluginFrontend { + + /** + * for mac we need to specify an address, otherwise it uses ANY (*.* in netstat) + * which does not conflict with existing 'localhost' sockets, + * resulting in a conflict later on in MacPluginFrontend + */ + def getFreeSocket(): ServerSocket = { + if (!PluginFrontend.isMac) { + // Bind to any available port. + new ServerSocket(0) + } else { + new ServerSocket(0, 50, InetAddress.getByName("127.0.0.1")) + } + } +} From 80be6541bae4338da775990f8b4c3e21a3e5caad Mon Sep 17 00:00:00 2001 From: reimai Date: Thu, 10 Apr 2025 12:24:07 +0300 Subject: [PATCH 2/2] free socket for windows; fmt --- .../frontend/SocketBasedPluginFrontend.scala | 35 ++++++------------- 1 file changed, 10 insertions(+), 25 deletions(-) diff --git a/bridge/src/main/scala/protocbridge/frontend/SocketBasedPluginFrontend.scala b/bridge/src/main/scala/protocbridge/frontend/SocketBasedPluginFrontend.scala index dc177ed..d969525 100644 --- a/bridge/src/main/scala/protocbridge/frontend/SocketBasedPluginFrontend.scala +++ b/bridge/src/main/scala/protocbridge/frontend/SocketBasedPluginFrontend.scala @@ -1,6 +1,5 @@ package protocbridge.frontend -import protocbridge.frontend.SocketBasedPluginFrontend.getFreeSocket import protocbridge.{ExtraEnv, ProtocCodeGenerator} import java.net.{InetAddress, ServerSocket} @@ -8,18 +7,22 @@ import java.nio.file.{Files, Path} import scala.concurrent.ExecutionContext.Implicits.global import scala.concurrent.{Future, blocking} - /** PluginFrontend for Windows and macOS where a server socket is used. - */ + */ abstract class SocketBasedPluginFrontend extends PluginFrontend { case class InternalState(serverSocket: ServerSocket, shellScript: Path) override def prepare( - plugin: ProtocCodeGenerator, - env: ExtraEnv - ): (Path, InternalState) = { - val ss = getFreeSocket() + plugin: ProtocCodeGenerator, + env: ExtraEnv + ): (Path, InternalState) = { + + /** we need to specify an address, otherwise it uses ANY (*.* in netstat) + * which does not conflict with existing 'localhost' sockets on macos, + * resulting in a conflict later on in MacPluginFrontend + */ + val ss = new ServerSocket(0, 50, InetAddress.getByName("127.0.0.1")) val sh = createShellScript(ss.getLocalPort) Future { @@ -52,21 +55,3 @@ abstract class SocketBasedPluginFrontend extends PluginFrontend { protected def createShellScript(port: Int): Path } - - -object SocketBasedPluginFrontend { - - /** - * for mac we need to specify an address, otherwise it uses ANY (*.* in netstat) - * which does not conflict with existing 'localhost' sockets, - * resulting in a conflict later on in MacPluginFrontend - */ - def getFreeSocket(): ServerSocket = { - if (!PluginFrontend.isMac) { - // Bind to any available port. - new ServerSocket(0) - } else { - new ServerSocket(0, 50, InetAddress.getByName("127.0.0.1")) - } - } -}