void *dbg_mem_get(struct memmgr *mm, size_t amt) { size_t ramt; struct dbg_header *dh; void *p; abort_unless(mm == &dbgmem); ramt = ROUNDUP(amt); abort_unless(ramt >= amt); dh = malloc(ramt); if ( dh == NULL ) return NULL; ++dbg_num_alloc; dbg_alloc_amt += amt; dh->dh_amt = amt; p = TOMEM(dh); ht_ninit(&dh->dh_hnode, p); ht_ins_h(&dbg_htab, &dh->dh_hnode); return p; }
void pc_init(struct pcache *pc, size_t asiz, size_t pgsiz, uint hiwat, uint maxpools, struct memmgr *mm) { abort_unless(pc); abort_unless(asiz > 0); abort_unless(pgsiz == 0 || (pgsiz >= sizeof(union pc_pool_u) + pl_isiz(asiz, -1))); if ( pgsiz == 0 ) pgsiz = PC_DEF_SIZE; if ( !maxpools ) maxpools = ~0; pc->asiz = asiz + sizeof(cat_pcpad_t); pc->mm = mm; pc->pgsiz = pgsiz; pc->hiwat = hiwat; pc->maxpools = maxpools; pc->npools = 0; l_init(&pc->avail); l_init(&pc->empty); l_init(&pc->full); }
static void setup_pkb(struct pktbuf *pkb, void *p, struct bpf_hdr *bh) { struct xpkt_tag_iface ti; struct xpkt_tag_snapinfo si; struct xpkt_tag_ts ts; int rv; pkb_init(pkb, p, bh->bh_caplen, g_xbuf, sizeof(g_xbuf)); if (g_ifnum != (uint)-1) { xpkt_tag_iif_init(&ti, g_ifnum); rv = pkb_add_tag(pkb, (struct xpkt_tag_hdr *)&ti); abort_unless(rv == 0); } /* add snaplen */ if (bh->bh_caplen < bh->bh_datalen) { xpkt_tag_si_init(&si, bh->bh_datalen); rv = pkb_add_tag(pkb, (struct xpkt_tag_hdr *)&si); abort_unless(rv == 0); } xpkt_tag_ts_init(&ts, bh->bh_tstamp.tv_sec, bh->bh_tstamp.tv_usec * 1000); rv = pkb_add_tag(pkb, (struct xpkt_tag_hdr *)&ts); abort_unless(rv == 0); pkb_set_len(pkb, bh->bh_caplen); pkb_set_dltype(pkb, g_prid); }
void cb_init(struct callback *cb, callback_f f, void *ctx) { abort_unless(cb); abort_unless(f); l_init(&cb->entry); cb->ctx = ctx; cb->func = f; }
char * net_tostr(struct sockaddr *sa, char *buf, size_t len) { abort_unless(len > 0); abort_unless(buf); switch ( sa->sa_family ) { case AF_INET : { struct sockaddr_in sin; uchar *p; /* XXX.XXX.XXX.XXX.XXXXX0 */ if ( len < 22 ) return NULL; sin = *(struct sockaddr_in *)sa; p = (uchar *)&sin.sin_addr; len = snprintf(buf, len, "%u.%u.%u.%u:%u", p[0], p[1], p[2], p[3], ntohs(sin.sin_port)); return buf; } break; #ifdef AF_INET6 case AF_INET6 : { char *p, *ap; char *off; ap = (char *)&((struct sockaddr_in6 *)sa)->sin6_addr; /* deliberately discard constant qualifier */ p = (char *)inet_ntop(sa->sa_family, ap, buf, len); if ( p == NULL ) return NULL; off = p + strlen(p); if ( (len - (off - p)) < 6 ) return NULL; snprintf(off, len - (off - p), ".%u", ntohs(((struct sockaddr_in6 *)sa)->sin6_port)); return p; } break; #endif /* IPV6 */ #ifdef AF_UNIX case AF_UNIX: { char *path = ((struct sockaddr_un *)sa)->sun_path; size_t plen = strlen(path) + 1; if ( len < plen ) return NULL; memcpy(buf, path, plen); return buf; } break; #endif /* AF_UNIX */ default: return NULL; } }
void pc_addpg(struct pcache *pc, void *page, size_t pgsiz) { struct pc_pool *pcp; abort_unless(pc); abort_unless(page); abort_unless(pgsiz >= sizeof(union pc_pool_u) + pl_isiz(pc->asiz, -1)); pcp = page; pl_init(&pcp->pool, pc->asiz, -1, (char *)pcp + sizeof(union pc_pool_u), pgsiz - sizeof(union pc_pool_u)); pcp->cache = pc; l_ins(&pc->avail, &pcp->entry); pc->npools += 1; }
int vfprintf(FILE *file, const char *fmt, va_list ap) { struct file_emitter e = { {EMIT_OK, file_emit_func}, NULL }; abort_unless(file && fmt); e.file = file; return emit_vformat(&e.emitter, fmt, ap); }
void * pc_alloc(struct pcache *pc) { struct pool *pp; struct pc_pool *pcp, **item; abort_unless(pc); if ( l_isempty(&pc->avail) ) { if ( l_isempty(&pc->full) ) { if ( ! pc->mm || (pc->npools == pc->maxpools) ) return NULL; pcp = mem_get(pc->mm, pc->pgsiz); if ( ! pcp ) return NULL; pc_addpg(pc, pcp, pc->pgsiz); } else { pcp = (struct pc_pool *)pc->full.next; l_rem(&pcp->entry); l_ins(pc->avail.prev, &pcp->entry); } } pcp = (struct pc_pool *)pc->avail.next; pp = &pcp->pool; if ( pp->fill == 1 ) { l_rem(&pcp->entry); l_ins(&pc->empty, &pcp->entry); } item = pl_alloc(pp); *item = pcp; return (char *)item + sizeof(cat_pcpad_t); }
int setvbuf(FILE *file, char *buf, int mode, size_t bsiz) { if ( file == NULL ) return -1; if ( mode != _IONBF && mode != _IOLBF && mode != _IOFBF ) return -1; /* enforce the rule that buffering must be performed between initial */ /* open and any subsequent operations */ if ( file->f_lastop ) return -1; if ( file->f_fill > 0 && fflush(file) < 0 ) return -1; if ( bsiz > INT_MAX ) return -1; file->f_flags &= _IOBFMASK; file->f_flags |= mode; if ( buf != NULL ) { abort_unless(bsiz > 0); file->f_flags = CAT_SIO_BUFGIVEN; file->f_buffer = buf; file->f_buflen = bsiz; } return 0; }
size_t strlen(const char *s) { int n = 0; abort_unless(s); while (*s++) ++n; return n; }
void pc_free(void *item) { struct pcache *pc; struct pc_pool *pcp; struct pool *pp; abort_unless(item); item = (char *)item - sizeof(cat_pcpad_t); pcp = *(struct pc_pool **)item; pp = &pcp->pool; if ( pp->fill == 0 ) { l_rem(&pcp->entry); l_ins(pcp->cache->avail.prev, &pcp->entry); } pl_free(pp, item); if ( pp->fill == pp->max ) { pc = pcp->cache; l_rem(&pcp->entry); if ( pc->mm && (pc->hiwat > 0) && (pc->npools > pc->hiwat) ) { mem_free(pc->mm, pcp); pc->npools -= 1; } else { l_ins(&pc->full, &pcp->entry); } } }
int net_resolv(const char *host, const char *serv, const char *proto, struct sockaddr_storage *sas) { struct addrinfo *res, *hintsp = NULL, hints; abort_unless(sas); if ( proto != NULL ) { hintsp = &hints; memset(hintsp, 0, sizeof(struct addrinfo)); hintsp->ai_family = AF_UNSPEC; if ( strcmp(proto, "tcp") == 0 ) { hintsp->ai_socktype = SOCK_STREAM; hintsp->ai_protocol = IPPROTO_TCP; } else if ( strcmp(proto, "udp") == 0 ) { hintsp->ai_socktype = SOCK_DGRAM; hintsp->ai_protocol = IPPROTO_UDP; } else { return -1; } } if ( getaddrinfo(host, serv, hintsp, &res) < 0 ) return -1; memcpy(sas, res->ai_addr, res->ai_addrlen); freeaddrinfo(res); return 0; }
static void load_prlib(const char *path) { struct oproto_library *lib; abort_unless(path != NULL); if (oprliblist == NULL) oprliblist = cl_new(NULL, 1); lib = ecalloc(sizeof(*lib), 1); lib->path = path; lib->handle = dlopen(path, RTLD_LAZY); if (lib->handle == NULL) err("%s\n", dlerror()); lib->load = dlsym(lib->handle, "load"); if (lib->load == NULL) err("%s\n", dlerror()); lib->unload = dlsym(lib->handle, "unload"); if (lib->unload == NULL) err("%s\n", dlerror()); if ((*lib->load)() < 0) errsys("Error loading %s: "); cl_push(oprliblist, lib); }
int readpkt(void *arg, struct callback *cb) { int rv; struct pktbuf *p; struct ue_ioevent *ioe = container(cb, struct ue_ioevent, cb); struct xpkt_tag_iface *xifp; struct xpkt_tag_iface xif; int n; if ((rv = pkb_fd_read_a(&p, ioe->fd, NULL, NULL)) <= 0) { if (rv < 0) logsys(1, "Error reading from fd %d\n", ioe->fd); ue_io_del(ioe); return 0; } ++g_npkts; xifp = (struct xpkt_tag_iface *)pkb_find_tag(p, XPKT_TAG_INIFACE, 0); if (xifp) { /* there's an existing tag: so modify it */ if (ioe->fd >= 3) { xifp->iface = ioe->fd - 3; } else { /* these should always succeed */ n = pkb_find_tag_idx(p, (struct xpkt_tag_hdr *)xifp); abort_unless(n >= 0); rv = pkb_del_tag(p, xifp->type, n); abort_unless(rv == 0); } } else { if (ioe->fd >= 3) { xpkt_tag_oif_init(&xif, ioe->fd - 3); rv = pkb_add_tag(p, (struct xpkt_tag_hdr *)&xif); if (rv < 0) { pkb_free(p); return 0; } } } rv = pkb_pack(p); abort_unless(rv == 0); if (pkb_fd_write(p, 1) < 0) errsys("Error writing packet %lu\n", g_npkts); pkb_free(p); return 0; }
int tcp_cli_nb_completion(int fd) { int err; socklen_t size = sizeof(err); abort_unless(fd < 0); if ( getsockopt(fd, SOL_SOCKET, SO_ERROR, &err, &size) < 0 ) return -1; return err; }
void *dbg_mem_resize(struct memmgr *mm, void *p, size_t newsize) { size_t ramt; struct dbg_header *dh; struct hnode *hn; void *p2; size_t osize; abort_unless(mm == &dbgmem); hn = ht_lkup(&dbg_htab, p, NULL); if ( hn == NULL ) errsys("dbg_mem_resize: attempt to reallocate non dynamic" "pointer: %p", p); dh = container(hn, struct dbg_header, dh_hnode); osize = dh->dh_amt; if ( newsize > 0 ) { ramt = ROUNDUP(newsize); abort_unless(ramt >= newsize); } else { ramt = 0; } p2 = realloc(dh, ramt); if ( p2 == NULL || ramt == 0 ) { if ( ramt == 0 ) { dbg_alloc_amt -= osize; --dbg_num_alloc; } return NULL; } dbg_alloc_amt = dbg_alloc_amt - osize + newsize; dh = p2; dh->dh_amt = newsize; p = TOMEM(dh); ht_ninit(&dh->dh_hnode, p); ht_ins_h(&dbg_htab, &dh->dh_hnode); return p; }
static value ocamlpool_chunk_truncate(size_t word_size) { assert_in_section(); ocamlpool_assert(ocamlpool_root != Val_unit); abort_unless((Wosize_val(ocamlpool_root) >= word_size) && (word_size >= 1)); OCAMLPOOL_SET_HEADER(ocamlpool_root, word_size, String_tag, ocamlpool_color); value *first_word = (value*)ocamlpool_root; first_word[word_size - 1] = 0; return (value)(first_word + word_size + 1); }
int file_emit_func(struct emitter *e, const void *buf, size_t len) { size_t rv; struct file_emitter *fe = (struct file_emitter *)e; abort_unless(e && buf); if ( (rv = do_fput_bytes(fe->file, buf, len)) == 0 ) { e->emit_state = EMIT_ERR; return -1; } return rv; }
void pc_delpg(void *page) { struct pc_pool *pcp; abort_unless(page); pcp = page; l_rem(&pcp->entry); pcp->cache->npools -= 1; pcp->cache = NULL; }
int memcmp(const void *b1p, const void *b2p, size_t len) { const uchar *b1 = b1p, *b2 = b2p; abort_unless(b1 && b2); while ( len > 0 && (*b1 == *b2) ) { b1++; b2++; len--; } if ( len ) return (int)*b1 - (int)*b2; else return 0; }
int strcmp(const char *c1, const char *c2) { abort_unless(c1 && c2); while ( *c1 == *c2 && *c1 != '\0' && *c2 != '\0' ) { c1++; c2++; } if ( *c1 == *c2 ) return 0; else if ( *c1 == '\0' ) return -1; else if ( *c2 == '\0' ) return 1; else return (int)*(uchar *)c1 - (int)*(uchar *)c2; }
void dbg_mem_free(struct memmgr *mm, void *p) { struct hnode *hn; struct dbg_header *dh; abort_unless(mm == &dbgmem); hn = ht_lkup(&dbg_htab, p, NULL); if ( hn == NULL ) errsys("dbg_mem_free: attempt to free non-dynamic pointer: %p", p); dh = container(hn, struct dbg_header, dh_hnode); dbg_alloc_amt -= dh->dh_amt; --dbg_num_alloc; free(dh); }
int strncmp(const char *c1, const char *c2, size_t n) { abort_unless(c1 && c2); while ( n > 0 && *c1 == *c2 && *c1 != '\0' && *c2 != '\0' ) { c1++; c2++; --n; } if ( n == 0 || *c1 == *c2 ) return 0; else if ( *c1 == '\0' ) return -1; else if ( *c2 == '\0' ) return 1; else return (int)*(uchar *)c1 - (int)*(uchar *)c2; }
static int string_match(struct peg_grammar_parser *pgp, const char *pat, struct peg_cursor *pc) { uint plen; plen = strlen(pat); abort_unless(pgp->input_len >= pc->pos); if ( plen > pgp->input_len - pc->pos ) return 0; if ( strncmp(STR(pgp, pc), pat, plen) == 0 ) { pc->pos += plen; skip_space(pgp, pc); return 1; } else { return 0; } }
value ocamlpool_reserve_block(int tag, size_t words) { assert_in_section(); if (words == 0) return Atom(tag); size_t size = words + 1; size_t remaining = ocamlpool_chunk_remaining_words(); abort_unless(size < ocamlpool_next_chunk_size); /* We cannot allocate a value bigger than the chunk size */ value result; /* Easy case: we have enough remaining space */ if (size < remaining) { result = ocamlpool_chunk_truncate(remaining - size); } /* Exactly the space we want */ else if (words == remaining) { result = ocamlpool_root; ocamlpool_root = Val_unit; } /* Two reasons to get there: * - words - 1 == remaining: * splitting the block would introduce fragmentation that is annoying to * deal with. * - words > remaining: * not enough space, allocate a new chunk */ else { ocamlpool_chunk_alloc(); result = ocamlpool_chunk_truncate(ocamlpool_chunk_remaining_words() - size); } OCAMLPOOL_SET_HEADER(result, words, tag, ocamlpool_color); for (size_t i = 0; i < words; ++i) { Field(result, i) = Val_unit; } return result; }
void *memmove(void *dst, const void *src, size_t len) { const uchar *s; uchar *d; abort_unless(dst && src); if ( src < dst ) { s = src; d = dst; while (len--) *d++ = *s++; } else if ( src > dst ) { s = (const uchar *)src + len; d = (uchar *)dst + len; while (len--) *--d = *--s; } return dst; }
int snprintf(char *buf, size_t len, const char *fmt, ...) { struct string_emitter se; va_list ap; int rlen; abort_unless(buf && fmt); if ( len <= 1 ) return 0; va_start(ap, fmt); string_emitter_init(&se, buf, len); rlen = emit_vformat(&se.se_emitter, fmt, ap); string_emitter_terminate(&se); va_end(ap); return rlen; }
int cb_run(struct list *l, void *arg) { struct list *node; struct callback *cb; int r; abort_unless(l); node = l_head(l); while ( node != l_end(l) ) { cb = container(node, struct callback, entry); node = node->next; if ( (r = (*cb->func)(arg, cb)) ) return r; } return 0; }
int net_resolv(const char *host, const char *serv, const char *proto, struct sockaddr_storage *sas) { struct hostent *hp; struct servent *sp; ulong portnum; char *cp; struct sockaddr_in *sin = (struct sockaddr_in *)sas; abort_unless(sas); memset(sas, 0, sizeof(struct sockaddr_in)); sin->sin_family = AF_INET; /* Look up the address */ if ( !host || !*host ) sin->sin_addr.s_addr = INADDR_ANY; else if ( inet_pton(AF_INET, host, &sin->sin_addr.s_addr) ) ; else if ( (hp = gethostbyname(host)) ) memcpy(&sin->sin_addr, hp->h_addr, hp->h_length); else return -1; /* now look up the service */ if (!serv || !*serv) { sin->sin_port = 0; goto skiplookup; } portnum = strtoul(serv, &cp, 0); if ( cp != serv ) { if ( portnum > 65535 ) return -1; sin->sin_port = htons(portnum); } else if ( (sp = getservbyname(serv, proto)) ) sin->sin_port = sp->s_port; else return -1; skiplookup: return 0; }
static void peg_node_free(struct peg_grammar *peg, int nn) { struct peg_node *pn; if ( nn < 0 || nn >= peg->max_nodes ) return; pn = NODE(peg, nn); switch ( pn->pn_type ) { case PEG_DEFINITION: peg_node_free(peg, pn->pd_id); peg_node_free(peg, pn->pd_expr); break; case PEG_SEQUENCE: peg_node_free(peg, pn->ps_pri); peg_node_free(peg, pn->pn_next); break; case PEG_PRIMARY: peg_node_free(peg, pn->pp_match); peg_node_free(peg, pn->pn_next); if ( pn->pp_action != PEG_ACT_NONE ) free_str(&pn->pp_label); break; case PEG_IDENTIFIER: --pn->pi_refcnt; if ( pn->pi_refcnt > 0 ) return; free_str(&pn->pi_name); break; case PEG_LITERAL: free_str(&pn->pl_value); break; case PEG_CLASS: free_str(&pn->pc_cset_raw); break; default: return; } abort_unless(peg->num_nodes > 0); --peg->num_nodes; pn->pn_type = PEG_NONE; }