bool lgtd_router_send(const struct lgtd_proto_target_list *targets, enum lgtd_lifx_packet_type pkt_type, void *pkt) { if (strcmp(SLIST_FIRST(targets)->target, "*")) { errx( 1, "invalid target [%s] (expected=[*])", SLIST_FIRST(targets)->target ); } if (pkt_type != LGTD_LIFX_SET_BULB_LABEL) { errx(1, "invalid packet type %d (expected %d)", pkt_type, LGTD_LIFX_SET_BULB_LABEL ); } struct lgtd_lifx_packet_label *set_label = pkt; if (strcmp(set_label->label, "test")) { errx( 1, "invalid packet label %.*s (expected test)", LGTD_LIFX_LABEL_SIZE, set_label->label ); } if (router_send_call_count++) { errx(1, "lgtd_router_send should be called once"); } return true; }
static struct pgt *pop_least_used_from_cache_list(void) { struct pgt *pgt; struct pgt *p_prev = NULL; size_t least_used; pgt = SLIST_FIRST(&pgt_cache_list); if (!pgt) return NULL; if (!pgt->num_used_entries) goto out; least_used = pgt->num_used_entries; while (true) { if (!SLIST_NEXT(pgt, link)) break; if (SLIST_NEXT(pgt, link)->num_used_entries <= least_used) { p_prev = pgt; least_used = SLIST_NEXT(pgt, link)->num_used_entries; } pgt = SLIST_NEXT(pgt, link); } out: if (p_prev) { pgt = SLIST_NEXT(p_prev, link); SLIST_REMOVE_AFTER(p_prev, link); } else { pgt = SLIST_FIRST(&pgt_cache_list); SLIST_REMOVE_HEAD(&pgt_cache_list, link); } return pgt; }
bool lgtd_router_send(const struct lgtd_proto_target_list *targets, enum lgtd_lifx_packet_type pkt_type, void *pkt) { if (strcmp(SLIST_FIRST(targets)->target, "*")) { errx( 1, "invalid target [%s] (expected=[*])", SLIST_FIRST(targets)->target ); } if (pkt_type != LGTD_LIFX_SET_POWER_STATE) { errx(1, "invalid packet type %d (expected %d)", pkt_type, LGTD_LIFX_SET_POWER_STATE ); } struct lgtd_lifx_packet_power_state *power_off = pkt; if (power_off->power != LGTD_LIFX_POWER_OFF) { errx(1, "invalid power state %hx (expected %x)", power_off->power, LGTD_LIFX_POWER_OFF); } return true; }
int main(void) { tmpdir = lgtd_tests_make_temp_dir(); atexit(cleanup_tmpdir); char path[PATH_MAX] = { 0 }; snprintf(path, sizeof(path), "%s/lightsd.pipe", tmpdir); if (!lgtd_command_pipe_open(path)) { errx(1, "couldn't open pipe"); } struct lgtd_command_pipe *pipe = SLIST_FIRST(&lgtd_command_pipes); lgtd_command_pipe_read_callback(pipe->fd, EV_READ, pipe); if (event_del_call_count != 1) { errx(1, "the pipe wasn't reset"); } jsonrpc_dispatch_request_call_count = 0; evbuffer_drain_call_count = 0; evbuffer_read_call_count = 0; evbuffer_pullup_call_count = 0; evbuffer_get_length_call_count = 0; event_del_call_count = 0; pipe = SLIST_FIRST(&lgtd_command_pipes); lgtd_command_pipe_read_callback(pipe->fd, EV_READ, pipe); if (event_del_call_count != 1) { errx(1, "the pipe wasn't reset"); } return 0; }
static void destroy_buffers(struct chip_swap *swap) { struct block_space *blk_space; if (swap == NULL) return; blk_space = SLIST_FIRST(&swap->free_bs); while (blk_space) { SLIST_REMOVE_HEAD(&swap->free_bs, free_link); nand_debug(NDBG_SIM,"destroyed blk_space %p[%p]\n", blk_space, blk_space->blk_ptr); free(blk_space->blk_ptr, M_NANDSIM); free(blk_space, M_NANDSIM); blk_space = SLIST_FIRST(&swap->free_bs); } blk_space = STAILQ_FIRST(&swap->used_bs); while (blk_space) { STAILQ_REMOVE_HEAD(&swap->used_bs, used_link); nand_debug(NDBG_SIM,"destroyed blk_space %p[%p]\n", blk_space, blk_space->blk_ptr); free(blk_space->blk_ptr, M_NANDSIM); free(blk_space, M_NANDSIM); blk_space = STAILQ_FIRST(&swap->used_bs); } }
int main(int argc, char **argv) { struct head root; SLIST_INIT(&root); addnodes(&root, 2); addnodes(&SLIST_FIRST(&root)->children, 4); addnodes(&SLIST_NEXT(SLIST_FIRST(&root), links)->children, 2); // dumptree output: // // 1 // 3 // 2 // 1 // 0 // 0 // 1 // 0 dumptree(&root, 0); /* free_tree(&root); */ }
OM_uint32 GSSAPI_LIB_FUNCTION gss_release_name(OM_uint32 *minor_status, gss_name_t *input_name) { struct _gss_name *name; *minor_status = 0; if (input_name == NULL || *input_name == NULL) return GSS_S_COMPLETE; name = (struct _gss_name *) *input_name; if (name->gn_type.elements) free(name->gn_type.elements); while (SLIST_FIRST(&name->gn_mn)) { struct _gss_mechanism_name *mn; mn = SLIST_FIRST(&name->gn_mn); SLIST_REMOVE_HEAD(&name->gn_mn, gmn_link); mn->gmn_mech->gm_release_name(minor_status, &mn->gmn_name); free(mn); } gss_release_buffer(minor_status, &name->gn_value); free(name); *input_name = GSS_C_NO_NAME; return (GSS_S_COMPLETE); }
/* * Unregister all hooks and cookies for that module. Note: doesn't disconnect * any hooks! */ void ng_unregister_module(const struct lmodule *mod) { struct msgreg *m, *m1; struct datareg *d, *d1; m = SLIST_FIRST(&msgreg_list); while (m != NULL) { m1 = SLIST_NEXT(m, link); if (m->mod == mod) { SLIST_REMOVE(&msgreg_list, m, msgreg, link); free(m); } m = m1; } d = SLIST_FIRST(&datareg_list); while (d != NULL) { d1 = SLIST_NEXT(d, link); if (d->mod == mod) { SLIST_REMOVE(&datareg_list, d, datareg, link); free(d); } d = d1; } }
void listeners_reload(struct Listener_head *existing_listeners, struct Listener_head *new_listeners, const struct Table_head *tables, struct ev_loop *loop) { struct Listener *iter_existing = SLIST_FIRST(existing_listeners); struct Listener *iter_new = SLIST_FIRST(new_listeners); while (iter_existing != NULL || iter_new != NULL) { int compare_result; char address[ADDRESS_BUFFER_SIZE]; if (iter_existing == NULL) compare_result = 1; else if (iter_new == NULL) compare_result = -1; else compare_result = address_compare(iter_existing->address, iter_new->address); if (compare_result > 0) { struct Listener *new_listener = iter_new; iter_new = SLIST_NEXT(iter_new, entries); notice("Listener %s added.", display_address(new_listener->address, address, sizeof(address))); SLIST_REMOVE(new_listeners, new_listener, Listener, entries); add_listener(existing_listeners, new_listener); init_listener(new_listener, tables, loop); /* -1 for removing from new_listeners */ listener_ref_put(new_listener); } else if (compare_result == 0) { notice ("Listener %s updated.", display_address(iter_existing->address, address, sizeof(address))); listener_update(iter_existing, iter_new, tables); iter_existing = SLIST_NEXT(iter_existing, entries); iter_new = SLIST_NEXT(iter_new, entries); } else { struct Listener *removed_listener = iter_existing; iter_existing = SLIST_NEXT(iter_existing, entries); notice("Listener %s removed.", display_address(removed_listener->address, address, sizeof(address))); SLIST_REMOVE(existing_listeners, removed_listener, Listener, entries); close_listener(loop, removed_listener); /* -1 for removing from existing_listeners */ listener_ref_put(removed_listener); } } }
void lgtd_proto_set_light_from_hsbk(struct lgtd_client *client, const struct lgtd_proto_target_list *targets, int hue, int saturation, int brightness, int kelvin, int transition_msecs) { if (!client) { errx(1, "missing client!"); } if (strcmp(SLIST_FIRST(targets)->target, "*")) { errx( 1, "Invalid target [%s] (expected=[*])", SLIST_FIRST(targets)->target ); } int expected_hue = lgtd_jsonrpc_float_range_to_uint16( "324.2341", strlen("324.2341"), 0, 360 ); if (hue != expected_hue) { errx(1, "Invalid hue: %d, expected: %d", hue, expected_hue); } int expected_saturation = lgtd_jsonrpc_float_range_to_uint16( "0.234", strlen("0.234"), 0, 1 ); if (saturation != expected_saturation) { errx( 1, "Invalid saturation: %d, expected: %d", saturation, expected_saturation ); } if (brightness != UINT16_MAX) { errx( 1, "Invalid brightness: %d, expected: %d", brightness, UINT16_MAX ); } if (kelvin != 4200) { errx( 1, "Invalid temperature: %d, expected: 4200", kelvin ); } if (transition_msecs != 60) { errx( 1, "Invalid transition duration: %d, expected: 60", transition_msecs ); } set_light_called = true; }
static __inline struct ida_qcb * ida_get_qcb(struct ida_softc *ida) { struct ida_qcb *qcb; if ((qcb = SLIST_FIRST(&ida->free_qcbs)) != NULL) { SLIST_REMOVE_HEAD(&ida->free_qcbs, link.sle); } else { ida_alloc_qcb(ida); if ((qcb = SLIST_FIRST(&ida->free_qcbs)) != NULL) SLIST_REMOVE_HEAD(&ida->free_qcbs, link.sle); } return (qcb); }
/* * Get an item from the item free q of the given slab with id. */ static struct item * _slab_get_item_from_freeq(uint8_t id) { struct slabclass *p; /* parent slabclass */ struct item *it; if (!use_freeq) { return NULL; } p = &slabclass[id]; if (p->nfree_itemq == 0) { return NULL; } it = SLIST_FIRST(&p->free_itemq); ASSERT(it->magic == ITEM_MAGIC); ASSERT(it->in_freeq); ASSERT(!(it->is_linked)); it->in_freeq = 0; ASSERT(p->nfree_itemq > 0); p->nfree_itemq--; SLIST_REMOVE(&p->free_itemq, it, item, i_sle); PERSLAB_DECR(id, item_free); log_verb("get free q it %p at offset %"PRIu32" with id %"PRIu8, it, it->offset, it->id); return it; }
/** * \fn order_remove * * \brief order the remove list according to dependency level */ Plisthead * order_remove(Plisthead *deptreehead) { int i, maxlevel = 0; Pkglist *pdp, *next; Plisthead *ordtreehead; /* package removal cannot trust recorded dependencies, reorder */ remove_dep_deepness(deptreehead); SLIST_FOREACH(pdp, deptreehead, next) if (pdp->level > maxlevel) maxlevel = pdp->level; ordtreehead = init_head(); for (i = maxlevel; i >= 0; i--) { pdp = SLIST_FIRST(deptreehead); while (pdp != NULL) { next = SLIST_NEXT(pdp, next); if (pdp->level == i) { SLIST_REMOVE(deptreehead, pdp, Pkglist, next); SLIST_INSERT_HEAD(ordtreehead, pdp, next); } pdp = next; } } return ordtreehead; }
void adv_free(struct adv_softc *adv) { switch (adv->init_level) { case 6: { struct adv_ccb_info *cinfo; while ((cinfo = SLIST_FIRST(&adv->free_ccb_infos)) != NULL) { SLIST_REMOVE_HEAD(&adv->free_ccb_infos, links); adv_destroy_ccb_info(adv, cinfo); } bus_dmamap_unload(adv->sense_dmat, adv->sense_dmamap); } case 5: bus_dmamem_free(adv->sense_dmat, adv->sense_buffers, adv->sense_dmamap); case 4: bus_dma_tag_destroy(adv->sense_dmat); case 3: bus_dma_tag_destroy(adv->buffer_dmat); case 2: bus_dma_tag_destroy(adv->parent_dmat); case 1: if (adv->ccb_infos != NULL) free(adv->ccb_infos, M_DEVBUF); case 0: break; } }
void* new_blocks(struct s_arena* arena,size_t count){ /* TODO better allocation sequence. it will require TAILQ. */ struct mega_bdescr* mega_block = SLIST_FIRST(&(arena->mega_blocks)); struct single_bdescr* new_block = NULL; void* new_vblocks = NULL; if(count > ( MEGA_BLOCK_SIZE / BLOCK_SIZE)){ debug("ERROR: %s cannot allocate size %08x\n",__FUNCTION__,count); return NULL; } if(mega_block == NULL){ mega_block = new_megablock(arena); SLIST_INSERT_HEAD(&(arena->mega_blocks),mega_block,link); } /* now mega_block is non-NULL */ if(mega_block->nblocks <= count) { mega_block = new_megablock(arena); SLIST_INSERT_HEAD(&(arena->mega_blocks),mega_block,link); } SLIST_REMOVE_HEAD(&(arena->mega_blocks),link); new_vblocks = new_blocks_from_megablock(&mega_block,count); if(mega_block != NULL){ SLIST_INSERT_HEAD(&(arena->mega_blocks),mega_block,link); } return new_vblocks; }
void lgtd_proto_power_off(struct lgtd_client *client, const struct lgtd_proto_target_list *targets) { if (!client) { errx(1, "missing client!"); } if (strcmp(SLIST_FIRST(targets)->target, "*")) { errx( 1, "Invalid target [%s] (expected=[*])", SLIST_FIRST(targets)->target ); } power_off_called = true; }
static int uart_chipc_probe(device_t dev) { struct uart_softc *sc; struct resource *res; int rid; rid = 0; res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid, RF_ACTIVE); if (res == NULL) { device_printf(dev, "can't allocate main resource\n"); return (ENXIO); } sc = device_get_softc(dev); sc->sc_class = &uart_ns8250_class; sc->sc_sysdev = SLIST_FIRST(&uart_sysdevs); if (sc->sc_sysdev == NULL) { device_printf(dev, "missing sysdev\n"); return (EINVAL); } bcopy(&sc->sc_sysdev->bas, &sc->sc_bas, sizeof(sc->sc_bas)); sc->sc_sysdev->bas.bst = rman_get_bustag(res); sc->sc_sysdev->bas.bsh = rman_get_bushandle(res); sc->sc_bas.bst = sc->sc_sysdev->bas.bst; sc->sc_bas.bsh = sc->sc_sysdev->bas.bsh; bus_release_resource(dev, SYS_RES_MEMORY, rid, res); /* We use internal SoC clock generator with non-standart freq MHz */ return (uart_bus_probe(dev, 0, sc->sc_sysdev->bas.rclk, 0, 0)); }
static struct pgt *pop_from_cache_list(vaddr_t vabase, void *ctx) { struct pgt *pgt; struct pgt *p; pgt = SLIST_FIRST(&pgt_cache_list); if (!pgt) return NULL; if (match_pgt(pgt, vabase, ctx)) { SLIST_REMOVE_HEAD(&pgt_cache_list, link); return pgt; } while (true) { p = SLIST_NEXT(pgt, link); if (!p) break; if (match_pgt(p, vabase, ctx)) { SLIST_REMOVE_AFTER(pgt, link); break; } pgt = p; } return p; }
struct twe_ccb * twe_ccb_alloc_wait(struct twe_softc *sc, int flags) { struct twe_ccb *ccb; int s; KASSERT((flags & TWE_CCB_AEN) == 0); s = splbio(); while (__predict_false((ccb = SLIST_FIRST(&sc->sc_ccb_freelist)) == NULL)) { sc->sc_flags |= TWEF_WAIT_CCB; (void) tsleep(&sc->sc_ccb_freelist, PRIBIO, "tweccb", 0); } SLIST_REMOVE_HEAD(&sc->sc_ccb_freelist, ccb_chain.slist); #ifdef DIAGNOSTIC if ((ccb->ccb_flags & TWE_CCB_ALLOCED) != 0) panic("twe_ccb_alloc_wait: CCB %ld already allocated", (long)(ccb - sc->sc_ccbs)); flags |= TWE_CCB_ALLOCED; #endif splx(s); twe_ccb_init(sc, ccb, flags); return (ccb); }
void free_listeners(struct Listener_head *listeners) { struct Listener *iter; while ((iter = SLIST_FIRST(listeners)) != NULL) remove_listener(listeners, iter); }
int nffs_dir_read(struct nffs_dir *dir, struct nffs_dirent **out_dirent) { struct nffs_inode_entry *child; int rc; if (dir->nd_dirent.nde_inode_entry == NULL) { child = SLIST_FIRST(&dir->nd_parent_inode_entry->nie_child_list); } else { child = SLIST_NEXT(dir->nd_dirent.nde_inode_entry, nie_sibling_next); rc = nffs_inode_dec_refcnt(dir->nd_dirent.nde_inode_entry); if (rc != 0) { /* XXX: Need to clean up anything? */ return rc; } } dir->nd_dirent.nde_inode_entry = child; if (child == NULL) { *out_dirent = NULL; return FS_ENOENT; } child->nie_refcnt++; *out_dirent = &dir->nd_dirent; return 0; }
/* * Prepend the source path to a file name. */ char * sourcepath(const char *file) { size_t len; char *cp; struct prefix *pf; pf = SLIST_EMPTY(&prefixes) ? NULL : SLIST_FIRST(&prefixes); if (pf != NULL && *pf->pf_prefix == '/') len = strlen(pf->pf_prefix) + 1 + strlen(file) + 1; else { len = strlen(srcdir) + 1 + strlen(file) + 1; if (pf != NULL) len += strlen(pf->pf_prefix) + 1; } cp = emalloc(len); if (pf != NULL) { if (*pf->pf_prefix == '/') (void) sprintf(cp, "%s/%s", pf->pf_prefix, file); else (void) sprintf(cp, "%s/%s/%s", srcdir, pf->pf_prefix, file); } else (void) sprintf(cp, "%s/%s", srcdir, file); return (cp); }
void alarmsProcess(void) { // // Note that this code works in the way that neither locking the list // nor disabling interrupts is required // uint32_t now = (uint32_t) getJiffies(); // PRINTF("processAlarms: jiffies=%lu\n", now); Alarm_t **a = &SLIST_FIRST(&alarmListHead); while (*a) { Alarm_t *ap = *a; // the alarm must have valid callback ASSERT(ap->callback != NULL); // PRINTF("processAlarms: ap=%p, ap->jiffies=%lu\n", ap, ap->jiffies); if (timeAfter32(ap->jiffies, now)) { break; } // save next alarm for later reference Alarm_t **next = &SLIST_NEXT(ap, chain); // remove the alarm from the list *a = *next; // call the callback ap->callback(ap->data); // move to the next a = next; } }
/* * Allocate a new TPD, zero the TPD part. Cannot return NULL if * flag is 0. The TPD is removed from the free list and its used * bit is set. */ static struct tpd * hatm_alloc_tpd(struct hatm_softc *sc, u_int flags) { struct tpd *t; /* if we allocate a transmit TPD check for the reserve */ if (flags & M_NOWAIT) { if (sc->tpd_nfree <= HE_CONFIG_TPD_RESERVE) return (NULL); } else { if (sc->tpd_nfree == 0) return (NULL); } /* make it beeing used */ t = SLIST_FIRST(&sc->tpd_free); KASSERT(t != NULL, ("tpd botch")); SLIST_REMOVE_HEAD(&sc->tpd_free, link); TPD_SET_USED(sc, t->no); sc->tpd_nfree--; /* initialize */ t->mbuf = NULL; t->cid = 0; bzero(&t->tpd, sizeof(t->tpd)); t->tpd.addr = t->no << HE_REGS_TPD_ADDR; return (t); }
/* ARGSUSED */ int poptag(int f, int n) { struct line *dotp; struct tagpos *s; if (SLIST_EMPTY(&shead)) { dobeep(); ewprintf("No previous location for find-tag invocation"); return (FALSE); } s = SLIST_FIRST(&shead); SLIST_REMOVE_HEAD(&shead, entry); if (loadbuffer(s->bname) == FALSE) return (FALSE); curwp->w_dotline = s->dotline; curwp->w_doto = s->doto; /* storing of dotp in tagpos wouldn't work out in cases when * that buffer is killed by user(dangling pointer). Explicitly * traverse till dotline for correct handling. */ dotp = curwp->w_bufp->b_headp; while (s->dotline--) dotp = dotp->l_fp; curwp->w_dotp = dotp; free(s->bname); free(s); return (TRUE); }
/* returns a free command struct if one is available. * It also blanks out anything that may be a wild pointer/value. * Also, command buffers are not freed. They are * small so they are saved and kept dmamapped and loaded. */ int ips_get_free_cmd(ips_softc_t *sc, ips_command_t **cmd, unsigned long flags) { ips_command_t *command; if(sc->state & IPS_OFFLINE){ return EIO; } if ((flags & IPS_STATIC_FLAG) == 0) { command = SLIST_FIRST(&sc->free_cmd_list); if(!command || (sc->state & IPS_TIMEOUT)){ return EBUSY; } SLIST_REMOVE_HEAD(&sc->free_cmd_list, next); (sc->used_commands)++; } else { if (sc->state & IPS_STATIC_BUSY) return EAGAIN; command = sc->staticcmd; sc->state |= IPS_STATIC_BUSY; } clear_ips_command(command); bzero(command->command_buffer, IPS_COMMAND_LEN); *cmd = command; return 0; }
struct twe_ccb * twe_ccb_alloc(struct twe_softc *sc, int flags) { struct twe_ccb *ccb; int s; s = splbio(); if (__predict_false((flags & TWE_CCB_AEN) != 0)) { /* Use the reserved CCB. */ ccb = sc->sc_ccbs; } else { /* Allocate a CCB and command block. */ if (__predict_false((ccb = SLIST_FIRST(&sc->sc_ccb_freelist)) == NULL)) { splx(s); return (NULL); } SLIST_REMOVE_HEAD(&sc->sc_ccb_freelist, ccb_chain.slist); } #ifdef DIAGNOSTIC if ((long)(ccb - sc->sc_ccbs) == 0 && (flags & TWE_CCB_AEN) == 0) panic("twe_ccb_alloc: got reserved CCB for non-AEN"); if ((ccb->ccb_flags & TWE_CCB_ALLOCED) != 0) panic("twe_ccb_alloc: CCB %ld already allocated", (long)(ccb - sc->sc_ccbs)); flags |= TWE_CCB_ALLOCED; #endif splx(s); twe_ccb_init(sc, ccb, flags); return (ccb); }
/* * Free all the memory collected while the cdev mutex was * locked. Since devmtx is after the system map mutex, free() cannot * be called immediately and is postponed until cdev mutex can be * dropped. */ static void dev_unlock_and_free(void) { struct cdev_priv_list cdp_free; struct free_cdevsw csw_free; struct cdev_priv *cdp; struct cdevsw *csw; mtx_assert(&devmtx, MA_OWNED); /* * Make the local copy of the list heads while the dev_mtx is * held. Free it later. */ TAILQ_INIT(&cdp_free); TAILQ_CONCAT(&cdp_free, &cdevp_free_list, cdp_list); csw_free = cdevsw_gt_post_list; SLIST_INIT(&cdevsw_gt_post_list); mtx_unlock(&devmtx); while ((cdp = TAILQ_FIRST(&cdp_free)) != NULL) { TAILQ_REMOVE(&cdp_free, cdp, cdp_list); devfs_free(&cdp->cdp_c); } while ((csw = SLIST_FIRST(&csw_free)) != NULL) { SLIST_REMOVE_HEAD(&csw_free, d_postfree_list); free(csw, M_DEVT); } }
static void readdumptimes(FILE *df) { int i; struct dumptime *dtwalk; for (;;) { dtwalk = (struct dumptime *)calloc(1, sizeof (struct dumptime)); if (getrecord(df, &(dtwalk->dt_value)) < 0) { free(dtwalk); break; } nddates++; SLIST_INSERT_HEAD(&dthead, dtwalk, dt_list); } /* * arrayify the list, leaving enough room for the additional * record that we may have to add to the ddate structure */ ddatev = (struct dumpdates **) calloc((unsigned) (nddates + 1), sizeof (struct dumpdates *)); dtwalk = SLIST_FIRST(&dthead); for (i = nddates - 1; i >= 0; i--, dtwalk = SLIST_NEXT(dtwalk, dt_list)) ddatev[i] = &dtwalk->dt_value; }
ENTRY * hsearch(ENTRY item, ACTION action) { struct internal_head *head; struct internal_entry *ie; uint32_t hashval; size_t len; len = strlen(item.key); hashval = (*__default_hash)(item.key, len); head = &htable[hashval & (htablesize - 1)]; ie = SLIST_FIRST(head); while (ie != NULL) { if (strcmp(ie->ent.key, item.key) == 0) break; ie = SLIST_NEXT(ie, link); } if (ie != NULL) return &ie->ent; else if (action == FIND) return NULL; ie = malloc(sizeof *ie); if (ie == NULL) return NULL; ie->ent.key = item.key; ie->ent.data = item.data; SLIST_INSERT_HEAD(head, ie, link); return &ie->ent; }