void bufwrite_bufdel(caryll_Buffer *buf, caryll_Buffer *that) { if (!that) return; if (!that->data) { buffree(that); return; } size_t len = buflen(that); bufbeforewrite(buf, len); memcpy(buf->data + buf->cursor, that->data, len); buffree(that); buf->cursor += len; }
char *unquoteurl(char *in) { struct charbuf buf; char *p; int c; bufinit(buf); p = in; while(*p) { if(*p == '%') { if(!p[1] || !p[2]) goto fail; c = 0; if((p[1] >= '0') && (p[1] <= '9')) c |= (p[1] - '0') << 4; else if((p[1] >= 'a') && (p[1] <= 'f')) c |= (p[1] - 'a' + 10) << 4; else if((p[1] >= 'A') && (p[1] <= 'F')) c |= (p[1] - 'A' + 10) << 4; else goto fail; if((p[2] >= '0') && (p[2] <= '9')) c |= (p[2] - '0'); else if((p[2] >= 'a') && (p[2] <= 'f')) c |= (p[2] - 'a' + 10); else if((p[2] >= 'A') && (p[2] <= 'F')) c |= (p[2] - 'A' + 10); else goto fail; bufadd(buf, c); p += 3; } else { bufadd(buf, *(p++)); } } bufadd(buf, 0); return(buf.b); fail: buffree(buf); return(NULL); }
/** * @ingroup etherspecific * * Callback function executed with interrupts disabled when an asynchronous USB * bulk transfer to the Bulk OUT endpoint of the SMSC LAN9512 USB Ethernet * Adapter for the purpose of sending an Ethernet packet has successfully * completed or has failed. * * Currently all this function has to do is return the buffer to its pool. This * may wake up a thread in etherWrite() that is waiting for a free buffer. * * @param req * USB bulk OUT transfer request that has completed. */ void smsc9512_tx_complete(struct usb_xfer_request *req) { struct ether *ethptr = req->private; ethptr->txirq++; usb_dev_debug(req->dev, "SMSC9512: Tx complete\n"); buffree(req); }
/* * truncate d (in p) to zero length. * freeing blocks in reverse order is traditional, from Unix, * in an attempt to keep the free list contiguous. */ void dtrunc(Iobuf *p, Dentry *d, int uid) { int i; for (i = NIBLOCK-1; i >= 0; i--) { buffree(p->dev, d->iblocks[i], i+1, nil); d->iblocks[i] = 0; } for (i = NDBLOCK-1; i >= 0; i--) { buffree(p->dev, d->dblock[i], 0, nil); d->dblock[i] = 0; } d->size = 0; p->flags |= Bmod|Bimm; accessdir(p, d, FWRITE, uid); }
static void outplex(struct muth *muth, va_list args) { vavar(FILE *, sk); struct { struct ch { FILE *s; int id; } *b; size_t s, d; } outs; int i; struct ch ch; int type, rid; char *data; size_t dlen; bufinit(outs); while((ch.s = va_arg(args, FILE *)) != NULL) { ch.id = va_arg(args, int); bufadd(outs, ch); } data = NULL; while(1) { if(recvrec(sk, &type, &rid, &data, &dlen)) goto out; if(rid != 1) goto out; for(i = 0; i < outs.d; i++) { if(outs.b[i].id == type) { if(outs.b[i].s != NULL) { if(dlen == 0) { fclose(outs.b[i].s); outs.b[i].s = NULL; } else { if(fwrite(data, 1, dlen, outs.b[i].s) != dlen) goto out; } } break; } } free(data); data = NULL; } out: if(data != NULL) free(data); for(i = 0; i < outs.d; i++) { if(outs.b[i].s != NULL) fclose(outs.b[i].s); } buffree(outs); fclose(sk); }
/* * free the block at `addr' on dev. * if it's an indirect block (d [depth] > 0), * first recursively free all the blocks it names. * * ts->relblk is the block number within the file of this * block (or the first data block eventually pointed to via * this indirect block). */ void buffree(Device *dev, Off addr, int d, Truncstate *ts) { Iobuf *p; Off a; int i, pastlast; if(!addr) return; pastlast = (ts == nil? 1: ts->pastlast); /* * if this is an indirect block, recurse and free any * suitable blocks within it (possibly via further indirect blocks). */ if(d > 0) { d--; p = getbuf(dev, addr, Brd); if(p) { if (ts == nil) /* common case: create */ for(i=INDPERBUF-1; i>=0; i--) { a = ((Off *)p->iobuf)[i]; buffree(dev, a, d, nil); } else /* wstat truncation */ for (i = 0; i < INDPERBUF; i++) truncfree(ts, dev, d, p, i); putbuf(p); } } if (!pastlast) return; /* * having zeroed the pointer to this block, add it to the free list. * stop outstanding i/o */ p = getbuf(dev, addr, Bprobe); if(p) { p->flags &= ~(Bmod|Bimm); putbuf(p); } /* * dont put written worm * blocks into free list */ if(dev->type == Devcw) { i = cwfree(dev, addr); if(i) return; } p = getbuf(dev, superaddr(dev), Brd|Bmod); if(!p || checktag(p, Tsuper, QPSUPER)) panic("buffree: super block"); addfree(dev, addr, (Superb*)p->iobuf); putbuf(p); }
/* * truncate d (in p) to length `newsize'. * if larger, just increase size. * if smaller, deallocate blocks after last one * still in file at new size. last byte to keep * is newsize-1, due to zero origin. * we free in forward order because it's simpler to get right. * if the final block at the new size is partially-filled, * zero the remainder. */ int dtrunclen(Iobuf *p, Dentry *d, Off newsize, int uid) { int i, pastlast; Truncstate trunc; if (newsize <= 0) { dtrunc(p, d, uid); return 0; } memset(&trunc, 0, sizeof trunc); trunc.d = d; trunc.p = p; trunc.uid = uid; trunc.newsize = newsize; trunc.lastblk = newsize/BUFSIZE; if (newsize % BUFSIZE == 0) trunc.lastblk--; else trunczero(&trunc); for (i = 0; i < NDBLOCK; i++) if (trunc.pastlast) { trunc.relblk = i; buffree(p->dev, d->dblock[i], 0, &trunc); d->dblock[i] = 0; } else if (i == trunc.lastblk) trunc.pastlast = 1; trunc.relblk = NDBLOCK; for (i = 0; i < NIBLOCK; i++) { pastlast = trunc.pastlast; buffree(p->dev, d->iblocks[i], i+1, &trunc); if (pastlast) d->iblocks[i] = 0; } d->size = newsize; p->flags |= Bmod|Bimm; accessdir(p, d, FWRITE, uid); return trunc.err; }
int memory::switchbuf(unsigned int i) // creates a new buffer with size >= i { bufcount++; // the new buffer has number bufcount if (bufcount == BUFPOS) { buffree(); bufcount--; printf("The blocks are used up.\n"); delete this; exit(0); // freebuf(); } if (bufcount < BUFSBSWITCH) rest[bufcount] = BUFS_SMALL; else{ int j = BUFPOS/(BUFPOS-bufcount); if(j<12) rest[bufcount] = power2[j-1]*BUFS_BIG; else rest[bufcount] = power2[11]*BUFS_BIG; } if (rest[bufcount] < i) rest[bufcount] = i; restsize[bufcount] = rest[bufcount]; buffer[bufcount] = new char[rest[bufcount]]; if (buffer[bufcount] == NULL) { #ifdef DEBUG perror("switchbuf 1"); #endif buffree(); printf("Not enough memory!\n"); delete this; // freebuf(); } start[bufcount] = buffer[bufcount]; return bufcount; } // switchbuf
/* truncating to length > 0 */ static void truncfree(Truncstate *ts, Device *dev, int d, Iobuf *p, int i) { int pastlast; Off a; pastlast = ts->pastlast; a = ((Off *)p->iobuf)[i]; if (d > 0 || pastlast) buffree(dev, a, d, ts); if (pastlast) { ((Off *)p->iobuf)[i] = 0; p->flags |= Bmod|Bimm; } else if (d == 0 && ts->relblk == ts->lastblk) ts->pastlast = 1; if (d == 0) ts->relblk++; }
int recvreq(int sock, struct hthead **reqp) { int fd; struct charbuf buf; char *p; size_t l; char *name, *val; struct hthead *req; if((fd = recvfd(sock, &buf.b, &buf.d)) < 0) { return(-1); } fcntl(fd, F_SETFD, FD_CLOEXEC); buf.s = buf.d; p = buf.b; l = buf.d; *reqp = omalloc(req); if((req->method = sstrdup(decstr(&p, &l))) == NULL) goto fail; if((req->url = sstrdup(decstr(&p, &l))) == NULL) goto fail; if((req->ver = sstrdup(decstr(&p, &l))) == NULL) goto fail; if((req->rest = sstrdup(decstr(&p, &l))) == NULL) goto fail; while(1) { if(!*(name = decstr(&p, &l))) break; val = decstr(&p, &l); headappheader(req, name, val); } buffree(buf); return(fd); fail: close(fd); freehthead(req); errno = EPROTO; return(-1); }
int sendreq2(int sock, struct hthead *req, int fd, int flags) { int ret, i; struct charbuf buf; bufinit(buf); bufcatstr2(buf, req->method); bufcatstr2(buf, req->url); bufcatstr2(buf, req->ver); bufcatstr2(buf, req->rest); for(i = 0; i < req->noheaders; i++) { bufcatstr2(buf, req->headers[i][0]); bufcatstr2(buf, req->headers[i][1]); } bufcatstr2(buf, ""); ret = sendfd2(sock, fd, buf.b, buf.d, flags); buffree(buf); if(ret < 0) return(-1); else return(0); }
/** * Transmit packet interrupt handler */ void txPackets(struct ether *ethptr, struct ag71xx *nicptr) { struct dmaDescriptor *dmaptr; struct ethPktBuffer **epb = NULL; struct ethPktBuffer *pkt = NULL; ulong head = 0; // kprintf("txS=0x%08X\r\n", nicptr->txStatus); if (ethptr->txHead == ethptr->txTail) { nicptr->txStatus = TX_STAT_SENT; return; } while (ethptr->txHead != ethptr->txTail) { head = ethptr->txHead % ETH_TX_RING_ENTRIES; dmaptr = ðptr->txRing[head]; if (!(dmaptr->control & ETH_DESC_CTRL_EMPTY)) { break; } epb = ðptr->txBufs[head]; // Clear Tx interrupt. nicptr->txStatus = TX_STAT_SENT; ethptr->txHead++; pkt = *epb; if (NULL == pkt) { continue; } buffree((void *)((ulong)pkt & (PMEM_MASK | KSEG0_BASE))); *epb = NULL; } }
static struct hthead *parsereq(struct bufio *in) { struct hthead *req; struct charbuf method, url, ver; int c; req = NULL; bufinit(method); bufinit(url); bufinit(ver); while(1) { c = biogetc(in); if(c == ' ') { break; } else if((c == EOF) || (c < 32) || (c >= 128)) { goto fail; } else { bufadd(method, c); if(method.d >= 128) goto fail; } } while(1) { c = biogetc(in); if(c == ' ') { break; } else if((c == EOF) || (c < 32)) { goto fail; } else { bufadd(url, c); if(url.d >= 65536) goto fail; } } while(1) { c = biogetc(in); if(c == 10) { break; } else if(c == 13) { } else if((c == EOF) || (c < 32) || (c >= 128)) { goto fail; } else { bufadd(ver, c); if(ver.d >= 128) goto fail; } } bufadd(method, 0); bufadd(url, 0); bufadd(ver, 0); req = mkreq(method.b, url.b, ver.b); if(parseheadersb(req, in)) goto fail; trimx(req); goto out; fail: if(req != NULL) { freehthead(req); req = NULL; } out: buffree(method); buffree(url); buffree(ver); return(req); }
/** * Control function for ethloop devices. * @param devptr ethloop device table entry * @param func control function to execute * @param arg1 first argument for the control function * @param arg2 second argument for the control function * @return the result of the control function */ devcall ethloopControl(device *devptr, int func, long arg1, long arg2) { struct ethloop *elpptr; struct netaddr *addr; uchar old; irqmask im; char *buf; char *hold; int holdlen; elpptr = &elooptab[devptr->minor]; im = disable(); if (ELOOP_STATE_ALLOC != elpptr->state) { restore(im); return SYSERR; } switch (func) { /* Get link header length. */ case NET_GET_LINKHDRLEN: restore(im); return ETH_HDR_LEN; /* Get MAC address from card. */ case NET_GET_HWADDR: restore(im); addr = (struct netaddr *)arg1; addr->type = NETADDR_ETHERNET; addr->len = ETH_ADDR_LEN; addr->addr[0] = 0xAA; addr->addr[1] = 0xBB; addr->addr[2] = 0xCC; addr->addr[3] = 0xDD; addr->addr[4] = 0xEE; addr->addr[5] = 0xFF; break; /* Get broadcast MAC address. */ case NET_GET_HWBRC: restore(im); addr = (struct netaddr *)arg1; addr->type = NETADDR_ETHERNET; addr->len = ETH_ADDR_LEN; addr->addr[0] = 0xFF; addr->addr[1] = 0xFF; addr->addr[2] = 0xFF; addr->addr[3] = 0xFF; addr->addr[4] = 0xFF; addr->addr[5] = 0xFF; break; /* Get MTU. */ case NET_GET_MTU: restore(im); return ELOOP_MTU; /* Get next packet off hold queue */ case ELOOP_CTRL_GETHOLD: buf = (char *)arg1; /* Wait for held packet */ wait(elpptr->hsem); /* Get and clear held packet */ hold = elpptr->hold; holdlen = elpptr->holdlen; elpptr->hold = NULL; elpptr->holdlen = 0; restore(im); /* Copy held packet to buffer */ if (arg2 < holdlen) { holdlen = arg2; } memcpy(buf, hold, holdlen); /* Free hold buffer */ buffree(hold); return holdlen; /* Set flags */ case ELOOP_CTRL_SETFLAG: old = elpptr->flags & arg1; elpptr->flags |= (arg1); restore(im); return old; /* Clear flags */ case ELOOP_CTRL_CLRFLAG: old = elpptr->flags & arg1; elpptr->flags &= ~(arg1); restore(im); return old; default: restore(im); return SYSERR; } restore(im); return OK; }
int main(int argc, char **argv) { if (argc < 2 || argc > 4) usage("pattern_file target_file [[-]expected]\ne.g. acism_x patts act.txt -5"); MEMBUF patt = chomp(slurp(argv[1])); if (!patt.ptr) die("cannot read %s", argv[1]); int npatts; MEMREF *pattv = refsplit(patt.ptr, '\n', &npatts); double t = tick(); ACISM *psp = acism_create(pattv, npatts); t = tick() - t; plan_tests(argc < 3 ? 1 : 3); ok(psp, "acism_create(pattv[%d]) compiled, in %.3f secs", npatts, t); acism_dump(psp, PS_ALL, stderr, pattv); #ifdef ACISM_STATS { int i; for (i = 1; i < (int)psstat[0].val; ++i) if (psstat[i].val) fprintf(stderr, "%11llu %s\n", psstat[i].val, psstat[i].name); } #endif//ACISM_STATS diag("state machine saved as acism.tmp"); FILE *fp = FOPEN("acism.tmp", "w"); acism_save(fp, psp); fclose(fp); if (argc > 2) { // Negative count => print match details int expected = argc > 3 ? atoi(argv[3]) : 0; int details = expected < 0; if (details) expected = -expected; FILE* textfp = FOPEN(argv[2], "r"); // REUSE PATTERN FILE AS A TARGET if (!fp) die("cannot open %s", argv[2]); static char buf[1024*1024]; MEMREF text = {buf, 0}; int state = 0; double elapsed = 0, start = tick(); while (0 < (text.len = fread(buf, sizeof*buf, sizeof buf, textfp))) { t = tick(); (void)acism_more(psp, text, (ACISM_ACTION*)on_match, pattv, &state); elapsed += tick() - t; putc('.', stderr); } putc('\n', stderr); fclose(textfp); ok(text.len == 0, "text_file scanned in 1M blocks; read(s) took %.3f secs", tick() - start - elapsed); if (!ok(actual == expected || expected == 0, "%d matches found, in %.3f secs", actual, elapsed)) diag("actual: %d\n", actual); } buffree(patt); free(pattv); acism_destroy(psp); return exit_status(); }
syscall rtpFreebuf(struct rtpPkt *rtppkt) { return buffree(rtppkt); }
static void serve(struct muth *muth, va_list args) { vavar(struct hthead *, req); vavar(int, fd); vavar(int, sfd); FILE *is, *os, *outi, *outo, *erri, *erro; struct charbuf head; struct hthead *resp; size_t read; char buf[8192]; sfd = reconn(); is = mtstdopen(fd, 1, 60, "r+", NULL); os = mtstdopen(sfd, 1, 600, "r+", NULL); outi = NULL; mtiopipe(&outi, &outo); mtiopipe(&erri, &erro); mustart(outplex, mtstdopen(dup(sfd), 1, 600, "r+", NULL), outo, FCGI_STDOUT, erro, FCGI_STDERR, NULL); mustart(errhandler, erri); if(begreq(os, 1)) goto out; bufinit(head); mkcgienv(req, &head); if(sendrec(os, FCGI_PARAMS, 1, head.b, head.d)) goto out; if(sendrec(os, FCGI_PARAMS, 1, NULL, 0)) goto out; buffree(head); if(fflush(os)) goto out; while(!feof(is)) { read = fread(buf, 1, sizeof(buf), is); if(ferror(is)) goto out; if(sendrec(os, FCGI_STDIN, 1, buf, read)) goto out; } if(sendrec(os, FCGI_STDIN, 1, NULL, 0)) goto out; if(fflush(os)) goto out; if((resp = parseresp(outi)) == NULL) goto out; writeresp(is, resp); freehthead(resp); fputc('\n', is); if(passdata(outi, is) < 0) goto out; out: freehthead(req); buffree(head); shutdown(sfd, SHUT_RDWR); if(outi != NULL) fclose(outi); fclose(is); fclose(os); }
int parseheadersb(struct hthead *head, struct bufio *in) { int c, state; struct charbuf name, val; size_t tsz; bufinit(name); bufinit(val); state = 0; tsz = 0; while(1) { c = biogetc(in); if(++tsz >= 65536) goto fail; again: if(state == 0) { if(c == '\r') { } else if(c == '\n') { break; } else if(c == EOF) { goto fail; } else { state = 1; goto again; } } else if(state == 1) { if(c == ':') { trim(&name); bufadd(name, 0); state = 2; } else if(c == '\r') { } else if(c == '\n') { goto fail; } else if(c == EOF) { goto fail; } else { bufadd(name, c); } } else if(state == 2) { if(c == '\r') { } else if(c == '\n') { trim(&val); bufadd(val, 0); headappheader(head, name.b, val.b); buffree(name); buffree(val); state = 0; } else if(c == EOF) { goto fail; } else { bufadd(val, c); } } } return(0); fail: buffree(name); buffree(val); return(-1); }
struct hthead *parseresponseb(struct bufio *in) { struct hthead *req; int code; struct charbuf ver, msg; int c; req = NULL; bufinit(ver); bufinit(msg); code = 0; while(1) { c = biogetc(in); if(c == ' ') { break; } else if((c == EOF) || (c < 32) || (c >= 128)) { goto fail; } else { bufadd(ver, c); if(ver.d >= 128) goto fail; } } while(1) { c = biogetc(in); if(c == ' ') { break; } else if((c == EOF) || (c < '0') || (c > '9')) { goto fail; } else { code = (code * 10) + (c - '0'); if(code >= 10000) goto fail; } } while(1) { c = biogetc(in); if(c == 10) { break; } else if(c == 13) { } else if((c == EOF) || (c < 32)) { goto fail; } else { bufadd(msg, c); if(msg.d >= 512) goto fail; } } bufadd(msg, 0); bufadd(ver, 0); req = mkresp(code, msg.b, ver.b); if(parseheadersb(req, in)) goto fail; goto out; fail: if(req != NULL) { freehthead(req); req = NULL; } out: buffree(msg); buffree(ver); return(req); }
thread test_bufpool(bool verbose) { bool passed = TRUE; int id, i; void *pbuf; void *chain[TBUFNUM]; irqmask im; ulong memsize; char datums[] = { "abcdefghijklmnopqrstuvwxyz1234567" }; /* Create buffer pool */ testPrint(verbose, "Create buffer pool"); im = disable(); memsize = memlist.length; id = bfpalloc(TBUFSIZE, TBUFNUM); if (memlist.length != memsize - ((TBUFSIZE + sizeof(struct poolbuf)) * TBUFNUM)) { restore(im); testFail(verbose, "\nmemlist.length reduction does not match pool size"); return OK; } else { restore(im); testPass(verbose, ""); } /* Allocate single buffer */ testPrint(verbose, "Allocate single buffer"); pbuf = bufget(id); if (SYSERR == (ulong)pbuf) { passed = FALSE; testFail(verbose, "\nbufget() returns SYSERR"); } else { testPass(verbose, ""); /* Return single buffer */ testPrint(verbose, "Return single buffer"); if (SYSERR == buffree(pbuf)) { passed = FALSE; testFail(verbose, "\nbuffree() returns SYSERR"); } else { testPass(verbose, ""); } } /* Allocate and fill all buffers in pool */ testPrint(verbose, "Allocate and fill all buffers"); for (i = 0; i < TBUFNUM; i++) { pbuf = bufget(id); chain[i] = pbuf; if (SYSERR == (ulong)pbuf) { break; } memcpy(pbuf, datums, TBUFSIZE); } if (TBUFNUM != i) { passed = FALSE; testFail(verbose, "\ngetbuf() returns SYSERR"); } else { for (i = 0; i < TBUFNUM; i++) { pbuf = chain[i]; if (0 != memcmp(pbuf, datums, TBUFSIZE)) { break; } } if (TBUFNUM != i) { passed = FALSE; testFail(verbose, "\nbuffer data does not match source"); } else { testPass(verbose, ""); /* Free all buffers in pool */ testPrint(verbose, "Free all buffers"); for (i = 0; i < TBUFNUM; i++) { pbuf = chain[i]; if (SYSERR == buffree(pbuf)) { break; } } if (TBUFNUM != i) { passed = FALSE; testFail(verbose, "\nbuffree() returns SYSERR"); } else { testPass(verbose, ""); } } } /* Release pool */ testPrint(verbose, "Free buffer pool"); im = disable(); memsize = memlist.length; bfpfree(id); if (memlist.length != memsize + ((TBUFSIZE + sizeof(struct poolbuf)) * TBUFNUM)) { restore(im); passed = FALSE; testFail(verbose, "\nmemlist.length increase does not match pool size"); } else { restore(im); testPass(verbose, ""); } /* Final report */ if (TRUE == passed) { testPass(TRUE, ""); } else { testFail(TRUE, ""); } return OK; }