2

I see that gen_udp has support for Unix sockets, and this example shows creating an using one in Erlang.

I want to send messages to an existing Unix socket (to control mpv via its JSON IPC interface). I see there was a self-answered question on the Erlang mailing list about this, but the answer doesn't make sense to me, as Sock2 is used without previous assignment.

I see in the gen_udp docs this option:

{fd, integer() >= 0}

  If a socket has somehow been opened without using gen_udp,
  use this option to pass the file descriptor for it.

But when I try to open the socket as a file with file:open/2, I get {error,eopnotsupp}.

How can I send messages to an existing Unix socket?

Nathan Long
  • 122,748
  • 97
  • 336
  • 451
  • The mailing list example is working if you get `Sock2` like this: `{ok, Sock2} = gen_udp:open(0, [local]).` – nico Feb 18 '20 at 13:15

1 Answers1

0

Answer for my case

This will not be a canonical and thorough answer, because I'm not super familiar with sockets. However, I emailed Joe from the mailing list link above, and he said:

As far as I understand, the unix socket type to erlang module mapping is as follows:

SOCK_STREAM -> gen_tcp
SOCK_DGRAM -> gen_udp
SOCK_SEQPACKET -> gen_sctp

He suggested using gen_tcp:connect in my case, and it worked! Apparently, mpv created a SOCK_STREAM socket.

So, having started mpv like:

mpv /Users/me/playlist.m3u --input-ipc-server=/tmp/mpv.sock --idle yes --no-audio-display

... so that it expects commands on the socket /tmp/mpv.sock, I could send it a "play a different playlist" command like this in erl:

{ok, Port} = gen_tcp:connect({local, "/tmp/mpv.sock"}, 0, [local]).
Msg = "{ \"command\": [\"loadlist\", \"/Users/me/playlist2.m3u\", \"replace\"] }\n".
gen_tcp:send(Port, Msg).
Nathan Long
  • 122,748
  • 97
  • 336
  • 451