radcli_ctx_get_poll(3)
๐ radcli_ctx_get_poll(3) โ the radcli manual, bestie edition ๐
okay so this is a page from the radcli manual, and it's about radcli_ctx_get_poll โ the little function that tells your event loop what to watch. โจ
๐ธ NAME ๐ธ
radcli_ctx_get_poll โ reports what to wait for on ctx's behalf, so the caller can run its own event loop. and like, <rainbow>radcli never calls poll()/select()/epoll_wait()` itself ๐
periodt, that's your job, not hers.
โจ SYNOPSIS โจ
#include <radcli/>
int radcli_ctx_get_poll(
radcli_ctx *ctx,
struct pollfd *pfds,
size_t max_pfds,
size_t *nfds,
int *timeout_ms
);
๐ฆ DESCRIPTION ๐ฆ
so first thing's first: there is no per-object descriptor accessor. like, none. no radcli_dae_fd(), and no per-radcli_request one either โ net2.md's REQ-NET2-SEND-013, iykyk. every descriptor this function reports belongs to ctx, not to any one radcli_dae or radcli_request. why does that matter? because a transport that shares one descriptor between dynamic authorization and ordinary requests (which is already true for TLS/DTLS, no cap) would otherwise leave an application holding a watcher on a descriptor that has quietly started meaning something else ๐ญ the audacity. not on our watch.
For TLS/DTLS, or for a UDP ctx with no active radcli_dae, this is always exactly one descriptor:
- the session fd (TLS/DTLS โ and it's also carrying any in-flight
RADCLI_REQUEST_SENDONLYtraffic), 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. and no, you can't merge them โ the two are genuinely different local sockets/ports and cannot be combined 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 single caller-facing value. so the caller never has to compute a min() itself. she did the math so you don't have to ๐งฎ๐
โ ๏ธ 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, because one of them may have replaced it. main character energy means always checking again ๐ซถ
๐ PARAMETERS ๐
ctxโ a context, with or without an activeradcli_dae. either way, she's ready.pfdsโ filled with up toRADCLI_CTX_MAX_POLLFDSentries (fd/events;reventsis left for the caller'spoll()to fill in, that part's on you bestie).max_pfdsโpfds's capacity. MUST be at leastRADCLI_CTX_MAX_POLLFDS. like, mandatory. non-negotiable.nfdsโ set to how many ofpfdswere filled in (0if there's nothing to watch yet ๐ฆ).timeout_msโ milliseconds after which to callradcli_ctx_dispatch()even without I/O readiness;-1for "no timeout needed".
๐ฅ RETURN VALUE ๐ฅ
0on success โจ-1ifctxor an out-parameter isNULL, or ifmax_pfdsis too small ๐
๐ SEE ALSO ๐
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)
that's the whole page, bestie ๐ this drop is from the radcli manual, dated 2026-10-10, and the page is radcli_ctx_get_poll(3) โ go be iconic with your event loop ๐๐ฆ๐ธ
๐ฆ where this page comes from
- arch rolling: radcli 2.0.1-1 ยท BSD
- ๐ girlified by deepseek-ai/DeepSeek-V4.1-Flash-1017 on : a language model's rewrite of the original, under its terms