Opening Sockets to The Xserver Directly

Opening sockets to the Xserver directly

The question should rather be "What are the advantages of using Xlib instead of a graphical toolkit like gtk"?

Even to master Xlib, you have to spent months or years! It's so intricate that almost every app that has graphical content to display uses a toolkit instead.

Using a plain socket means speaking the X11 protocol directly, which means you would end up recreating Xlib (no, you wouldn't finish!)

As an analogy, plain socket ~ machine code, xlib ~ assembly code, toolkit ~ higher level language. (notwithstanding that xlib does a little maintenance for you, but I guess it's rather neglectable)

How to get the list of open windows from xserver

From the CLI you can use

xwininfo -tree -root

If you need to do this within your own code then you need to use the XQueryTree function from the Xlib library.

How to set up working X11 forwarding on WSL2

TL;DR:

Add the following to your ~/.bashrc:

export DISPLAY=$(ip route list default | awk '{print $3}'):0
export LIBGL_ALWAYS_INDIRECT=1

Enable Public Access on your X11 server for Windows.*

Add a separate inbound rule for TCP port 6000 to the windows firewall in order to allow WSL access to the X server, as described by the wsl-windows-toolbar-launcher people.


As pointed out by WSL_subreddit_mod on reddit and as you can read in Microsoft's documentation on WSL2, the WSL2 architecture uses virtualized network components. This means that WSL2 has a different IP address than the host machine.
This explains why the X11 forwarding settings of WSL1 cannot simply be transferred to WSL2.

On the Ubuntu Wiki page about WSL you can already find a configuration adapted for WSL2 under Running Graphical Applications. A similar configuration is also suggested by the above mentioned Reddit User, who also contributes another part of the solution: Enable Public Access on the X11 server under Windows.

This means add the following to your ~/.bashrc:

export DISPLAY=$(ip route list default | awk '{print $3}'):0
export LIBGL_ALWAYS_INDIRECT=1

And Enable Public Access on your X11 server for Windows.*

The most important part to enable X11 forwarding for WSL2 on Windows 10 is still missing: the Windows firewall blocks connections via the network interface configured for WSL by default.

A separate inbound rule for TCP port 6000 is required to allow WSL access to the X server. After the rule has been created, as described by the wsl-windows-toolbar-launcher people, the IP address range can be restricted to the WSL subnet in the settings of the newly created rule, under Scope: 172.16.0.0/12.

*: If you use VcXSrv you can enable public access for your X server by disabling Access Control on the Extra Settings:

Disable access control VcXSrv

Or by calling vcxsrv.exe directly with the ac flag: vcxsrv.exe -ac as pointed out by ameeno on the github issue.

Alternatively this SO answer shows how to share keys via .Xauthority files, leaving you with intact access control.

get foreground console / find active X server

I like the /proc fs :) It seems to provide everything i need. I have not yet cast this into C code, but this should work pretty good:

  • look for open X displays (and their Names, eg. :0) in /tmp/.X11-unix/
  • look for these sockets in /proc/net/unix, get their inodes
  • look for processes in /proc/[PID]/ that have a vt open: ls -la /proc/*/fd/ | grep /dev/tty - if they also have one of the socket inodes in their open file descriptors, they should be an X server, else a tty. Of course, /proc/[PID]/exe helps, but may be less reliable.

The output of cat /proc/net/unix | grep -a '/tmp/.X11-unix/X' suggests, that there is always a socket of the form /tmp/.X11-unix/X0 and many of the form @/tmp/.X11-unix/X0 (note the @). I wonder if it is a save assumption that there is always exactly one process (the X server) listening on the former.

SSH into vagrant with X server set up

Install Cygwin with the following packages to resolve the problem as specified in this website:

  • xorg-server
  • xinit
  • xorg-docs (for documentation)
  • openssh (in case this wasn't installed previously)

Then load up the window using startxwin from the cygwin terminal.

A note that I discovered later is that it is better to ssh into vagrant using the following command:

vagrant -Y ssh

Than:

vagrant -X ssh

The latter is performed in untrusted mode as in this answer and times out after a while.

How do I get a list of connected sockets/clients with Socket.IO?

In Socket.IO 0.7 you have a clients method on the namespaces. This returns an array of all connected sockets.

API for no namespace:

var clients = io.sockets.clients();
var clients = io.sockets.clients('room'); // all users from room `room`

For a namespace

var clients = io.of('/chat').clients();
var clients = io.of('/chat').clients('room'); // all users from room `room`

Note: This solution only works with a version prior to 1.0

From 1.x and above, please refer to getting how many people are in a chat room in socket.io.

XIO: fatal IO error 11 (Resource temporarily unavailable) on X server :0 after 235 requests (235 known processed) with 0 events remaining

Not necessarily a real answer, but I would not use multiprocessing to parallelize access to sockets like the connection to the X server. That looks like a bad idea. Use regular threads instead.

Be aware that multiprocessing is a hack based (sometimes) on forking, so what exactly occurs with a forked socket when both the parent and the child try to access it... is random mixed garbage.

EDIT: the reason is that both forked sockets are still the "same end" of the socket, with the X server holding on the "other end". When the X server wants to send a message, it writes, say, 100 bytes on the socket. But if you're unlucky, the forked process 1 reads the first 50 bytes and the forked process 2 reads the remaining 50 bytes. Each process is unexpectedly getting only a random part of the message. They will each complain that the X server is sending nonsense.

psql: error: connection to server on socket /tmp/.s.PGSQL.5432 failed: No such file or directory

Below was the workaround if you prefer to stay in v13.3, if you are on 14.2 you can simply change the port postgresql is listening to. Read their docs about it here.

Note that this solution works for the setup that I have (take a look at the original post for my setup details ie. OS & how what I'd use to install Postgres)

  1. open your postgresql.conf file in the following directory and use
    any text editor you want. below uses vscode/vim.

vscode

sudo code . /usr/local/var/postgres/postgresql.conf

vim

sudo vi /usr/local/var/postgres/postgresql.conf

  1. change port to 5432 and restart your machine.

v13.3 solution

it appears that the upgrade really messed up my postgres since per Nagev's answer it's listening to port 5433 instead of 5432. I downgraded to v13.3 to fix this issue.

brew uninstall postgresql
brew install postgresql@13
brew services start postgresql@13
brew link postgresql@13 --force


Related Topics



Leave a reply



Submit