radcli_avp_iter_next(3)
π NAME
radcli_avp_iter_next β bestie, this is the one that hands you the current attribute and then immediately advances. Like, grab-and-go energy β¨
(Oh and the manual name is Radius client library, and it lives in section 3 of the radcli pages, iykyk π)
β¨ SYNOPSIS
#include <radcli/>
const radcli_avp * radcli_avp_iter_next(
radcli_avp_iter *it
);
πΈ DESCRIPTION
Okay so this section on the actual page is lowkey empty β no cap, it goes straight from the heading into PARAMETERS. So there's literally nothing to summarize here, the real tea is all in the sections below π«Ά
π PARAMETERS
itβ an iterator, and it's gotta be one you got fromradcli_avp_list_iter(). That's the only currency accepted here π
π¦ STRUCTURES
So we're iterating over a radcli_avp_list, and the iterator itself is described like this:
A plain value: construct withradcli_avp_list_iter(), advance withradcli_avp_iter_next(). No allocation, safe to copy, safe to run several independent iterators over the same list concurrently (as long as nothing mutates the list while any of them are in use β seeradcli_avp_list_st's locking note inlib/avp.c). Fields are an implementation detail; do not access them directly. Deliberately not opaque via an incomplete type: a two-pointer cursor belongs on the caller's stack at zero cost, the way any ccan/list or kernel list cursor does, not behind a heap allocation.
Translation: it's a plain value, zero allocation, you can copy it all you want, and you can totally run a bunch of independent iterators over the same list at the same time β but only if nothing mutates the list while any of them are live π that's the one caveat, respect it. Also the struct fields are an implementation detail, so keep your hands off them, fr fr. And this thing is deliberately not opaque via an incomplete type β a two-pointer cursor belongs on the caller's stack at zero cost, the way any ccan/list or kernel list cursor does, not behind a heap allocation. Main character design choice π
Usage, presented exactly like the page has it (spacing gremlins and all, we don't touch code π):
Usage: radcli_avp_iterit=radcli_avp_list_iter(list);
constradcli_avp*a;
while((a=radcli_avp_iter_next(&it))!=NULL){
}
And the struct itself:
struct radcli_avp_iter {
const radcli_avp_list *list;
const radcli_avp *cur;
};
β RETURN VALUE
It gives you the current attribute, or NULL once the list is exhausted. And listen β every subsequent call on the same it also returns NULL; it does not restart. The iterator is done, it has left the chat π
π SEE ALSO
The whole friend group, go say hi π
radcli_avp_add_bytes(3)radcli_avp_add_bytes_by_num(3)radcli_avp_add_gigawords64(3)radcli_avp_add_gigawords64_by_num(3)radcli_avp_add_ip4(3)radcli_avp_add_ip4_by_num(3)radcli_avp_add_ip4prefix(3)radcli_avp_add_ip4prefix_by_num(3)radcli_avp_add_ip6(3)radcli_avp_add_ip6_by_num(3)radcli_avp_add_str(3)radcli_avp_add_str_by_num(3)radcli_avp_add_uint32(3)radcli_avp_add_uint32_by_num(3)radcli_avp_add_uint64(3)radcli_avp_add_uint64_by_num(3)radcli_avp_add_username(3)radcli_avp_concat_str(3)radcli_avp_concat_str_by_num(3)radcli_avp_def(3)radcli_avp_get(3)radcli_avp_get_by_num(3)radcli_avp_get_bytes(3)radcli_avp_get_bytes_by_num(3)radcli_avp_get_cstr(3)radcli_avp_get_cstr_by_num(3)radcli_avp_get_gigawords64(3)radcli_avp_get_gigawords64_by_num(3)radcli_avp_get_ip4prefix(3)radcli_avp_get_ip4prefix_by_num(3)radcli_avp_get_ip6(3)radcli_avp_get_ip6_by_num(3)radcli_avp_get_uint32(3)radcli_avp_get_uint32_by_num(3)radcli_avp_get_uint64(3)radcli_avp_get_uint64_by_num(3)radcli_avp_list_error(3)radcli_avp_list_free(3)radcli_avp_list_iter(3)radcli_avp_list_new(3)
Go forth and loop, bestie. Just remember: NULL means stop, not "try again harder" π₯
And that's the whole page! This one came from radcli, dated 2026-10-10 β so if you're citing it, that's the version and the date, mwah ππ
π¦ 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