+ i->ctn_iter_fun = (void (*) (void)) ctf_member_next;
+ i->ctn_n = 0;
+ *it = i;
+ }
+
+ if ((void (*) (void)) ctf_member_next != i->ctn_iter_fun)
+ return (ctf_set_errno (ofp, ECTF_NEXT_WRONGFUN));
+
+ if (ofp != i->cu.ctn_fp)
+ return (ctf_set_errno (ofp, ECTF_NEXT_WRONGFP));
+
+ /* Resolve to the native dict of this type. */
+ if ((fp = ctf_get_dict (ofp, type)) == NULL)
+ return (ctf_set_errno (ofp, ECTF_NOPARENT));
+
+ max_vlen = LCTF_INFO_VLEN (fp, i->ctn_tp->ctt_info);
+
+ /* When we hit an unnamed struct/union member, we set ctn_type to indicate
+ that we are inside one, then return the unnamed member: on the next call,
+ we must skip over top-level member iteration in favour of iteration within
+ the sub-struct until it later turns out that that iteration has ended. */
+
+ retry:
+ if (!i->ctn_type)
+ {
+ ctf_lmember_t memb;
+ const char *membname;
+
+ if (i->ctn_n == max_vlen)
+ goto end_iter;
+
+ if (ctf_struct_member (fp, &memb, i->ctn_tp, i->u.ctn_vlen, i->ctn_size,
+ i->ctn_n) < 0)
+ return -1; /* errno is set for us. */
+
+ membname = ctf_strptr (fp, memb.ctlm_name);
+
+ if (name)
+ *name = membname;
+ if (membtype)
+ *membtype = memb.ctlm_type;
+ offset = (unsigned long) CTF_LMEM_OFFSET (&memb);
+
+ if (membname[0] == 0
+ && (ctf_type_kind (fp, memb.ctlm_type) == CTF_K_STRUCT
+ || ctf_type_kind (fp, memb.ctlm_type) == CTF_K_UNION))
+ i->ctn_type = memb.ctlm_type;
+ i->ctn_n++;
+
+ /* The callers might want automatic recursive sub-struct traversal. */
+ if (!(flags & CTF_MN_RECURSE))
+ i->ctn_type = 0;
+
+ /* Sub-struct traversal starting? Take note of the offset of this member,
+ for later boosting of sub-struct members' offsets. */
+ if (i->ctn_type)
+ i->ctn_increment = offset;