uring-cmd-socket.dhover×174all
#!/usr/bin/env dub
/+ dub.sdl:
    name "io_uring_uring_cmd_socket"
    dependency "during" version="~>0.5.0"
    platforms "linux"
    targetPath "build"
+/
/**
 * `io_uring` — `IORING_OP_URING_CMD` passthrough on a socket (Linux 5.19).
 *
 * `IORING_OP_URING_CMD` (Linux 5.19) is a generic "command" channel that lets a
 * file's underlying driver service an `ioctl`/`setsockopt`-like request straight
 * out of the ring, with no per-call syscall. The socket sub-commands
 * (`SOCKET_URING_OP_*`, the `cmd_op` field — socket support landed in Linux 6.7)
 * ride that channel. Here we drive a `getsockopt`/`setsockopt` round-trip on a
 * loopback TCP socket entirely through the ring via `prepCmdSock`, instead of
 * calling `getsockopt(2)` / `setsockopt(2)` directly.
 *
 * What it does:
 *   1. Creates and binds a TCP socket to 127.0.0.1:0 with libc.
 *   2. Submits one `uring_cmd` SQE: `SOCKET_URING_OP_GETSOCKOPT` of
 *      `SO_REUSEADDR`, reading the option value through the ring; the option
 *      length comes back in the CQE `res` and the value buffer is filled
 *      in-place.
 *   3. Submits a `SOCKET_URING_OP_SETSOCKOPT` to flip `SO_REUSEADDR` on, then a
 *      second `GETSOCKOPT` to confirm the new value round-tripped — proving the
 *      passthrough moves data into the kernel and back out, not just succeeds.
 *
 * `uring_cmd` on a socket needs no special hardware (unlike NVMe/block or ZCRX
 * passthrough), so it runs on any 6.7+ loopback host — including this 6.18 box,
 * where the feature MUST be exercised.
 *
 * (Note: a `SOCKET_URING_OP_GETSOCKNAME` sub-command was proposed but never
 * merged into mainline; on a live kernel it returns `-EOPNOTSUPP`. We therefore
 * demonstrate the getsockopt/setsockopt sub-commands that the kernel actually
 * implements.)
 *
 * Companion to the io_uring chronology:
 * see docs/research/async-io/io-uring/timeline.md
 *   § "5.19 — Buffer rings, zero-copy groundwork, big SQE/CQE".
 *
 * Run with: `dub run --single uring-cmd-socket.d`
 *
 * Portability: if the running kernel lacks `io_uring` (setup < 0) or this
 * specific op is unsupported (`-EINVAL` / `-EOPNOTSUPP` / `-ENOSYS`), the
 * program prints a `SKIP:` line and exits 0 so it stays green in CI.
 */
module 
(module) io_uring_uring_cmd_socket

io_uringIORING_OP_URING_CMD passthrough on a socket (Linux 5.19).

IORING_OP_URING_CMD (Linux 5.19) is a generic "command" channel that lets a file's underlying driver service an ioctl/setsockopt-like request straight out of the ring, with no per-call syscall. The socket sub-commands (SOCKET_URING_OP_*, the cmd_op field — socket support landed in Linux 6.7) ride that channel. Here we drive a getsockopt/setsockopt round-trip on a loopback TCP socket entirely through the ring via prepCmdSock, instead of calling getsockopt(2) / setsockopt(2) directly.

What it does:

  1. Creates and binds a TCP socket to 127.0.0.1:0 with libc.

  2. Submits one uring_cmd SQE: SOCKET_URING_OP_GETSOCKOPT of SO_REUSEADDR, reading the option value through the ring; the option length comes back in the CQE res and the value buffer is filled in-place.

  3. Submits a SOCKET_URING_OP_SETSOCKOPT to flip SO_REUSEADDR on, then a second GETSOCKOPT to confirm the new value round-tripped — proving the passthrough moves data into the kernel and back out, not just succeeds.

uring_cmd on a socket needs no special hardware (unlike NVMe/block or ZCRX passthrough), so it runs on any 6.7+ loopback host — including this 6.18 box, where the feature MUST be exercised.

(Note: a SOCKET_URING_OP_GETSOCKNAME sub-command was proposed but never merged into mainline; on a live kernel it returns -EOPNOTSUPP. We therefore demonstrate the getsockopt/setsockopt sub-commands that the kernel actually implements.)

