/* to catch use after free */
bp->rptr = (uchar*)0xdeadbabe;
bp->wptr = (uchar*)0xdeadbabe;
bp->next = (Block*)0xdeadbabe;
bp->list = (Block*)0xdeadbabe;
ADEBUG aunref(&arefblock, bp->pc);
bp = next;
}
qunlock(&area);
}
/*
* concatenate a list of blocks into a single one and make sure
* the result is at least min uchars
*/
Block*
concat(Block *bp)
{
int len;
Block *nb, *f;
nb = allocb(blen(bp));
for(f = bp; f; f = f->next) {
len = BLEN(f);
memmove(nb->wptr, f->rptr, len);
nb->wptr += len;
}
freeb(bp);
return nb;
}
int
blen(Block *bp)
{
int len;
len = 0;
while(bp) {
len += BLEN(bp);
bp = bp->next;
}
return len;
}
Block *
pullup(Block *bp, int n)
{
int i;
Block *nbp;
/*
* this should almost always be true, the rest it
* just for to avoid every caller checking.
*/
if(BLEN(bp) >= n)
return bp;
/*
* if not enough room in the first block,
* add another to the front of the list.
*/
if(bp->lim - bp->rptr < n){
nbp = allocb(n);
nbp->next = bp;
bp = nbp;
}
/*
* copy uchars from the trailing blocks into the first
*/
n -= BLEN(bp);
while(nbp = bp->next){
i = BLEN(nbp);
if(i >= n) {
memmove(bp->wptr, nbp->rptr, n);
bp->wptr += n;
nbp->rptr += n;
return bp;
}
else {
memmove(bp->wptr, nbp->rptr, i);
bp->wptr += i;
bp->next = nbp->next;
nbp->next = nil;
freeb(nbp);
n -= i;
}
}
freeb(bp);
return nil;
}
/*
* Pad a block to the front with n uchars. This is used to add protocol
* headers to the front of blocks.
*/
Block*
padb(Block *bp, int n)
{
Block *nbp;