unix.seqpacket.socket
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:slice(1, nread))
A note on 0-sized packets
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 […]
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.
According to POSIX the behaviour for Linux and BSD is wrong, 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 | Default constructor. |
2 | Converts a file descriptor into an unix.seqpacket.socket object. |
close(self)
Close the socket.
Forward the call to the function with same name in Boost.Asio:
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.
Forward the call to the function with same name in Boost.Asio:
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.
release(self) → file_descriptor
Release ownership of the native descriptor implementation.
Forward the call to the function with same name in Boost.Asio:
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:
"debug"
"send_buffer_size"
"receive_buffer_size"
get_option(self, opt: string) → value
Get an option from the socket.
Currently available options are:
"debug"
"send_buffer_size"
"receive_buffer_size"
"remote_credentials": { uid: integer, groups: integer[], pid: integer }
-
Returns the credentials from the remote process.
On Linux, groups
don’t include the supplementary group list.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.