[Libwebsockets] should I use LWS_ADOPT_SOCKET for AF_UNIX socket?

Andy Green andy at warmcat.com
Tue Feb 18 06:39:46 CET 2020

On February 18, 2020 2:49:37 AM GMT, Per Bothner <per at bothner.com> wrote:
>On 2/15/20 8:08 PM, Andy Green wrote:
>> On February 15, 2020 10:20:04 PM GMT, Per Bothner <per at bothner.com>
>>> tl;dr: If for a AF_UNIX socket I just want to use lws to multiplex
>>> listening to a connection, should I use LWS_ADOPT_SOCKET? It seems
>I was confused - the problem was not at the connect/accept level,
>but later: recvmsg not blocking in the same way it does on Linux.
>I couldn't figure out how to make it work on MacOS: I added a call to
>poll before the recvmsg, but that only partially helped.
>However, using write/read instead of sendmsg/recvmsg seems to work.
>I have to forego passing stdin/stdout/stderr from the client to the
>but I can get most of the same functionality by just using the socket
>So I'm trying that instead, at least for MacOS.  It seems promising.
>(A bonus of using just the socket rather than passing descriptor is
>the same logic should work if using named pipes instead of local
>if/when I try porting DomTerm to a system without the latter, such as
>plain non-WSL Windows.)

Bsd has some quirks compared to linux, if another thread changes the poll wait array (say, enable POLLOUT wait on something) while the event loop thread is in the poll wait asleep, on exiting the sleep and updating .revents the kernel overwrites your .events with the value it had on entry to the sleep as well... it basically copied the array on entry, updated revents on that and then memcpy()'d the array back over the userland copy.  Whatever the other thread changed in the original inbetweentimes gets lost.  Linux just updates .revents members.

If your workaround is helping then fine, but if it's a spawn, FYI on master the cgi stuff was broken out into its own api, lws_spawn_ that wraps the whole stdxxx redirect to pipes / fork / wsis for stdxxx part


I have tested that on linux and OSX catalina with the stdxxx pipe wsi bound to raw-file role (ie, also using read()...) and that works perfectly.

>> But for unix domain sockets, they are like tcp sockets in that they
>have a stateful connection concept and are either istening or making
>connections.  For that reason if you want to listen with one, it's fine
>but the way follows tcp listen / serving in lws... create a vhost and
>use the vhost option LWS_SERVER_OPTION_UNIX_SOCK, you set the uds path
>in .iface IIRC.
>I couldn't figure out how to use LWS_SERVER_OPTION_UNIX_SOCK - the
>example(s) are unclear how I would use that  And when I figured out
>the problem was at the sendmsg/recvmsg level, I didn't pursue it.
>> This stuff is in use with gitohashi on https://libwebsockets.org/git
>... gitohashi is actually a separate process also using lws to serve
>over a unix domain socket, lwsws proxies it back out over h1 or h2 to
>the remote client.
>I couldn't find LWS_SERVER_OPTION_UNIX_SOCK in the gitohasi code, so
>that didn't help me figure out what to do.

Gitohashi uses the generic lejp-config JSON stuff to configure itself, so it's just a JSON flag in the vhost definition.  I mentioned it to mean this is in use and works.

If you're working via adopt no worries, but you shouldn't have to do anything other than set the related vhost flag and set .iface to your socket path.


More information about the Libwebsockets mailing list