From 635834566782b1e9fa3fc52ee8a0ceca9885c18e Mon Sep 17 00:00:00 2001 From: felixdoerre Date: Mon, 27 Jan 2020 14:32:15 +0100 Subject: [PATCH] Fix open port for X11 applications (#18583) Whenever mono opens an X11 window, the application opens a tcp socket for controlling the (non-tcp)-connection to X11. This is bad practice, as a tcp socket is not needed. This pull request cleans the logic, by replacing the tcp socket with a fifo. That way this loopback connection is not visible from outside the .NET application, and all logic surrounding it should remain unchanged. --- .../System.Windows.Forms/XplatUIX11.cs | 27 +++++++++------------- 1 file changed, 11 insertions(+), 16 deletions(-) diff --git a/mcs/class/System.Windows.Forms/System.Windows.Forms/XplatUIX11.cs b/mcs/class/System.Windows.Forms/System.Windows.Forms/XplatUIX11.cs index 32b64fd7579..2a535516082 100644 --- a/mcs/class/System.Windows.Forms/System.Windows.Forms/XplatUIX11.cs +++ b/mcs/class/System.Windows.Forms/System.Windows.Forms/XplatUIX11.cs @@ -67,6 +67,7 @@ using System.Runtime.Serialization.Formatters.Binary; using System.Text; using System.Threading; using Mono.Unix.Native; +using Mono.Unix; /// X11 Version namespace System.Windows.Forms { @@ -108,9 +109,8 @@ namespace System.Windows.Forms { static object wake_waiting_lock = new object (); static X11Keyboard Keyboard; // static X11Dnd Dnd; - static Socket listen; // - static Socket wake; // - static Socket wake_receive; // + static UnixStream wake; // + static UnixStream wake_receive; // static byte[] network_buffer; // static bool detectable_key_auto_repeat; @@ -485,24 +485,19 @@ namespace System.Windows.Forms { hwnd.whole_window = RootWindow; hwnd.ClientWindow = RootWindow; - // For sleeping on the X11 socket - listen = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.IP); - IPEndPoint ep = new IPEndPoint(IPAddress.Loopback, 0); - listen.Bind(ep); - listen.Listen(1); - // To wake up when a timer is ready network_buffer = new byte[10]; - wake = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.IP); - wake.Connect(listen.LocalEndPoint); + int[] pipefds = new int[2]; + Syscall.pipe (pipefds); + wake = new UnixStream (pipefds [1]); // Make this non-blocking, so it doesn't // deadlock if too many wakes are sent // before the wake_receive end is polled - wake.Blocking = false; + Syscall.fcntl (pipefds [1], FcntlCommand.F_SETFL, Syscall.fcntl (pipefds [1], FcntlCommand.F_GETFL) | (int) OpenFlags.O_NONBLOCK); - wake_receive = listen.Accept(); + wake_receive = new UnixStream (pipefds [0]); pollfds = new Pollfd [2]; pollfds [0] = new Pollfd (); @@ -510,7 +505,7 @@ namespace System.Windows.Forms { pollfds [0].events = PollEvents.POLLIN; pollfds [1] = new Pollfd (); - pollfds [1].fd = wake_receive.Handle.ToInt32 (); + pollfds [1].fd = pipefds [0]; pollfds [1].events = PollEvents.POLLIN; Keyboard = new X11Keyboard(DisplayHandle, FosterParent); @@ -1232,7 +1227,7 @@ namespace System.Windows.Forms { void WakeupMain () { try { - wake.Send (new byte [] { 0xFF }); + wake.Write (new byte [] { 0xFF }, 0, 1); } catch (SocketException ex) { if (ex.SocketErrorCode != SocketError.WouldBlock) { throw; @@ -1739,7 +1734,7 @@ namespace System.Windows.Forms { // Clean out buffer, so we're not busy-looping on the same data if (length == pollfds.Length) { if (pollfds[1].revents != 0) - wake_receive.Receive(network_buffer, 0, 1, SocketFlags.None); + wake_receive.Read(network_buffer, 0, 1); lock (wake_waiting_lock) { wake_waiting = false; } -- 2.11.4.GIT