Companion to the io_uring chronology: see docs/research/async-io/io-uring/timeline.md § "5.19 — Buffer rings, zero-copy groundwork, big SQE/CQE".

Run with: dub run --single uring-cmd-socket.d

Portability

if the running kernel lacks io_uring (setup < 0) or this specific op is unsupported (-EINVAL / -EOPNOTSUPP / -ENOSYS), the program prints a SKIP: line and exits 0 so it stays green in CI.

io_uring_uring_cmd_socket
;
import
(module) during

Simple idiomatic dlang wrapper around linux io_uring (see: https://kernel.dk/io_uring.pdf) asynchronous API.

during
;
import
(package) core
core
.
(package) core.sys
sys
.
(package) core.sys.linux
linux
.
(module) core.sys.linux.errno

D header file for GNU/Linux

glibc stdlib/errno.h

errno
:
(alias constant) io_uring_uring_cmd_socket.EINVAL = int core.stdc.errno.EINVAL = 22
EINVAL
,
(alias constant) io_uring_uring_cmd_socket.EOPNOTSUPP = int core.stdc.errno.EOPNOTSUPP = 95
EOPNOTSUPP
,
(alias constant) io_uring_uring_cmd_socket.ENOSYS = int core.stdc.errno.ENOSYS = 38
ENOSYS
;
import
(package) core
core
.
(package) core.sys
sys
.
(package) core.sys.posix
posix
.
(package) core.sys.posix.arpa
arpa
.
(module) core.sys.posix.arpa.inet

D header file for POSIX.

@copyrightCopyright Sean Kelly 2005 - 2009.@licenseBoost License 1.0.@authorsSean Kelly@standardsThe Open Group Base Specifications Issue 6, IEEE Std 1003.1, 2004 Edition
inet
:
(alias) io_uring_uring_cmd_socket.htonl = uint core.sys.posix.arpa.inet.htonl(uint) pure nothrow @nogc @trusted
htonl
;
import
(package) core
core
.
(package) core.sys
sys
.
(package) core.sys.posix
posix
.
(package) core.sys.posix.netinet
netinet
.
(module) core.sys.posix.netinet.in_

D header file for POSIX.

@copyrightCopyright Sean Kelly 2005 - 2009.@licenseBoost License 1.0.@authorsSean Kelly@standardsThe Open Group Base Specifications Issue 6, IEEE Std 1003.1, 2004 Edition
in_
:
(struct) core.sys.posix.netinet.in_.sockaddr_in
sockaddr_in
,
(alias enum value) io_uring_uring_cmd_socket.AF_INET = core.sys.posix.sys.socket.AF_INET = 2
AF_INET
,
(alias enum value) io_uring_uring_cmd_socket.IPPROTO_TCP = core.sys.posix.netinet.in_.IPPROTO_TCP = 6
IPPROTO_TCP
;
import
(package) core
core
.
(package) core.sys
sys
.
(package) core.sys.posix
posix
.
(package) core.sys.posix.sys
sys
.
(module) core.sys.posix.sys.socket

D header file for POSIX.

@copyrightCopyright Sean Kelly 2005 - 2009.@licenseBoost License 1.0.@authorsSean Kelly, Alex Rønne Petersen@standardsThe Open Group Base Specifications Issue 6, IEEE Std 1003.1, 2004 Edition
socket
:
(alias) io_uring_uring_cmd_socket.socket = int core.sys.posix.sys.socket.socket(int, int, int) nothrow @nogc @safe
socket
,
(alias) io_uring_uring_cmd_socket.bind = int core.sys.posix.sys.socket.bind(int, scope const(core.sys.posix.sys.socket.sockaddr*), uint) nothrow @nogc
bind
,
(struct) core.sys.posix.sys.socket.sockaddr
sockaddr
, socklen_t,
(alias enum value) io_uring_uring_cmd_socket.SOCK_STREAM = core.sys.posix.sys.socket.SOCK_STREAM = 1
SOCK_STREAM
,
(alias enum value) io_uring_uring_cmd_socket.SOL_SOCKET = core.sys.posix.sys.socket.SOL_SOCKET = 1
SOL_SOCKET
,
(alias enum value) io_uring_uring_cmd_socket.SO_REUSEADDR = core.sys.posix.sys.socket.SO_REUSEADDR = 2
SO_REUSEADDR
;
import
(package) core
core
.
(package) core.sys
sys
.
(package) core.sys.posix
posix
.
(module) core.sys.posix.unistd

D header file for POSIX.

@copyrightCopyright Sean Kelly 2005 - 2009.@licenseBoost License 1.0.@authorsSean Kelly@standardsThe Open Group Base Specifications Issue 8, IEEE Std 1003.1, 2024 Edition
unistd
:
(alias) io_uring_uring_cmd_socket.close = int core.sys.posix.unistd.close(int) nothrow @nogc @trusted
close
;
import
(package) std
std
.
(module) std.stdio
Category Symbols
File handles _popen File isFileHandle openNetwork stderr stdin stdout
Reading chunks lines readf readfln readln
Writing toFile write writef writefln writeln
Misc KeepTerminator LockType StdioException

Standard I/O functions that extend core.stdc.stdio. core.stdc.stdio is publically imported when importing std.stdio.

There are three layers of I/O:

  1. The lowest layer is the operating system layer. The two main schemes are Windows and Posix.

  2. C's stdio.h which unifies the two operating system schemes.

  3. std.stdio, this module, unifies the various stdio.h implementations into a high level package for D programs.

Source

std/stdio.d

@copyrightCopyright The D Language Foundation 2007-.@licenseBoost License 1.0.@authorsWalter Bright, Andrei Alexandrescu, Alex Rønne Petersen
stdio
:
(alias template) io_uring_uring_cmd_socket.writefln = std.stdio.writefln(alias fmt, A...)(A args) if (isSomeString!(typeof(fmt)))

Equivalent to writef(fmt, args, '\n').

writefln
, stderr;
// during exposes the socket uring_cmd sub-commands as plain enums; spell them // out here so the example is self-contained and the cmd_op values are explicit. enum uint
(constant) uint io_uring_uring_cmd_socket.SOCKET_URING_OP_GETSOCKOPT = 2u
SOCKET_URING_OP_GETSOCKOPT
= 2;
enum uint
(constant) uint io_uring_uring_cmd_socket.SOCKET_URING_OP_SETSOCKOPT = 3u
SOCKET_URING_OP_SETSOCKOPT
= 3;
/// Submit one socket `uring_cmd` and return its CQE `res` (or a negative -errno). int
int io_uring_uring_cmd_socket.runCmdSock(ref during.Uring io, uint cmdOp, int fd, uint level, uint optname, void* optval, uint optlen)

Submit one socket uring_cmd and return its CQE res (or a negative -errno).

runCmdSock
(ref
(struct) during.Uring

Main entry point to work with io_uring.

It hides SubmissionQueue and CompletionQueue behind standard range interface. We put in SubmissionEntry entries and take out CompletionEntry entries.

Use predefined prepXX methods to fill required fields of SubmissionEntry before put or during putWith.

Note

prepXX functions doesn't touch previous entry state, just fills in operation properties. This is because for less error prone interface it is cleared automatically when prepared using putWith. So when using on own SubmissionEntry (outside submission queue), that would be added to the submission queue using put, be sure its cleared if it's reused for multiple operations.

Uring
(parameter) during.Uring io
io
, uint
(parameter) uint cmdOp
cmdOp
, int
(parameter) int fd
fd
, uint
(parameter) uint level
level
, uint
(parameter) uint optname
optname
,
void*
(parameter) void* optval
optval
, uint
(parameter) uint optlen
optlen
)
{ // Pass everything as explicit args so the prep lambda captures nothing — a // closure would force a GC-allocated dual-context delegate (rejected under // putWith's @nogc).
(parameter) during.Uring io
io
.putWith!((ref SubmissionEntry e, uint c, int f, uint lv, uint on, ulong ov, uint ol) {
e.prepCmdSock(c, f, lv, on, cast(void*)ov, ol); })(
during.Uring during.Uring.putWith!(function (ref during.io_uring.SubmissionEntry e, uint c, int f, uint lv, uint on, ulong ov, uint ol) nothrow @nogc @safe { prepCmdSock(e, c, f, lv, on, cast(void*)ov, ol); } , uint, int, uint, uint, ulong, uint)(ref uint __param_0, ref int __param_1, ref uint __param_2, ref uint __param_3, ulong __param_4, ref uint __param_5) nothrow @nogc return ref @safe

Adds new entry to the SubmissionQueue.

Note that this just adds entry to the queue and doesn't advance the tail marker kernel sees. For that finishSq() is needed to be called next.

Also note that to actually enter new entries to kernel, it's needed to call submit().

@paramFN Function to fill next entry in queue by ref (should be faster). It is expected to be in a form of void function(ARGS)(ref SubmissionEntry, auto ref ARGS). Note that in this case queue entry is cleaned first before function is called.@paramentry Custom built SubmissionEntry to be posted as is. Note that in this case it is copied whole over one in the SubmissionQueue.@paramargs Optional arguments passed to the function@returnsreference to Uring structure so it's possible to chain multiple commands.
cmdOp
,
(parameter) int fd
fd
,
(parameter) uint level
level
,
(parameter) uint optname
optname
, cast(ulong)
(parameter) void* optval
optval
,
(parameter) uint optlen
optlen
);
const
(local variable) const(int) submitted
submitted
=
(parameter) during.Uring io
io
.
int during.Uring.submit(uint want) nothrow @nogc @safe

Submits qued SubmissionEntry to be processed by kernel.

@paramwant number of CompletionEntries to wait for. If 0, this just submits queued entries and returns. If > 0, it blocks until at least wanted number of entries were completed.@paramsig See io_uring_enter(2) man page@returnsNumber of submitted entries on success, -errno on error
submit
(1);
if (
(local variable) const(int) submitted
submitted
< 0)
return
(local variable) const(int) submitted
submitted
; // -errno from submit
(parameter) during.Uring io
io
.
int during.Uring.wait(uint want = 1u) nothrow @nogc

Simmilar to submit but with this method we just wait for required number of CompletionEntries.

@returns0 on success, -errno on error
wait
(1);
const
(local variable) const(int) res
res
=
(parameter) during.Uring io
io
.
during.io_uring.CompletionEntry during.Uring.front() pure nothrow @nogc return ref @safe

Get first CompletionEntry from cq ring

front
.
(field) int during.io_uring.CompletionEntry.res

result code for this event

res
;
(parameter) during.Uring io
io
.
void during.Uring.popFront() pure nothrow @nogc @safe

Move to next CompletionEntry

popFront
();
return
(local variable) const(int) res
res
;
} int
int D main()
main
()
{
(struct) during.Uring

Main entry point to work with io_uring.

It hides SubmissionQueue and CompletionQueue behind standard range interface. We put in SubmissionEntry entries and take out CompletionEntry entries.

Use predefined prepXX methods to fill required fields of SubmissionEntry before put or during putWith.

Note

prepXX functions doesn't touch previous entry state, just fills in operation properties. This is because for less error prone interface it is cleared automatically when prepared using putWith. So when using on own SubmissionEntry (outside submission queue), that would be added to the submission queue using put, be sure its cleared if it's reused for multiple operations.

Uring
(local variable) during.Uring io
io
;
const
(local variable) const(int) setupRet
setupRet
=
(local variable) during.Uring io
io
.
int during.setup(ref during.Uring uring, uint entries = 128u, during.io_uring.SetupFlags flags = SetupFlags.NONE) nothrow @nogc @safe

Setup new instance of io_uring into provided Uring structure.

@paramuring Uring structure to be initialized (must not be already initialized)@paramentries Number of entries to initialize uring with@paramflags SetupFlags to use to initialize uring.@returnsOn succes it returns 0, -errno otherwise.
setup
(8);
if (
(local variable) const(int) setupRet
setupRet
< 0)
{
void std.stdio.writefln!(char, const(int))(in char[] fmt, const(int) __param_1) @safe

Equivalent to writef(fmt, args, '\n').

writefln
("SKIP: io_uring_setup failed (errno %d) — io_uring unavailable on this host",
-
(local variable) const(int) setupRet
setupRet
);
return 0; } // --- Bind a TCP socket to an ephemeral loopback port with plain libc. --- const int
(local variable) const(int) fd
fd
=
int core.sys.posix.sys.socket.socket(int, int, int) nothrow @nogc @safe
socket
(
(enum value) core.sys.posix.sys.socket.AF_INET = 2
AF_INET
,
(enum value) core.sys.posix.sys.socket.SOCK_STREAM = 1
SOCK_STREAM
,
(enum value) core.sys.posix.netinet.in_.IPPROTO_TCP = 6
IPPROTO_TCP
);
if (
(local variable) const(int) fd
fd
< 0)
{ stderr.
std.stdio.File std.stdio.makeGlobal!"core.stdc.stdio.stderr"() nothrow @nogc @property ref @system
writefln
("socket() failed");
return 1; } scope (exit)
int core.sys.posix.unistd.close(int) nothrow @nogc @trusted
close
(
(local variable) const(int) fd
fd
);
(struct) core.sys.posix.netinet.in_.sockaddr_in
sockaddr_in
(local variable) core.sys.posix.netinet.in_.sockaddr_in addr
addr
;
(local variable) core.sys.posix.netinet.in_.sockaddr_in addr
addr
.
(field) ushort core.sys.posix.netinet.in_.sockaddr_in.sin_family
sin_family
=
(enum value) core.sys.posix.sys.socket.AF_INET = 2
AF_INET
;
(local variable) core.sys.posix.netinet.in_.sockaddr_in addr
addr
.
(field) ushort core.sys.posix.netinet.in_.sockaddr_in.sin_port
sin_port
= 0; // 0 => kernel picks an ephemeral port
(local variable) core.sys.posix.netinet.in_.sockaddr_in addr
addr
.
(field) core.sys.posix.arpa.inet.in_addr core.sys.posix.netinet.in_.sockaddr_in.sin_addr
sin_addr
.
(field) uint core.sys.posix.arpa.inet.in_addr.s_addr
s_addr
=
uint core.sys.posix.arpa.inet.htonl(uint) pure nothrow @nogc @trusted
htonl
(0x7f00_0001); // 127.0.0.1
if (
int core.sys.posix.sys.socket.bind(int, scope const(core.sys.posix.sys.socket.sockaddr*), uint) nothrow @nogc
bind
(
(local variable) const(int) fd
fd
, cast(
(struct) core.sys.posix.sys.socket.sockaddr
sockaddr
*)&
(local variable) core.sys.posix.netinet.in_.sockaddr_in addr
addr
,
(struct) core.sys.posix.netinet.in_.sockaddr_in
sockaddr_in
.
(constant) ulong core.sys.posix.netinet.in_.sockaddr_in.sizeof = 16LU
sizeof
) != 0)
{ stderr.
std.stdio.File std.stdio.makeGlobal!"core.stdc.stdio.stderr"() nothrow @nogc @property ref @system
writefln
("bind() failed");
return 1; } // --- 1) Read SO_REUSEADDR through the ring (SOCKET_URING_OP_GETSOCKOPT). --- // The socket driver fills `before` in-place; the returned optlen lands in res. int
(local variable) int before
before
= -1;
socklen_t
(local variable) uint vlen
vlen
=
(local variable) int before
before
.
(constant) ulong int.sizeof = 4LU
sizeof
;
const
(local variable) const(int) getRes
getRes
=
int io_uring_uring_cmd_socket.runCmdSock(ref during.Uring io, uint cmdOp, int fd, uint level, uint optname, void* optval, uint optlen)

Submit one socket uring_cmd and return its CQE res (or a negative -errno).

runCmdSock
(
(local variable) during.Uring io
io
,
(constant) uint io_uring_uring_cmd_socket.SOCKET_URING_OP_GETSOCKOPT = 2u
SOCKET_URING_OP_GETSOCKOPT
,
(local variable) const(int) fd
fd
,
(enum value) core.sys.posix.sys.socket.SOL_SOCKET = 1
SOL_SOCKET
,
(enum value) core.sys.posix.sys.socket.SO_REUSEADDR = 2
SO_REUSEADDR
, &
(local variable) int before
before
,
(local variable) uint vlen
vlen
);
// URING_CMD itself, or the socket sub-command, may be absent on older // kernels — treat those as a clean SKIP rather than a hard failure. if (
(local variable) const(int) getRes
getRes
== -
(constant) int core.stdc.errno.EINVAL = 22
EINVAL
||
(local variable) const(int) getRes
getRes
== -
(constant) int core.stdc.errno.EOPNOTSUPP = 95
EOPNOTSUPP
||
(local variable) const(int) getRes
getRes
== -
(constant) int core.stdc.errno.ENOSYS = 38
ENOSYS
)
{
void std.stdio.writefln!(char, const(int))(in char[] fmt, const(int) __param_1) @safe

Equivalent to writef(fmt, args, '\n').

writefln
("SKIP: IORING_OP_URING_CMD / SOCKET_URING_OP_GETSOCKOPT unsupported (errno %d)",
-
(local variable) const(int) getRes
getRes
);
return 0; } if (
(local variable) const(int) getRes
getRes
< 0)
{ stderr.
std.stdio.File std.stdio.makeGlobal!"core.stdc.stdio.stderr"() nothrow @nogc @property ref @system
writefln
("uring_cmd getsockopt failed: errno %d", -
(local variable) const(int) getRes
getRes
);
return 1; } // On success, getsockopt reports the option length (sizeof(int)) in res. if (
(local variable) const(int) getRes
getRes
!= cast(int)
(local variable) int before
before
.
(constant) ulong int.sizeof = 4LU
sizeof
)
{ stderr.
std.stdio.File std.stdio.makeGlobal!"core.stdc.stdio.stderr"() nothrow @nogc @property ref @system
writefln
("unexpected getsockopt optlen: res=%d (expected %d)",
(local variable) const(int) getRes
getRes
, cast(int)
(local variable) int before
before
.
(constant) ulong int.sizeof = 4LU
sizeof
);
return 1; } // --- 2) Flip SO_REUSEADDR on through the ring (SOCKET_URING_OP_SETSOCKOPT). --- int
(local variable) int on
on
= 1;
const
(local variable) const(int) setRes
setRes
=
int io_uring_uring_cmd_socket.runCmdSock(ref during.Uring io, uint cmdOp, int fd, uint level, uint optname, void* optval, uint optlen)

