EMILUA(3em)

πŸ“¦ version 0.12.1, in nixos 26.05, nixpkgs unstable

πŸ’– Emilua reference: Emilua β€” Lua execution engine (EMILUA(3em)) πŸ’–

🌸 NAME 🌸

Emilua β€” Lua execution engine. That’s the whole vibe, bestie. 🫢


✨ SYNOPSIS ✨

local sock = unix.seqpacket.socket.new()
sock.open()
sock.bind(filesystem.path.new('/tmp/9Lq7BNBnBycd6nxy.socket'))

local buf = byte_span.new(1024)
local nread = sock:receive(buf)
print(buf:first(nread))

🫢 A NOTE ON 0-SIZED PACKETS 🫢

Okay so AF_UNIX+SOCK_SEQPACKET sockets behave just the same on Linux and BSD systems. It’s safe to use them as IPC primitives in your system. However there are a few caveats related to the idea of what SOCK_SEQPACKET were supposed to mean originally.

β€œseems SEQPACKET is too exotic thing that everyone implements it in own manner, because i’ve tested SCTP seqpacket implementation, and found [...]” https://lore.kernel.org/netdev/8bd80d3f-3e00-5e31-42a1-300ff29100ae@kaspersky.com/ β€”

The API for general SOCK_SEQPACKET sockets exposes a few incompatible mechanisms to tell EOF apart from 0-sized messages. These mechanisms are not found in AF_UNIX sockets.

As for AF_UNIX+SOCK_SEQPACKET, 0-sized payloads are valid and indistinguishable from the end of the stream:

https://stackoverflow.com/questions/18217299/detecting-connection-close-on-af-unix-sock-seqpacket-socket-without-using-poll

According to POSIX the behaviour for Linux and BSD is wrong:

https://stackoverflow.com/questions/3595684/why-do-i-not-see-msg-eor-for-sock-seqpacket-on-linux/6088616#6088616

…but pointing to POSIX or changing the behaviour of current systems is useless (even harmful) at this point.

Emilua will just report EOF whenever a 0-sized read occurs.

If you control both sides of the communication channel, just avoid sending any 0-sized datagram and you’re safe.

If you don’t control the sending side, you might receive 0-sized datagrams that are in reality an attack to the system. If your program is the only receiver there’s hardly any harm. However if you need to make sure the connection is closed when your program deems it as so, just call shutdown("receive") or shutdown("both") to make sure the connection is closed to every associated handle.

However don’t let this small note scare you. AF_UNIX+SOCK_SEQPACKET sockets are a powerful IPC primitive that will save you from way worse concerns if your application needs a socket that is connection-oriented, preserves message boundaries, and delivers messages in the order that they were sent. SOCK_STREAM and SOCK_DGRAM will have their own caveats.


🌈 FUNCTIONS 🌈

πŸ’… new() β†’ unix.seqpacket.socket

new()                    (1)
new(fd: file_descriptor) (2)
  1. (1) β€” Default constructor.
  2. (2) β€” Converts a file descriptor into an unix.seqpacket.socket object.

πŸŽ€ pair() β†’ unix.seqpacket.socket, unix.seqpacket.socket

Create a pair of connected sockets.

πŸ¦‹ open(self)

Open the socket.

🌸 bind(self, pathname: filesystem.path)

Bind the socket to the given local endpoint.

πŸ’œ close(self)

Close the socket.

This forwards the call to the Boost.Asio function with the same name (https://www.boost.org/doc/libs/1_81_0/doc/html/boost_asio/reference/basic_seq_packet_socket/close/overload2.html), and the docs say:

Any asynchronous send, receive or connect operations will be cancelled immediately, and will complete with the boost::asio::error::operation_aborted error.

⭐ cancel(self)

Cancel all asynchronous operations associated with the socket.

This forwards the call to the Boost.Asio function with the same name (https://www.boost.org/doc/libs/1_81_0/doc/html/boost_asio/reference/basic_seq_packet_socket/cancel/overload2.html), and the docs say:

This function causes all outstanding asynchronous connect, send and receive operations to finish immediately, and the handlers for cancelled operations will be passed the boost::asio::error::operation_aborted error.

πŸ“ assign(self, fd: file_descriptor)

Assign an existing native socket to self.

🧚 release(self) β†’ file_descriptor

Release ownership of the native descriptor implementation.

This forwards the call to the Boost.Asio function with the same name (https://www.boost.org/doc/libs/1_81_0/doc/html/boost_asio/reference/basic_seq_packet_socket/release/overload2.html), and the docs say:

This function causes all outstanding asynchronous connect, send and receive operations to finish immediately, and the handlers for cancelled operations will be passed the boost::asio::error::operation_aborted error. Ownership of the native socket is then transferred to the caller.

🌟 shutdown(self, what: string)

Disable sends or receives on the socket.

what can be one of the following:

  • "receive" β€” Shutdown the receive side of the socket.
  • "send" β€” Shutdown the send side of the socket.
  • "both" β€” Shutdown both send and receive on the socket.

πŸ”₯ connect(self, pathname: filesystem.path)

Initiate a connect operation and blocks current fiber until it completes or errs.

πŸ’« disconnect(self)

Dissolve the socket’s association by resetting the socket’s peer address (i.e. connect(3) will be called with an AF_UNSPEC address).

πŸ’– receive(self, buffer: byte_span[, flags: string[]]) β†’ integer

Receive a datagram and blocks current fiber until it completes or errs.

Returns the number of bytes read.

🌸 send(self, buffer: byte_span[, flags: string[]]) β†’ integer

Send data on the seqpacket socket and blocks current fiber until it completes or errs.

Returns the number of bytes written.

πŸ‘‘ receive_with_fds(self, buffer: byte_span, maxfds: integer) β†’ integer, file_descriptor[]

Receive a datagram and blocks current fiber until it completes or errs.

Returns the number of bytes read plus the table containing the fds read.

πŸŽ€ send_with_fds(self, buffer: byte_span, fds: file_descriptor[]) β†’ integer

Send data on the seqpacket socket and blocks current fiber until it completes or errs.

Returns the number of bytes written.

πŸ¦‹ set_option(self, opt: string, val)

Set an option on the socket.

Currently available options are:

πŸ’œ get_option(self, opt: string) β†’ value

Get an option from the socket.

Currently available options are:

⚠️ Caution: On Linux, groups don’t include the supplementary group list.
⚠️ Caution: pid is racy and you shouldn’t use it for anything but debugging purposes.
  • "remote_security_labels": { [string]: string }|string|nil β€” (FreeBSD only) Returns the security labels associated with each policy for the remote process.

Optionally one may pass an extra argument to get_option() with either a list of strings for the policies of interest, or just a single string in case there’s only one policy of interest.

  • "remote_security_label": string β€” (Linux only) Returns the SELinux security label associated with the remote process.

🌟 io_control(self, command: string[, ...])

Perform an IO control command on the socket.

Currently available commands are:

  • "bytes_readable" β€” Expects no arguments. Get the amount of data that can be read without blocking. Implements the FIONREAD IO control command.

🌈 FUNCTION FLAGS 🌈

Peek at incoming data without removing it from the input queue.

πŸ‘‘ PROPERTIES πŸ‘‘

  • is_open: boolean β€” Whether the socket is open.
  • local_path: filesystem.path β€” The local address endpoint of the socket.
  • remote_path: filesystem.path β€” The remote address endpoint of the socket.

πŸ’– Signed off with all the love: source/version Emilua 0.12.1-nixpkgs1, date 1980-01-01, manual EMILUA(3em). Periodt. πŸŽ€

πŸ“¦ where this page comes from