#ifndef DTACT_UTIL_H
#define DTACT_UTIL_H

/* Generated with cbindgen:0.29.4 */

/* Warning, this file is autogenerated by cbindgen. Don't modify this manually. */

#include <stdarg.h>
#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>
#include <stdlib.h>

/*
 Stdio bitmask flag: route the child's stderr through a pipe.
 */
#define DTACT_STDERR_PIPE 4

/*
 Stdio bitmask flag: route the child's stdin through a pipe.
 */
#define DTACT_STDIN_PIPE 1

/*
 Stdio bitmask flag: route the child's stdout through a pipe.
 */
#define DTACT_STDOUT_PIPE 2

/*
 Max concurrent listeners for a single signal kind. Generous for real
 programs (which typically register one listener per signal kind, at
 startup) without the registry needing dynamic growth.
 */
#define MAX_LISTENERS 16

/*
 A spawned child process.

 `wait`/`wait_with_output` consume `self` (ownership transfers into the
 pool closure, so nothing needs to be shared or locked); `kill`/`id`
 are synchronous since they're fast, non-blocking syscalls.
 */
typedef struct DtactChild DtactChild;

/*
 One end of a child process's stderr pipe.

 Exclusively owned by whoever holds it (returned by `take_stderr` on
 `DtactChild`) — each async op temporarily moves the handle into a pool
 closure and gets it back in the result, never shared behind a lock.
 */
typedef struct DtactChildStderr DtactChildStderr;

/*
 One end of a child process's stdin pipe.

 Exclusively owned by whoever holds it (returned by `take_stdin` on
 `DtactChild`) — each async op temporarily moves the handle into a pool
 closure and gets it back in the result, never shared behind a lock.
 */
typedef struct DtactChildStdin DtactChildStdin;

/*
 One end of a child process's stdout pipe.

 Exclusively owned by whoever holds it (returned by `take_stdout` on
 `DtactChild`) — each async op temporarily moves the handle into a pool
 closure and gets it back in the result, never shared behind a lock.
 */
typedef struct DtactChildStdout DtactChildStdout;

/*
 An open file whose reads/writes are dispatched as real overlapped IOCP
 operations — no thread-pool hop, buffer handed straight to the kernel.
 */
typedef struct DtactFile DtactFile;

#if defined(DTACT_LINUX)
/*
 An open file whose ops are submitted as real `io_uring` SQEs.
 */
typedef struct DtactFile DtactFile;
#endif

#if !defined(DTACT_LINUX)
/*
 An open file whose blocking read/write/metadata operations run on the
 dtact-fs thread pool rather than the calling task's thread.
 */
typedef struct DtactFile DtactFile;
#endif

/*
 A repeating timer. `tick()` is a plain async method mirroring
 `tokio::time::Interval::tick`.
 */
typedef struct DtactInterval DtactInterval;

/*
 A repeating timer. `tick()` mirrors `tokio::time::Interval::tick`.
 */
typedef struct DtactInterval DtactInterval;

/*
 One named-pipe connection — the read/write half shared by
 [`DtactNamedPipeServer`] (after a client connects) and
 [`DtactNamedPipeClient`].
 */
typedef struct DtactNamedPipeHandle DtactNamedPipeHandle;

/*
 One named-pipe connection — the read/write half shared by
 [`DtactNamedPipeServer`] (after a client connects) and
 [`DtactNamedPipeClient`].
 */
typedef struct DtactNamedPipeHandle DtactNamedPipeHandle;

/*
 A single named-pipe server instance, before a client has connected.

 Create one per client you intend to accept — see the module doc's
 "no pipe-instance pooling" paragraph for why there's no persistent
 listener type the way TCP has [`super::DtactTcpListener`].
 */
typedef struct DtactNamedPipeServer DtactNamedPipeServer;

/*
 A single named-pipe server instance, before a client has connected.

 Create one per client you intend to accept — see this module's doc.
 */
typedef struct DtactNamedPipeServer DtactNamedPipeServer;

/*
 A stream of a specific signal's deliveries — call `.recv().await`
 repeatedly, once per delivery, mirroring `tokio::signal::unix::Signal`.
 */
typedef struct DtactSignalStream DtactSignalStream;

/*
 A stream of a specific console-control event's deliveries — call
 `.recv().await` repeatedly, mirroring `tokio::signal::windows`.
 */
typedef struct DtactSignalStream DtactSignalStream;

/*
 A stream of occurrences of one Unix signal.

 Backed by tokio's signal-fd/self-pipe reactor integration instead
 of dtact-signal's own registry. Unlike the native backend, each
 instance owns its own OS-level registration rather than sharing a
 broadcast registry.
 */
typedef struct DtactSignalStream DtactSignalStream;

/*
 A stream of occurrences of one Windows console-control event.

 Covers `Ctrl+C`, `Ctrl+Break`, window-close, logoff, and shutdown,
 backed by tokio's console-handler reactor integration instead of
 dtact-signal's own registry. Mirrors the native backend's
 `DtactSignalStream` — same five events, see its module doc for
 what each one means and the grace-period caveat that applies to
 the latter three.
 */
typedef struct DtactSignalStream DtactSignalStream;

/*
 One end of an in-process duplex pipe. Create a connected pair with
 [`pair`].
 */
typedef struct DtactStream DtactStream;

/*
 A lock-free, non-blocking TCP listener registered with the dtact-io
 driver. Mirrors the Windows backend's `DtactTcpListener` API so callers
 can switch platforms without code changes.
 */
typedef struct DtactTcpListener DtactTcpListener;

/*
 An async TCP listener backed by IOCP-issued `AcceptEx`.
 */
typedef struct DtactTcpListener DtactTcpListener;

/*
 Tokio-backed TCP listener. Mirrors the native backend's
 `DtactTcpListener` API surface.
 */
typedef struct DtactTcpListener DtactTcpListener;

/*
 A lock-free, non-blocking TCP stream registered with the dtact-io
 driver. Mirrors the Windows backend's `DtactTcpStream` API so callers
 can switch platforms without code changes.
 */