Submit one socket uring_cmd and return its CQE res (or a negative -errno).

runCmdSock
(
(local variable) during.Uring io
io
,
(constant) uint io_uring_uring_cmd_socket.SOCKET_URING_OP_SETSOCKOPT = 3u
SOCKET_URING_OP_SETSOCKOPT
,
(local variable) const(int) fd
fd
,
(enum value) core.sys.posix.sys.socket.SOL_SOCKET = 1
SOL_SOCKET
,
(enum value) core.sys.posix.sys.socket.SO_REUSEADDR = 2
SO_REUSEADDR
, &
(local variable) int on
on
,
(local variable) int on
on
.
(constant) ulong int.sizeof = 4LU
sizeof
);
if (
(local variable) const(int) setRes
setRes
< 0)
{ stderr.
std.stdio.File std.stdio.makeGlobal!"core.stdc.stdio.stderr"() nothrow @nogc @property ref @system
writefln
("uring_cmd setsockopt failed: errno %d", -
(local variable) const(int) setRes
setRes
);
return 1; } // --- 3) Read it back to confirm the write took effect (round-trip proof). --- int
(local variable) int after
after
= -1;
const
(local variable) const(int) getRes2
getRes2
=
int io_uring_uring_cmd_socket.runCmdSock(ref during.Uring io, uint cmdOp, int fd, uint level, uint optname, void* optval, uint optlen)

