radcli_ctx_get_poll(3) Radius client library radcli_ctx_get_poll(3)

radcli_ctx_get_poll - Report what to wait for on ctx's behalf, for the caller's own event loop radcli never calls poll()/select()/epoll_wait() itself.

#include <radcli/>

int radcli_ctx_get_poll(
    radcli_ctx     *ctx,
    struct pollfd  *pfds,
    size_t          max_pfds,
    size_t         *nfds,
    int            *timeout_ms
);

There is no per-object descriptor accessor (e.g. no radcli_dae_fd(), no per-radcli_request one either net2.md's REQ-NET2-SEND-013): every descriptor this reports belongs to ctx, not to any one radcli_dae or radcli_request, so that a transport sharing one descriptor between dynamic authorization and ordinary requests (already true for TLS/DTLS) never leaves an application holding a watcher on a descriptor that has quietly started meaning something else.

For TLS/DTLS, or for a UDP ctx with no active radcli_dae, this is always exactly one descriptor: the session fd (TLS/DTLS, also carrying any in-flight RADCLI_REQUEST_SENDONLY traffic) or the request-registry socket (UDP, REQ-NET2-SEND-016). A UDP ctx with an active radcli_dae reports a second, independent descriptor for the DAE listener alongside it the two are genuinely different local sockets/ports and cannot be merged into one without changing the wire protocol; RADCLI_CTX_MAX_POLLFDS (2) is the maximum this API ever needs. *timeout_ms folds together every deadline source that applies (DAE queued-work, RadSec watchdog, and any in-flight RADCLI_REQUEST_SENDONLY exchange's own retransmit/timeout) into one caller-facing value, so the caller never computes a min() itself.

A descriptor is closed or replaced only during a call the application itself makes (radcli_ctx_dispatch(), radcli_dae_free(), radcli_request_perform(), rc_destroy()), never asynchronously but re-query after any of those regardless, since one may replace it.

a context, with or without an active radcli_dae.
filled with up to RADCLI_CTX_MAX_POLLFDS entries (fd/events; revents is left for the caller's poll() to fill in).
pfds's capacity; MUST be at least RADCLI_CTX_MAX_POLLFDS.
set to how many of pfds were filled in (0 if there is nothing to watch yet).
milliseconds after which to call radcli_ctx_dispatch() even without I/O readiness; -1 for "no timeout
needed".

0 on success, -1 if ctx or an out-parameter is NULL, or max_pfds is too small.

radcli_ctx_dispatch(3), radcli_dae_free(3), radcli_dae_new(3), radcli_dae_process(3), radcli_dae_reply(3), radcli_dae_reply_error(3), radcli_dae_reply_to_buffer(3), radcli_dae_req_attrs(3), radcli_dae_req_code(3), radcli_dae_req_framed_ip(3), radcli_dae_req_nas_port(3), radcli_dae_req_session_id(3), radcli_dae_req_user_name(3), radcli_dae_request_free(3), radcli_dae_set_handler(3), radcli_dae_start(3)

2026-09-03 radcli