typedef struct DtactTcpStream DtactTcpStream;

/*
 An async TCP stream backed by IOCP-issued `WSARecv`/`WSASend`.
 */
typedef struct DtactTcpStream DtactTcpStream;

/*
 Tokio-backed TCP stream. Mirrors the native backend's `DtactTcpStream`
 API surface, but drives readiness through tokio's reactor instead of the
 crate's own `IOCP`/`io_uring`/kqueue driver.
 */
typedef struct DtactTcpStream DtactTcpStream;

/*
 Async UDP socket driven by the native backend (`io_uring` `SendMsg`/`RecvMsg`
 on Linux, `sendmsg`/`recvmsg` via the mio/kqueue reactor elsewhere).

 Supports the connectionless (`send_to`/`recv_from`) and connected
 (`connect`/`send`/`recv`) patterns, mirroring `std::net::UdpSocket`'s and
 `tokio::net::UdpSocket`'s API shape. The connected `send`/`recv` reuse the
 same `Write`/`Read` submission machinery as [`DtactTcpStream`].
 */
typedef struct DtactUdpSocket DtactUdpSocket;

/*
 Async UDP socket driven by the IOCP backend.

 Supports the connectionless (`send_to`/`recv_from`) and connected
 (`connect`/`send`/`recv`) patterns, mirroring `std::net::UdpSocket`'s and
 `tokio::net::UdpSocket`'s API shape. `send_to`/`recv_from` issue overlapped
 `WSASendTo`/`WSARecvFrom` ops; the connected `send`/`recv` reuse the same
 `WSASend`/`WSARecv` machinery as [`DtactTcpStream`].
 */
typedef struct DtactUdpSocket DtactUdpSocket;

/*
 Async UDP socket — tokio-backend equivalent of the native
 `DtactUdpSocket`, a thin wrapper over [`tokio::net::UdpSocket`].

 Mirrors the connectionless (`send_to`/`recv_from`) and connected
 (`connect`/`send`/`recv`) halves of `std::net::UdpSocket`'s and
 `tokio::net::UdpSocket`'s API so call-sites port across backends with a
 single feature flag.
 */
typedef struct DtactUdpSocket DtactUdpSocket;

/*
 Async Unix-domain datagram socket.

 Connectionless counterpart to [`DtactUnixStream`], directly analogous
 to [`DtactUdpSocket`] (same connectionless `send_to`/`recv_from` and
 connected `connect`/`send`/`recv` pattern, same `SendTo`/`RecvFrom`/
 `Read`/`Write` submission machinery — only the address family and the
 `libc::sockaddr_un` construction differ).
 */
typedef struct DtactUnixDatagram DtactUnixDatagram;

/*
 Async Unix-domain datagram socket — tokio-backend equivalent of the
 native `DtactUnixDatagram`, a thin wrapper over
 [`tokio::net::UnixDatagram`].

 Mirrors [`DtactUdpSocket`]'s connectionless/connected split. Unlike
 the native backend (which has to hand-parse a raw `sockaddr_un` into
 its own address type), `recv_from` here just returns tokio's own
 `tokio::net::unix::SocketAddr` directly.
 */
typedef struct DtactUnixDatagram DtactUnixDatagram;

/*
 A lock-free, non-blocking Unix-domain-socket listener registered with
 the dtact-io driver. Mirrors [`DtactTcpListener`]'s API.
 */
typedef struct DtactUnixListener DtactUnixListener;

/*
 Tokio-backed Unix-domain-socket listener. Mirrors the native backend's
 `DtactUnixListener` API surface.
 */
typedef struct DtactUnixListener DtactUnixListener;

/*
 A lock-free, non-blocking Unix-domain-socket stream registered with
 the dtact-io driver. Mirrors [`DtactTcpStream`]'s API.
 */
typedef struct DtactUnixStream DtactUnixStream;

/*
 Tokio-backed Unix-domain-socket stream. Mirrors the native backend's
 `DtactUnixStream` API surface.
 */
typedef struct DtactUnixStream DtactUnixStream;