Submit one socket uring_cmd and return its CQE res (or a negative -errno).

runCmdSock
(
(local variable) during.Uring io
io
,
(constant) uint io_uring_uring_cmd_socket.SOCKET_URING_OP_GETSOCKOPT = 2u
SOCKET_URING_OP_GETSOCKOPT
,
(local variable) const(int) fd
fd
,
(enum value) core.sys.posix.sys.socket.SOL_SOCKET = 1
SOL_SOCKET
,
(enum value) core.sys.posix.sys.socket.SO_REUSEADDR = 2
SO_REUSEADDR
, &
(local variable) int after
after
,
(local variable) uint vlen
vlen
);
if (
(local variable) const(int) getRes2
getRes2
< 0)
{ stderr.
std.stdio.File std.stdio.makeGlobal!"core.stdc.stdio.stderr"() nothrow @nogc @property ref @system
writefln
("uring_cmd getsockopt (after set) failed: errno %d", -
(local variable) const(int) getRes2
getRes2
);
return 1; } if (
(local variable) int after
after
== 0)
{ stderr.
std.stdio.File std.stdio.makeGlobal!"core.stdc.stdio.stderr"() nothrow @nogc @property ref @system
writefln
("SO_REUSEADDR still off after uring_cmd setsockopt (got %d)",
(local variable) int after
after
);
return 1; }
void std.stdio.writefln!(char, int, int)(in char[] fmt, int __param_1, int __param_2) @safe

Equivalent to writef(fmt, args, '\n').

writefln
("ok: IORING_OP_URING_CMD socket passthrough — getsockopt SO_REUSEADDR=%d, "
~ "setsockopt=1, re-read=%d (all through the ring)",
(local variable) int before
before
,
(local variable) int after
after
);
return 0; }