Is there a way to access UNIX domain sockets (e.g. /var/run/dbus/system_bus_socket ) directly from Erlang without resorting to a third-party driver?
Erlang/OTP comes with drivers for tcp and udp sockets only. So...
No.
The nanomsg library supports Unix domain sockets, and the enm driver provides an Erlang language binding for nanomsg.
For example, to open the response side of a request/response protocol and bind to a Unix domain socket address:
Url = "ipc:///path/to/socket/file",
{ok,Rep} = enm:rep([{bind,Url}]),
Here, Rep is a nanomsg socket. It supports send and recv as well as all the usual Erlang {active, true | false | N} modes, etc. that regular Erlang TCP/SCTP/UDP sockets provide. For more details consult the enm github README.
You can use hackney if you want to recieve http response as hackney provides support to UNIX socket . hackney:get<<"http+unix://path_to_ sock_file.sock">>
In Erlang/OTP 19.0, UNIX Sockets are now available, as stated in the readme:
OTP-13572 Application(s): erts, kernel
Related Id(s): PR-612
* HIGHLIGHT *
Experimental support for Unix Domain Sockets has been implemented. Read the sources if you want to try it out. Example: gen_udp:open(0, [{ifaddr,{local,"/tmp/socket"}}]). Documentation will be written after user feedback on the experimental API.
Example:
lsock.erl:
-module(lsock).
-export([watcher/1, test/0]).
watcher(Parent) ->
{ok, Sockin} = gen_udp:open(0, [{ifaddr, {local, "/tmp/testsockin"}}]),
io:format("watcher ok? ~w ~w~n", [ok, Sockin]),
Parent ! start,
receive
Msg -> io:format("watcher got: ~p ~n", [Msg]) end.
test() ->
file:delete("/tmp/testsockin"),
file:delete("/tmp/testsockout"),
_ = spawn(lsock, watcher, [self()]),
{ok, Sockout} = gen_udp:open(0, [{ifaddr, {local, "/tmp/testsockout"}}]),
io:format("parent ok? ~w ~w~n", [ok, Sockout]),
receive start ->
gen_udp:send(Sockout, {local, "/tmp/testsockin"}, 0, "hi") end.
And the following demonstrates its results:
$ erlc lsock.erl
$ erl
Erlang/OTP 19 [erts-8.0.1] [source-ca40008] [64-bit] [smp:2:2] [async-threads:10] [hipe] [kernel-poll:false]
Eshell V8.0.1 (abort with ^G)
1> lsock:test().
<0.58.0>
parent ok? ok #Port<0.455>
watcher ok? ok #Port<0.456>
watcher got: {udp,#Port<0.456>,{local,<<"/tmp/testsockout">>},0,"hi"}
ok
2>