#ifdef __cplusplus
extern "C" {
#endif // __cplusplus

/*
 Resolve `path` to an absolute path with all intermediate components
 resolved, writing it (NUL-terminated, truncated if it doesn't fit)
 into `out` (capacity `out_cap`).

 Returns the untruncated resolved path's byte length on success, or -1
 on error.

 # Safety

 See the [`crate::ffi`] module-level Safety contract. `path` must be a
 valid NUL-terminated C string; `out`, if non-null, must point to at
 least `out_cap` writable bytes.
 */

ptrdiff_t dtact_util_fs_canonicalize(const char *aPath,
                                     char *aOut,
                                     size_t aOutCap)
;

/*
 Copy the contents (and permission bits) of the file at `from` to `to`,
 returning the byte count copied, or -1 on error.

 # Safety

 See the [`crate::ffi`] module-level Safety contract. `from`/`to` must
 be valid NUL-terminated C strings.
 */
 int64_t dtact_util_fs_copy(const char *aFrom, const char *aTo) ;

/*
 Create a single new directory. Unlike
 [`dtact_util_fs_create_dir_all`], fails if any parent component
 doesn't already exist. Returns 0 on success, -1 on error.

 # Safety

 See the [`crate::ffi`] module-level Safety contract. `path` must be a
 valid NUL-terminated C string.
 */
 int32_t dtact_util_fs_create_dir(const char *aPath) ;

/*
 Recursively create `path` and any missing parent directories. Returns
 0 on success, -1 on error.

 # Safety

 See the [`crate::ffi`] module-level Safety contract. `path` must be a
 valid NUL-terminated C string.
 */
 int32_t dtact_util_fs_create_dir_all(const char *aPath) ;

/*
 Close and free a file handle. Passing null is a no-op.

 # Safety

 See the [`crate::ffi`] module-level Safety contract. `file` must have
 come from a `dtact_util_fs_file_*` constructor and must not be used
 afterwards.
 */
 void dtact_util_fs_file_close(struct DtactFile *aFile) ;

/*
 Create (truncating) the file at `path`, returning an owning handle or
 null on error. Free with [`dtact_util_fs_file_close`].

 # Safety

 See the [`crate::ffi`] module-level Safety contract. `path` must be a
 valid NUL-terminated C string.
 */
 struct DtactFile *dtact_util_fs_file_create(const char *aPath) ;

/*
 Open the existing file at `path` for reading, returning an owning handle
 or null on error. Free with [`dtact_util_fs_file_close`].

 # Safety

 See the [`crate::ffi`] module-level Safety contract. `path` must be a
 valid NUL-terminated C string.
 */
 struct DtactFile *dtact_util_fs_file_open(const char *aPath) ;

/*
 Read up to `len` bytes from `file` (advancing its cursor) into `buf`.
 Returns the byte count read (0 = EOF) or -1 on error.

 # Safety

 See the [`crate::ffi`] module-level Safety contract.
 */

ptrdiff_t dtact_util_fs_file_read(struct DtactFile *aFile,
                                  uint8_t *aBuf,
                                  size_t aLen)
;

/*
 Read up to `len` bytes from `file` at absolute `offset` (not affecting
 its cursor) into `buf`. Returns the byte count read (0 = EOF) or -1 on
 error.

 # Safety

 See the [`crate::ffi`] module-level Safety contract.
 */

ptrdiff_t dtact_util_fs_file_read_at(struct DtactFile *aFile,
                                     uint8_t *aBuf,
                                     size_t aLen,
                                     uint64_t aOffset)
;

/*
 Flush `file`'s buffers to disk (`FlushFileBuffers`/`fsync`). Returns 0 on
 success, -1 on error.

 # Safety

 See the [`crate::ffi`] module-level Safety contract.
 */
 int32_t dtact_util_fs_file_sync(struct DtactFile *aFile) ;

/*
 Write `len` bytes from `buf` to `file` (advancing its cursor). Returns
 the byte count written or -1 on error.

 # Safety

 See the [`crate::ffi`] module-level Safety contract.
 */

ptrdiff_t dtact_util_fs_file_write(struct DtactFile *aFile,
                                   const uint8_t *aBuf,
                                   size_t aLen)
;

/*
 Write `len` bytes from `buf` to `file` at absolute `offset` (not
 affecting its cursor). Returns the byte count written or -1 on error.

 # Safety

 See the [`crate::ffi`] module-level Safety contract.
 */

ptrdiff_t dtact_util_fs_file_write_at(struct DtactFile *aFile,
                                      const uint8_t *aBuf,
                                      size_t aLen,
                                      uint64_t aOffset)
;

/*
 Create a hard link at `dst` pointing at the same file as `src`.
 Returns 0 on success, -1 on error.

 # Safety

 See the [`crate::ffi`] module-level Safety contract. `src`/`dst` must
 be valid NUL-terminated C strings.
 */
 int32_t dtact_util_fs_hard_link(const char *aSrc, const char *aDst) ;

/*
 Initialize the fs backend with `workers` worker threads. Idempotent.

 # Safety

 See the [`crate::ffi`] module-level Safety contract. Takes no pointers.
 */
 void dtact_util_fs_init(size_t aWorkers) ;

/*
 Read the entire contents of the file at `path` into `buf` (capacity
 `len`).

 Returns the file's total byte length (which may exceed `len`, in
 which case `buf` received only the first `len` bytes) on success, or
 -1 on error.

 # Safety

 See the [`crate::ffi`] module-level Safety contract. `path` must be a
 valid NUL-terminated C string; `buf`, if non-null, must point to at
 least `len` writable bytes.
 */
 ptrdiff_t dtact_util_fs_read(const char *aPath, uint8_t *aBuf, size_t aLen) ;

/*
 Read the target of the symbolic link at `path` into `out` (capacity
 `out_cap`), NUL-terminated and truncated if it doesn't fit.

 Returns the untruncated target's byte length (which may exceed
 `out_cap`) on success, or -1 on error.

 # Safety

 See the [`crate::ffi`] module-level Safety contract. `path` must be a
 valid NUL-terminated C string; `out`, if non-null, must point to at
 least `out_cap` writable bytes.
 */

ptrdiff_t dtact_util_fs_read_link(const char *aPath,
                                  char *aOut,
                                  size_t aOutCap)
;

/*
 Read the entire contents of the file at `path` as UTF-8 text into
 `out` (capacity `out_cap`), NUL-terminated and truncated if it doesn't
 fit.

 Returns the untruncated content's byte length on success, or -1 on
 error (including `InvalidData` if the file isn't valid UTF-8).

 # Safety

 See the [`crate::ffi`] module-level Safety contract. `path` must be a
 valid NUL-terminated C string; `out`, if non-null, must point to at
 least `out_cap` writable bytes.
 */

ptrdiff_t dtact_util_fs_read_to_string(const char *aPath,
                                       char *aOut,
                                       size_t aOutCap)
;

/*
 Remove an empty directory. Fails if `path` is non-empty — see
 [`dtact_util_fs_remove_dir_all`] for the recursive version. Returns 0
 on success, -1 on error.

 # Safety

 See the [`crate::ffi`] module-level Safety contract. `path` must be a
 valid NUL-terminated C string.
 */
 int32_t dtact_util_fs_remove_dir(const char *aPath) ;

/*
 Recursively remove a directory and everything under it. Returns 0 on
 success, -1 on error.

 # Safety

 See the [`crate::ffi`] module-level Safety contract. `path` must be a
 valid NUL-terminated C string.
 */
 int32_t dtact_util_fs_remove_dir_all(const char *aPath) ;

/*
 Remove (unlink) the file at `path`. Returns 0 on success, -1 on error.

 # Safety

 See the [`crate::ffi`] module-level Safety contract. `path` must be a
 valid NUL-terminated C string.
 */
 int32_t dtact_util_fs_remove_file(const char *aPath) ;

/*
 Rename (move) the file or directory at `from` to `to`, replacing `to`
 if it already exists. Returns 0 on success, -1 on error.

 # Safety

 See the [`crate::ffi`] module-level Safety contract. `from`/`to` must
 be valid NUL-terminated C strings.
 */
 int32_t dtact_util_fs_rename(const char *aFrom, const char *aTo) ;

/*
 Set `path` read-only (`readonly != 0`) or read-write (`readonly ==
 0`).

 A thin, portable slice of `std::fs::Permissions` — the only bit
 consistently meaningful to set/query across Unix and Windows. Returns
 0 on success, -1 on error.

 # Safety

 See the [`crate::ffi`] module-level Safety contract. `path` must be a
 valid NUL-terminated C string.
 */
 int32_t dtact_util_fs_set_readonly(const char *aPath, int32_t aReadonly) ;

/*
 Create a symbolic link at `dst` pointing at `src`. Unix only —
 Windows callers need [`dtact_util_fs_symlink_dir`]/
 [`dtact_util_fs_symlink_file`] instead. Returns 0 on success, -1 on
 error.

 # Safety

 See the [`crate::ffi`] module-level Safety contract. `src`/`dst` must
 be valid NUL-terminated C strings.
 */
 int32_t dtact_util_fs_symlink(const char *aSrc, const char *aDst) ;

/*
 Create a directory symbolic link at `dst` pointing at `src`. Windows
 only — see [`dtact_util_fs_symlink`] for the Unix equivalent. Returns
 0 on success, -1 on error.

 # Safety

 See the [`crate::ffi`] module-level Safety contract. `src`/`dst` must
 be valid NUL-terminated C strings.
 */
 int32_t dtact_util_fs_symlink_dir(const char *aSrc, const char *aDst) ;

/*
 Create a file symbolic link at `dst` pointing at `src`. Windows only —
 see [`dtact_util_fs_symlink`] for the Unix equivalent. Returns 0 on
 success, -1 on error.

 # Safety

 See the [`crate::ffi`] module-level Safety contract. `src`/`dst` must
 be valid NUL-terminated C strings.
 */
 int32_t dtact_util_fs_symlink_file(const char *aSrc, const char *aDst) ;

/*
 Check whether `path` exists, following symlinks. Returns `1` if it
 exists, `0` if it doesn't, or `-1` on any other error (e.g.
 `PermissionDenied` on a parent directory).

 # Safety

 See the [`crate::ffi`] module-level Safety contract. `path` must be a
 valid NUL-terminated C string.
 */
 int32_t dtact_util_fs_try_exists(const char *aPath) ;

/*
 Write `len` bytes from `buf` to the file at `path`, creating it if it
 doesn't exist and truncating it if it does. Returns 0 on success, -1
 on error.

 # Safety

 See the [`crate::ffi`] module-level Safety contract. `path` must be a
 valid NUL-terminated C string; `buf` must point to at least `len`
 readable bytes.
 */

int32_t dtact_util_fs_write(const char *aPath,
                            const uint8_t *aBuf,
                            size_t aLen)
;

/*
 Initialize the TCP runtime with `workers` I/O worker threads. Idempotent;
 the first call wins.

 # Safety

 See the [`crate::ffi`] module-level Safety contract. Takes no pointers.
 */
 void dtact_util_io_init(size_t aWorkers) ;

/*
 Block until a client connects, returning an owning stream handle (free
 with [`dtact_util_io_stream_close`]) or null on error.

 # Safety

 See the [`crate::ffi`] module-level Safety contract. `listener` must be a
 live handle from [`dtact_util_io_listener_bind`].
 */

struct DtactTcpStream *dtact_util_io_listener_accept(struct DtactTcpListener *aListener)
;

/*
 Bind a TCP listener to `addr` (e.g. `"127.0.0.1:8080"`). Returns an
 owning handle or null on error. Free with
 [`dtact_util_io_listener_close`].

 # Safety

 See the [`crate::ffi`] module-level Safety contract. `addr` must be a
 valid NUL-terminated C string.
 */
 struct DtactTcpListener *dtact_util_io_listener_bind(const char *aAddr) ;

/*
 Close and free a listener handle. Passing null is a no-op.

 # Safety

 See the [`crate::ffi`] module-level Safety contract.
 */
 void dtact_util_io_listener_close(struct DtactTcpListener *aListener) ;

/*
 Resolve `host` (a `"host:port"` string) to zero or more socket
 addresses.

 Writes them as a single `;`-separated NUL-terminated string (e.g.
 `"127.0.0.1:80;[::1]:80"`) into `out` (capacity `out_cap`, truncated
 at a whole-address boundary if it doesn't fit). Returns the number of
 addresses found (which may be more than fit in
 `out`), or -1 on error.

 # Safety

 See the [`crate::ffi`] module-level Safety contract. `host` must be a
 valid NUL-terminated C string. `out`, if non-null, must point to at
 least `out_cap` writable bytes.
 */

ptrdiff_t dtact_util_io_lookup_host(const char *aHost,
                                    char *aOut,
                                    size_t aOutCap)
;

/*
 Connect to the named-pipe server instance named `name`, blocking until
 connected (retrying while every existing instance is busy).

 Returns an
 owning handle or null on error. Free with [`dtact_util_io_pipe_close`].

 # Safety

 See the [`crate::ffi`] module-level Safety contract. `name` must be a
 valid NUL-terminated C string.
 */

struct DtactNamedPipeHandle *dtact_util_io_pipe_client_connect(const char *aName)
;

/*
 Close and free a connected named-pipe handle. Passing null is a no-op.

 # Safety

 See the [`crate::ffi`] module-level Safety contract.
 */
 void dtact_util_io_pipe_close(struct DtactNamedPipeHandle *aPipe) ;

/*
 Read up to `len` bytes from `pipe` into `buf`. Returns the byte count
 read (0 = orderly close by peer) or -1 on error.

 # Safety

 See the [`crate::ffi`] module-level Safety contract.
 */

ptrdiff_t dtact_util_io_pipe_read(struct DtactNamedPipeHandle *aPipe,
                                  uint8_t *aBuf,
                                  size_t aLen)
;

/*
 Close and free a not-yet-connected pipe server handle. Passing null is
 a no-op.

 # Safety

 See the [`crate::ffi`] module-level Safety contract.
 */
 void dtact_util_io_pipe_server_close(struct DtactNamedPipeServer *aServer) ;

/*
 Block until a client connects to `server`.

 Takes ownership of `server`
 (it must not be used again, freed, or passed to this function twice,
 regardless of whether this call succeeds) and returns an owning
 connected-handle pointer, or null on error. Free the result with
 [`dtact_util_io_pipe_close`].

 # Safety

 See the [`crate::ffi`] module-level Safety contract. `server` must be a
 live handle from [`dtact_util_io_pipe_server_create`].
 */

struct DtactNamedPipeHandle *dtact_util_io_pipe_server_connect(struct DtactNamedPipeServer *aServer)
;

/*
 Create a new named-pipe server instance named `name`.

 E.g. `r"\\.\pipe\my-app"`. Returns an owning handle or null on error. Every
 instance accepts exactly one client — see
 [`crate::io::DtactNamedPipeServer`]'s own doc for why there's no
 persistent listener type here the way TCP/Unix sockets have one. Free
 with [`dtact_util_io_pipe_server_close`], or consume it with
 [`dtact_util_io_pipe_server_connect`].

 # Safety

 See the [`crate::ffi`] module-level Safety contract. `name` must be a
 valid NUL-terminated C string.
 */

struct DtactNamedPipeServer *dtact_util_io_pipe_server_create(const char *aName)
;

/*
 Write up to `len` bytes from `buf` to `pipe`. Returns the byte count
 written or -1 on error.

 # Safety

 See the [`crate::ffi`] module-level Safety contract.
 */

ptrdiff_t dtact_util_io_pipe_write(struct DtactNamedPipeHandle *aPipe,
                                   const uint8_t *aBuf,
                                   size_t aLen)
;

/*
 Close and free a TCP stream handle. Passing null is a no-op.

 # Safety

 See the [`crate::ffi`] module-level Safety contract.
 */
 void dtact_util_io_stream_close(struct DtactTcpStream *aStream) ;

/*
 Connect to `addr`, blocking until connected. Returns an owning stream
 handle or null on error. Free with [`dtact_util_io_stream_close`].

 # Safety

 See the [`crate::ffi`] module-level Safety contract. `addr` must be a
 valid NUL-terminated C string.
 */
 struct DtactTcpStream *dtact_util_io_stream_connect(const char *aAddr) ;

/*
 Read up to `len` bytes from `stream` into `buf`. Returns the byte count
 read (0 = orderly shutdown by peer) or -1 on error.

 # Safety

 See the [`crate::ffi`] module-level Safety contract.
 */

ptrdiff_t dtact_util_io_stream_read(struct DtactTcpStream *aStream,
                                    uint8_t *aBuf,
                                    size_t aLen)
;

/*
 Write up to `len` bytes from `buf` to `stream`. Returns the byte count
 written or -1 on error.

 # Safety

 See the [`crate::ffi`] module-level Safety contract.
 */

ptrdiff_t dtact_util_io_stream_write(struct DtactTcpStream *aStream,
                                     const uint8_t *aBuf,
                                     size_t aLen)
;

/*
 Bind a UDP socket to `addr` (e.g. `"127.0.0.1:8080"`, or `"0.0.0.0:0"`
 for an ephemeral port). Returns an owning handle or null on error. Free
 with [`dtact_util_io_udp_close`].

 # Safety

 See the [`crate::ffi`] module-level Safety contract. `addr` must be a
 valid NUL-terminated C string.
 */
 struct DtactUdpSocket *dtact_util_io_udp_bind(const char *aAddr) ;

/*
 Close and free a UDP socket handle. Passing null is a no-op.

 # Safety

 See the [`crate::ffi`] module-level Safety contract.
 */
 void dtact_util_io_udp_close(struct DtactUdpSocket *aSock) ;

/*
 Connect `sock` to `addr` so [`dtact_util_io_udp_send`]/
 [`dtact_util_io_udp_recv`] can omit the peer address. Returns 0 on
 success, -1 on error.

 # Safety

 See the [`crate::ffi`] module-level Safety contract. `addr` must be a
 valid NUL-terminated C string.
 */

int32_t dtact_util_io_udp_connect(struct DtactUdpSocket *aSock,
                                  const char *aAddr)
;

/*
 Receive a datagram from the connected peer into `buf`. Returns the byte
 count received, or -1 on error.

 # Safety

 See the [`crate::ffi`] module-level Safety contract.
 */

ptrdiff_t dtact_util_io_udp_recv(struct DtactUdpSocket *aSock,
                                 uint8_t *aBuf,
                                 size_t aLen)
;

/*
 Receive a single datagram into `buf` (capacity `len`).

 On success writes the sender's `"host:port"` address as a
 NUL-terminated string into `out_addr` (capacity `out_addr_cap`,
 truncated if it doesn't fit) and returns the byte count received;
 returns -1 on error.

 # Safety

 See the [`crate::ffi`] module-level Safety contract. `out_addr`, if
 non-null, must point to at least `out_addr_cap` writable bytes.
 */

ptrdiff_t dtact_util_io_udp_recv_from(struct DtactUdpSocket *aSock,
                                      uint8_t *aBuf,
                                      size_t aLen,
                                      char *aOutAddr,
                                      size_t aOutAddrCap)
;

/*
 Send `len` bytes from `buf` to the connected peer (see
 [`dtact_util_io_udp_connect`]). Returns the byte count sent, or -1 on
 error.

 # Safety

 See the [`crate::ffi`] module-level Safety contract.
 */

ptrdiff_t dtact_util_io_udp_send(struct DtactUdpSocket *aSock,
                                 const uint8_t *aBuf,
                                 size_t aLen)
;

/*
 Send `len` bytes from `buf` as a single datagram to `target` (a
 NUL-terminated `"host:port"` string). Returns the byte count sent, or -1
 on error.

 # Safety

 See the [`crate::ffi`] module-level Safety contract. `target` must be a
 valid NUL-terminated C string.
 */

ptrdiff_t dtact_util_io_udp_send_to(struct DtactUdpSocket *aSock,
                                    const uint8_t *aBuf,
                                    size_t aLen,
                                    const char *aTarget)
;

/*
 Bind a Unix-domain datagram socket to the filesystem path `addr`.
 Returns an owning handle or null on error. Free with
 [`dtact_util_io_unix_datagram_close`].

 # Safety

 See the [`crate::ffi`] module-level Safety contract. `addr` must be a
 valid NUL-terminated C string.
 */
 struct DtactUnixDatagram *dtact_util_io_unix_datagram_bind(const char *aAddr) ;

/*
 Close and free a Unix-domain datagram socket handle. Passing null is a
 no-op.

 # Safety

 See the [`crate::ffi`] module-level Safety contract.
 */
 void dtact_util_io_unix_datagram_close(struct DtactUnixDatagram *aSock) ;

/*
 Connect `sock` to the path `addr` so
 [`dtact_util_io_unix_datagram_send`]/
 [`dtact_util_io_unix_datagram_recv`] can omit the peer address.
 Returns 0 on success, -1 on error.

 # Safety

 See the [`crate::ffi`] module-level Safety contract. `addr` must be a
 valid NUL-terminated C string.
 */

int32_t dtact_util_io_unix_datagram_connect(struct DtactUnixDatagram *aSock,
                                            const char *aAddr)
;

/*
 Receive a datagram from the connected peer into `buf`. Returns the
 byte count received, or -1 on error.

 # Safety

 See the [`crate::ffi`] module-level Safety contract.
 */

ptrdiff_t dtact_util_io_unix_datagram_recv(struct DtactUnixDatagram *aSock,
                                           uint8_t *aBuf,
                                           size_t aLen)
;

/*
 Receive a single datagram into `buf` (capacity `len`).

 On success writes the sender's path (or an empty string if unnamed —
 see [`crate::io::DtactUnixSocketAddr::is_unnamed`]) as a
 NUL-terminated string into `out_addr` (capacity `out_addr_cap`,
 truncated if it doesn't fit) and returns the byte count received;
 returns -1 on error.

 # Safety

 See the [`crate::ffi`] module-level Safety contract. `out_addr`, if
 non-null, must point to at least `out_addr_cap` writable bytes.
 */

ptrdiff_t dtact_util_io_unix_datagram_recv_from(struct DtactUnixDatagram *aSock,
                                                uint8_t *aBuf,
                                                size_t aLen,
                                                char *aOutAddr,
                                                size_t aOutAddrCap)
;

/*
 Send `len` bytes from `buf` to the connected peer (see
 [`dtact_util_io_unix_datagram_connect`]). Returns the byte count sent,
 or -1 on error.

 # Safety

 See the [`crate::ffi`] module-level Safety contract.
 */

ptrdiff_t dtact_util_io_unix_datagram_send(struct DtactUnixDatagram *aSock,
                                           const uint8_t *aBuf,
                                           size_t aLen)
;

/*
 Send `len` bytes from `buf` as a single datagram to the socket bound
 at `target`. Returns the byte count sent, or -1 on error.

 # Safety

 See the [`crate::ffi`] module-level Safety contract. `target` must be
 a valid NUL-terminated C string.
 */

ptrdiff_t dtact_util_io_unix_datagram_send_to(struct DtactUnixDatagram *aSock,
                                              const uint8_t *aBuf,
                                              size_t aLen,
                                              const char *aTarget)
;

/*
 Block until a client connects, returning an owning stream handle (free
 with [`dtact_util_io_unix_stream_close`]) or null on error.

 # Safety

 See the [`crate::ffi`] module-level Safety contract. `listener` must
 be a live handle from [`dtact_util_io_unix_listener_bind`].
 */

struct DtactUnixStream *dtact_util_io_unix_listener_accept(struct DtactUnixListener *aListener)
;

/*
 Bind a Unix-domain-socket listener to the filesystem path `addr`.
 Returns an owning handle or null on error. Free with
 [`dtact_util_io_unix_listener_close`].

 # Safety

 See the [`crate::ffi`] module-level Safety contract. `addr` must be a
 valid NUL-terminated C string.
 */
 struct DtactUnixListener *dtact_util_io_unix_listener_bind(const char *aAddr) ;

/*
 Close and free a Unix-domain-socket listener handle. Passing null is a
 no-op.

 # Safety

 See the [`crate::ffi`] module-level Safety contract.
 */
 void dtact_util_io_unix_listener_close(struct DtactUnixListener *aListener) ;

/*
 Close and free a Unix-domain-socket stream handle. Passing null is a
 no-op.

 # Safety

 See the [`crate::ffi`] module-level Safety contract.
 */
 void dtact_util_io_unix_stream_close(struct DtactUnixStream *aStream) ;

/*
 Connect to the Unix-domain-socket path `addr`, blocking until
 connected. Returns an owning stream handle or null on error. Free with
 [`dtact_util_io_unix_stream_close`].

 # Safety

 See the [`crate::ffi`] module-level Safety contract. `addr` must be a
 valid NUL-terminated C string.
 */
 struct DtactUnixStream *dtact_util_io_unix_stream_connect(const char *aAddr) ;

/*
 Fetch `stream`'s connected peer's credentials into `out_uid`/
 `out_gid`/`out_pid`.

 `out_pid` is set to -1 on platforms that don't report a PID — see
 [`crate::io::DtactUnixStream::peer_cred`]. Any of the three output
 pointers may be null to skip that field. Returns 0 on success, -1 on
 error.

 # Safety

 See the [`crate::ffi`] module-level Safety contract. `out_uid`/
 `out_gid`/`out_pid`, if non-null, must each point to one writable
 value of the matching type.
 */

int32_t dtact_util_io_unix_stream_peer_cred(struct DtactUnixStream *aStream,
                                            uint32_t *aOutUid,
                                            uint32_t *aOutGid,
                                            int32_t *aOutPid)
;

/*
 Read up to `len` bytes from `stream` into `buf`. Returns the byte
 count read (0 = orderly shutdown by peer) or -1 on error.

 # Safety

 See the [`crate::ffi`] module-level Safety contract.
 */

ptrdiff_t dtact_util_io_unix_stream_read(struct DtactUnixStream *aStream,
                                         uint8_t *aBuf,
                                         size_t aLen)
;

/*
 Write up to `len` bytes from `buf` to `stream`. Returns the byte count
 written or -1 on error.

 # Safety

 See the [`crate::ffi`] module-level Safety contract.
 */

ptrdiff_t dtact_util_io_unix_stream_write(struct DtactUnixStream *aStream,
                                          const uint8_t *aBuf,
                                          size_t aLen)
;

/*
 Return the current thread's last-error message as a NUL-terminated C
 string, or null if no error has been recorded since the last successful
 call.

 The returned pointer is owned by the library and remains valid only
 until the next `dtact-util` FFI call on this thread. Do not free it.

 # Safety

 See the [`crate::ffi`] module-level Safety contract. This function reads
 only thread-local state and takes no pointer arguments.
 */
 const char *dtact_util_last_error_message(void) ;

/*
 Free a child handle without waiting (leaves a zombie on Unix if the
 child hasn't been reaped). Prefer [`dtact_util_process_child_wait`].
 Passing null is a no-op.

 # Safety

 See the [`crate::ffi`] module-level Safety contract.
 */
 void dtact_util_process_child_free(struct DtactChild *aChild) ;

/*
 Return the child's OS process id, or 0 if `child` is null.

 # Safety

 See the [`crate::ffi`] module-level Safety contract.
 */
 uint32_t dtact_util_process_child_id(struct DtactChild *aChild) ;

/*
 Kill the child (does not reap it — still call
 [`dtact_util_process_child_wait`] or [`dtact_util_process_child_free`]).
 Returns 0 on success, -1 on error.

 # Safety

 See the [`crate::ffi`] module-level Safety contract.
 */
 int32_t dtact_util_process_child_kill(struct DtactChild *aChild) ;

/*
 Take ownership of the child's stderr pipe (only if spawned with
 [`DTACT_STDERR_PIPE`]). Returns null if unavailable or already taken.

 # Safety

 See the [`crate::ffi`] module-level Safety contract.
 */

struct DtactChildStderr *dtact_util_process_child_take_stderr(struct DtactChild *aChild)
;

/*
 Take ownership of the child's stdin pipe (only if spawned with
 [`DTACT_STDIN_PIPE`]). Returns null if unavailable or already taken.

 # Safety

 See the [`crate::ffi`] module-level Safety contract.
 */

struct DtactChildStdin *dtact_util_process_child_take_stdin(struct DtactChild *aChild)
;

/*
 Take ownership of the child's stdout pipe (only if spawned with
 [`DTACT_STDOUT_PIPE`]). Returns null if unavailable or already taken.

 # Safety

 See the [`crate::ffi`] module-level Safety contract.
 */

struct DtactChildStdout *dtact_util_process_child_take_stdout(struct DtactChild *aChild)
;

/*
 Block until the child exits, writing its exit code into `*out_code`.

 **Consumes and frees `child`** — do not use the handle afterwards.
 Returns 0 on success, -1 on error (e.g. the platform reported no exit
 code, as for a signal-terminated process on Unix).

 # Safety

 See the [`crate::ffi`] module-level Safety contract. `child` must be a
 live handle; `out_code`, if non-null, must be writable.
 */

int32_t dtact_util_process_child_wait(struct DtactChild *aChild,
                                      int32_t *aOutCode)
;

/*
 Initialize the process backend's blocking-op pool with `workers`
 threads. Idempotent (the pool also self-initializes on first use).

 # Safety

 See the [`crate::ffi`] module-level Safety contract. Takes no pointers.
 */
 void dtact_util_process_init(size_t aWorkers) ;

/*
 Spawn `program` as a child process.

 Takes `arg_count` arguments (`argv[0..arg_count]`, none of which is the
 program name) and the given `stdio_flags` (see [`DTACT_STDIN_PIPE`]
 etc.). Returns an owning child handle or null on error.

 # Safety

 See the [`crate::ffi`] module-level Safety contract. `program` must be a
 valid C string; `argv` must be non-null when `arg_count > 0` and point to
 `arg_count` valid C-string pointers.
 */

struct DtactChild *dtact_util_process_spawn(const char *aProgram,
                                            const char *const *aArgv,
                                            size_t aArgCount,
                                            uint32_t aStdioFlags)
;

/*
 Free the child's stderr pipe handle. Passing null is a no-op.

 # Safety

 See the [`crate::ffi`] module-level Safety contract.
 */
 void dtact_util_process_stderr_free(struct DtactChildStderr *aStderr) ;

/*
 Read up to `len` bytes from the child's stderr into `buf`. Returns the
 byte count read (0 = EOF) or -1 on error.

 # Safety

 See the [`crate::ffi`] module-level Safety contract.
 */

ptrdiff_t dtact_util_process_stderr_read(struct DtactChildStderr *aStderr,
                                         uint8_t *aBuf,
                                         size_t aLen)
;

/*
 Close (free) the child's stdin pipe, letting the child observe EOF.
 Passing null is a no-op.

 # Safety

 See the [`crate::ffi`] module-level Safety contract.
 */
 void dtact_util_process_stdin_close(struct DtactChildStdin *aStdin) ;

/*
 Write `len` bytes from `buf` to the child's stdin. Returns the byte count
 written or -1 on error.

 # Safety

 See the [`crate::ffi`] module-level Safety contract.
 */

ptrdiff_t dtact_util_process_stdin_write(struct DtactChildStdin *aStdin,
                                         const uint8_t *aBuf,
                                         size_t aLen)
;

/*
 Free the child's stdout pipe handle. Passing null is a no-op.

 # Safety

 See the [`crate::ffi`] module-level Safety contract.
 */
 void dtact_util_process_stdout_free(struct DtactChildStdout *aStdout) ;

/*
 Read up to `len` bytes from the child's stdout into `buf`. Returns the
 byte count read (0 = EOF) or -1 on error.

 # Safety

 See the [`crate::ffi`] module-level Safety contract.
 */

ptrdiff_t dtact_util_process_stdout_read(struct DtactChildStdout *aStdout,
                                         uint8_t *aBuf,
                                         size_t aLen)
;

/*
 Register a listener for Ctrl+Break (`CTRL_BREAK_EVENT`), returning an
 owning handle. Free with [`dtact_util_signal_free`].

 # Safety

 See the [`crate::ffi`] module-level Safety contract. Takes no pointers.
 */
 struct DtactSignalStream *dtact_util_signal_ctrl_break(void) ;

/*
 Register a listener for Ctrl+C (`CTRL_C_EVENT`), returning an owning
 handle. Free with [`dtact_util_signal_free`].

 # Safety

 See the [`crate::ffi`] module-level Safety contract. Takes no pointers.
 */
 struct DtactSignalStream *dtact_util_signal_ctrl_c(void) ;

/*
 Register a listener for console-window-close (`CTRL_CLOSE_EVENT`),
 returning an owning handle. Free with [`dtact_util_signal_free`].

 # Safety

 See the [`crate::ffi`] module-level Safety contract. Takes no pointers.
 */
 struct DtactSignalStream *dtact_util_signal_ctrl_close(void) ;

/*
 Register a listener for user-logoff (`CTRL_LOGOFF_EVENT`), returning an
 owning handle. Free with [`dtact_util_signal_free`].

 # Safety

 See the [`crate::ffi`] module-level Safety contract. Takes no pointers.
 */
 struct DtactSignalStream *dtact_util_signal_ctrl_logoff(void) ;

/*
 Register a listener for system-shutdown (`CTRL_SHUTDOWN_EVENT`),
 returning an owning handle. Free with [`dtact_util_signal_free`].

 # Safety

 See the [`crate::ffi`] module-level Safety contract. Takes no pointers.
 */
 struct DtactSignalStream *dtact_util_signal_ctrl_shutdown(void) ;

/*
 Free a signal listener handle. Passing null is a no-op.

 # Safety

 See the [`crate::ffi`] module-level Safety contract.
 */
 void dtact_util_signal_free(struct DtactSignalStream *aStream) ;

/*
 Block until this signal is next delivered.

 # Safety

 See the [`crate::ffi`] module-level Safety contract. `stream` must be a
 live handle from one of the signal constructors above.
 */
 void dtact_util_signal_recv(struct DtactSignalStream *aStream) ;

/*
 Register a listener for a raw signal number (`libc::SIGINT` etc.),
 returning an owning handle. Free with [`dtact_util_signal_free`].

 # Safety

 See the [`crate::ffi`] module-level Safety contract. Takes no pointers.
 */
 struct DtactSignalStream *dtact_util_signal_register(int aSignum) ;

/*
 Free (close) a stream endpoint. Dropping it lets the peer observe EOF on
 its next read. Passing null is a no-op.

 # Safety

 See the [`crate::ffi`] module-level Safety contract.
 */
 void dtact_util_stream_free(struct DtactStream *aStream) ;

/*
 Create a connected pair of duplex streams.

 Each side buffers `capacity` bytes per direction (rounded up to a power
 of two). On success writes two owning handles into `out_a` / `out_b` and
 returns 0; on error returns -1 and records a message.

 # Safety

 See the [`crate::ffi`] module-level Safety contract. `out_a` and `out_b`
 must be non-null, writable, and point to storage for one pointer each.
 */

int32_t dtact_util_stream_pair_create(size_t aCapacity,
                                      struct DtactStream **aOutA,
                                      struct DtactStream **aOutB)
;

/*
 Read up to `len` bytes from `stream` into `buf`. Returns the number of
 bytes read (0 = EOF, peer's write half dropped), or -1 on error.

 # Safety

 See the [`crate::ffi`] module-level Safety contract.
 */

ptrdiff_t dtact_util_stream_read(struct DtactStream *aStream,
                                 uint8_t *aBuf,
                                 size_t aLen)
;

/*
 Write up to `len` bytes from `buf` into `stream`. Returns the number of
 bytes written, or -1 on error (e.g. the peer dropped its read half).

 # Safety

 See the [`crate::ffi`] module-level Safety contract.
 */

ptrdiff_t dtact_util_stream_write(struct DtactStream *aStream,
                                  const uint8_t *aBuf,
                                  size_t aLen)
;

/*
 Create a repeating interval timer with the given period in milliseconds.

 Returns an owning handle, or null if `period_millis` is 0 (an error is
 recorded). Free with [`dtact_util_timer_interval_free`].

 # Safety

 See the [`crate::ffi`] module-level Safety contract. Takes no pointers.
 */

struct DtactInterval *dtact_util_timer_interval_create(uint64_t aPeriodMillis)
;

/*
 Free an interval handle. Passing null is a no-op.

 # Safety

 See the [`crate::ffi`] module-level Safety contract. `interval` must have
 come from [`dtact_util_timer_interval_create`] and must not be used
 afterwards.
 */
 void dtact_util_timer_interval_free(struct DtactInterval *aInterval) ;

/*
 Block until this interval's next tick fires.

 # Safety

 See the [`crate::ffi`] module-level Safety contract. `interval` must be a
 live handle from [`dtact_util_timer_interval_create`].
 */
 void dtact_util_timer_interval_tick(struct DtactInterval *aInterval) ;

/*
 Block the calling thread for `millis` milliseconds using the native
 timer wheel.

 # Safety

 See the [`crate::ffi`] module-level Safety contract. Takes no pointers.
 */
 void dtact_util_timer_sleep_ms(uint64_t aMillis) ;

#ifdef __cplusplus
}  // extern "C"
#endif  // __cplusplus

#endif  /* DTACT_UTIL_H */
