Attr* _copyattr(Attr *a) { Attr **la, *na; na = nil; la = &na; for(; a; a=a->next) { *la = _mkattr(a->type, a->name, a->val, nil); setmalloctag(*la, getcallerpc(&a)); la = &(*la)->next; } *la = nil; return na; }
char* estrdupn(char *s, int n) { int l; char *t; l = strlen(s); if(l > n) l = n; t = emalloc(l+1); memmove(t, s, l); t[l] = '\0'; setmalloctag(t, getcallerpc(&s)); return t; }
void * ezmalloc(uint32_t n) { void *p; p = malloc(n); if(p == nil){ if(abortonmem) abort(); sysfatal("out of memory allocating %lud", n); } memset(p, 0, n); setmalloctag(p, getcallerpc()); if(0)print("ezmalloc %p-%p by %#p\n", p, (char*)p+n, getcallerpc()); return p; }
Attr* _mkattr(int type, char *name, char *val, Attr *next) { Attr *a; a = malloc(sizeof(*a)); if(a==nil) sysfatal("_mkattr malloc: %r"); a->type = type; a->name = strdup(name); a->val = strdup(val); if(a->name==nil || a->val==nil) sysfatal("_mkattr malloc: %r"); a->next = next; setmalloctag(a, getcallerpc(&type)); return a; }
Block* allocb(int size) { Block *b; /* * Check in a process and wait until successful. * Can still error out of here, though. */ if(up == nil) panic("allocb without up: %p\n", getcallerpc(&size)); if((b = _allocb(size)) == nil){ panic("allocb: no memory for %d bytes\n", size); } setmalloctag(b, getcallerpc(&size)); return b; }
/* * write to a queue. only Maxatomic bytes at a time is atomic. */ int qwrite(Queue *q, void *vp, int len) { int n, sofar; Block *b; uchar *p = vp; QDEBUG if(!islo()) print("qwrite hi %#p\n", getcallerpc(&q)); /* stop queue bloat before allocating blocks */ if(q->len/2 >= q->limit && q->noblock == 0 && q->bypass == nil){ while(waserror()){ if(up->procctl == Proc_exitme || up->procctl == Proc_exitbig) error(Egreg); } qflow(q); poperror(); } sofar = 0; do { n = len-sofar; if(n > Maxatomic) n = Maxatomic; b = allocb(n); setmalloctag(b, (up->text[0]<<24)|(up->text[1]<<16)|(up->text[2]<<8)|up->text[3]); if(waserror()){ freeb(b); nexterror(); } memmove(b->wp, p+sofar, n); poperror(); b->wp += n; qbwrite(q, b); sofar += n; } while(sofar < len && (q->state & Qmsg) == 0); return len; }
Block* iallocb(int size) { Block *b; static int m1, m2, mp; if(ialloc.bytes > conf.ialloc){ if((m1++%10000)==0){ if(mp++ > 1000){ active.exiting = 1; exit(0); } iprint("iallocb: limited %lud/%lud\n", ialloc.bytes, conf.ialloc); } return nil; } if((b = _allocb(size)) == nil){ if((m2++%10000)==0){ if(mp++ > 1000){ active.exiting = 1; exit(0); } iprint("iallocb: no memory %lud/%lud\n", ialloc.bytes, conf.ialloc); } return nil; } setmalloctag(b, getcallerpc(&size)); b->flag = BINTR; ilock(&ialloc); ialloc.bytes += b->lim - b->base; iunlock(&ialloc); return b; }
// allocate an n bit 0'd number mpint* mpnew(int n) { mpint *b; if(n < 0) sysfatal("mpsetminbits: n < 0"); b = mallocz(sizeof(mpint), 1); setmalloctag(b, getcallerpc(&n)); if(b == nil) sysfatal("mpnew: %r"); n = DIGITS(n); if(n < mpmindigits) n = mpmindigits; b->p = (mpdigit*)mallocz(n*Dbytes, 1); if(b->p == nil) sysfatal("mpnew: %r"); b->size = n; b->sign = 1; return b; }
Block* allocb(int size) { Block *b; /* * Check in a process and wait until successful. * Can still error out of here, though. */ if(up == nil) panic("allocb without up: %#p", getcallerpc(&size)); if((b = _allocb(size)) == nil){ splhi(); xsummary(); mallocsummary(); delay(500); panic("allocb: no memory for %d bytes; caller %#p", size, getcallerpc(&size)); } setmalloctag(b, getcallerpc(&size)); return b; }
// convert a big-endian byte array (most significant byte first) to an mpint mpint* betomp(uchar *p, uint n, mpint *b) { int m, s; mpdigit x; if(b == nil){ b = mpnew(0); setmalloctag(b, getcallerpc(&p)); } // dump leading zeros while(*p == 0 && n > 1){ p++; n--; } // get the space mpbits(b, n*8); b->top = DIGITS(n*8); m = b->top-1; // first digit might not be Dbytes long s = ((n-1)*8)%Dbits; x = 0; for(; n > 0; n--){ x |= ((mpdigit)(*p++)) << s; s -= 8; if(s < 0){ b->p[m--] = x; s = Dbits-8; x = 0; } } return b; }
int vtGetString(Packet *p, char **ret) { uint8_t buf[2]; int n; char *s; if(!packetConsume(p, buf, 2)) return 0; n = (buf[0]<<8) + buf[1]; if(n > VtMaxStringSize) { vtSetError(EBigString); return 0; } s = vtMemAlloc(n+1); setmalloctag(s, getcallerpc()); if(!packetConsume(p, (uint8_t*)s, n)) { vtMemFree(s); return 0; } s[n] = 0; *ret = s; return 1; }
void * vtMemBrk(int n) { static Lock lk; static uint8_t *buf; static int nbuf; static int nchunk; int align, pad; void *p; if(n >= IdealAlignment) align = IdealAlignment; else if(n > 8) align = 8; else align = 4; lock(&lk); pad = (align - (uintptr)buf) & (align-1); if(n + pad > nbuf) { buf = vtMemAllocZ(ChunkSize); setmalloctag(buf, getcallerpc(&n)); nbuf = ChunkSize; pad = (align - (uintptr)buf) & (align-1); nchunk++; } assert(n + pad <= nbuf); p = buf + pad; buf += pad + n; nbuf -= pad + n; unlock(&lk); return p; }
/* * search for a tuple that has the given 'attr=val' and also 'rattr=x'. * copy 'x' into 'buf' and return the whole tuple. * * return 0 if not found. */ char* csgetvalue(char *netroot, char *attr, char *val, char *rattr, Ndbtuple **pp) { Ndbtuple *t, *first, *last; int n, linefound; char line[1024]; int fd; int oops = 0; char *rv; if(pp) *pp = nil; rv = nil; if(netroot) snprint(line, sizeof(line), "%s/cs", netroot); else strcpy(line, "/net/cs"); fd = open(line, ORDWR); if(fd < 0) return 0; seek(fd, 0, 0); snprint(line, sizeof(line), "!%s=%s %s=*", attr, val, rattr); if(write(fd, line, strlen(line)) < 0){ close(fd); return 0; } seek(fd, 0, 0); first = last = 0; linefound = 0; for(;;){ n = read(fd, line, sizeof(line)-2); if(n <= 0) break; line[n] = '\n'; line[n+1] = 0; t = _ndbparseline(line); if(t == 0) continue; if(first) last->entry = t; else first = t; last = t; while(last->entry) last = last->entry; for(; t; t = t->entry){ if(linefound == 0){ if(strcmp(rattr, t->attr) == 0){ linefound = 1; rv = strdup(t->val); } } } } close(fd); if(oops){ werrstr("buffer too short"); ndbfree(first); return nil; } if(pp){ setmalloctag(first, getcallerpc(&netroot)); *pp = first; } else ndbfree(first); return rv; }
Whist* Brdwhist(Biobuf *b) { int i, current, conflict, c, n; char *author, *comment, *p, *title; uint32_t t; Wdoc *w; Whist *h; if((p = Brdline(b, '\n')) == nil){ werrstr("short read: %r"); return nil; } p[Blinelen(b)-1] = '\0'; p = strcondense(p, 1); title = estrdup(p); w = nil; n = 0; t = -1; author = nil; comment = nil; conflict = 0; current = 0; while((c = Bgetc(b)) != Beof){ if(c != '#'){ p = Brdline(b, '\n'); if(p == nil) break; p[Blinelen(b)-1] = '\0'; switch(c){ case 'D': t = strtoul(p, 0, 10); break; case 'A': free(author); author = estrdup(p); break; case 'C': free(comment); comment = estrdup(p); break; case 'X': conflict = 1; } } else { /* c=='#' */ Bungetc(b); if(n%8 == 0) w = erealloc(w, (n+8)*sizeof(w[0])); w[n].time = t; w[n].author = author; w[n].comment = comment; comment = nil; author = nil; w[n].wtxt = Brdpage(Brdwline, b); w[n].conflict = conflict; if(w[n].wtxt == nil) goto Error; if(!conflict) current = n; n++; conflict = 0; t = -1; } } if(w==nil) goto Error; free(comment); free(author); h = emalloc(sizeof *h); h->title = title; h->doc = w; h->ndoc = n; h->current = current; incref(h); setmalloctag(h, getcallerpc()); return h; Error: free(title); free(author); free(comment); for(i=0; i<n; i++){ free(w[i].author); free(w[i].comment); freepage(w[i].wtxt); } free(w); return nil; }