user1569030
user1569030

Reputation:

lua-socket: unix domain sockets?

I'm using lua-socket 3.0rc1.3 (that comes with Ubuntu Trusty) and lua 5.1. I'm trying to listen on a unix domain socket, and the only example code I can find is this

-- send stdin through unix socket
socket = require"socket"
socket.unix = require"socket.unix"
c = assert(socket.unix())
assert(c:connect("/tmp/foo"))
while 1 do
    local l = io.read()
    assert(c:send(l .. "\n"))
end

Problem is, when I try and connect() I get "no such file or directory" - how do I create that socket in the first place? mkfifo /tmp/foo which someone recommended me gets me a "connection refused" error instead (I don't think a fifo is the same thing as a domain socket?).

Is there any minimal working example out there of using luasocket on a unix domain socket?

EDIT: from Paul's solution, here's a MWE if anyone's interested

libsocket = require "socket"
libunix = require "socket.unix"
socket = assert(libunix())
SOCKET="/tmp/socket"
assert(socket:bind(SOCKET))
assert(socket:listen())
conn = assert(socket:accept())
while 1 do
    data=assert(conn:receive())
    print("Got line: " .. data)
    conn:send("echo: " .. data .. "\n")
    if data == "." then conn:close() return end
end

Upvotes: 6

Views: 6114

Answers (2)

mk12
mk12

Reputation: 26434

Although luasocket provides socket.unix, I don't recommend using it unless you're already using luasocket and want to avoid another dependency:

  • It is not mentioned anywhere in the documentation.
  • The code says "This module is just an example of how to extend LuaSocket with a new domain" (unix.h).

Instead I recommend luaposix, which has a well-documented API. Here's a simple example:

-- Send stdin through a Unix socket.
local socket = require("posix.sys.socket")
local unistd = require("posix.unistd")
local fd = assert(socket.socket(socket.AF_UNIX, socket.SOCK_STREAM, 0))
assert(socket.connect(fd, {family = socket.AF_UNIX, path = "/tmp/foo"}))
while true do
    local line = io.read()
    if not line then
        break
    end
    line = line .. "\n"
    local i = 1
    while i < #line do
        i = assert(socket.send(fd, line:sub(i)))
    end
end
unistd.close(fd)

Some other alternatives with explicit support for Unix sockets:

Upvotes: 4

Paul Kulchenko
Paul Kulchenko

Reputation: 26794

As far as I understand, you can't create that socket using mkfifo (or any command) as it will be created by the (listening) server. There is an example listed on the same page you referenced, but it may be difficult to find:

sock, err = s:listen([backlog|_32_])
sock, err = s:bind(path)
client_conection, err = s:accept()

Basically, you create the server the same way you'd do it for TCP, only instead of binding to an address/port, you bind to a path and then start accepting new connections on it.

Upvotes: 2

Related Questions