diff options
author | Taru Karttunen <taruti@taruti.net> | 2011-03-30 15:46:40 +0300 |
---|---|---|
committer | Taru Karttunen <taruti@taruti.net> | 2011-03-30 15:46:40 +0300 |
commit | e5888a1ffdae813d7575f5fb02275c6bb07e5199 (patch) | |
tree | d8d51eac403f07814b9e936eed0c9a79195e2450 /sys/src/cmd/unix/drawterm/kern/pgrp.c |
Import sources from 2011-03-30 iso image
Diffstat (limited to 'sys/src/cmd/unix/drawterm/kern/pgrp.c')
-rwxr-xr-x | sys/src/cmd/unix/drawterm/kern/pgrp.c | 272 |
1 files changed, 272 insertions, 0 deletions
diff --git a/sys/src/cmd/unix/drawterm/kern/pgrp.c b/sys/src/cmd/unix/drawterm/kern/pgrp.c new file mode 100755 index 000000000..30b1f3e7b --- /dev/null +++ b/sys/src/cmd/unix/drawterm/kern/pgrp.c @@ -0,0 +1,272 @@ +#include "u.h" +#include "lib.h" +#include "dat.h" +#include "fns.h" +#include "error.h" + +static Ref pgrpid; +static Ref mountid; + +#ifdef NOTDEF +void +pgrpnote(ulong noteid, char *a, long n, int flag) +{ + Proc *p, *ep; + char buf[ERRMAX]; + + if(n >= ERRMAX-1) + error(Etoobig); + + memmove(buf, a, n); + buf[n] = 0; + p = proctab(0); + ep = p+conf.nproc; + for(; p < ep; p++) { + if(p->state == Dead) + continue; + if(up != p && p->noteid == noteid && p->kp == 0) { + qlock(&p->debug); + if(p->pid == 0 || p->noteid != noteid){ + qunlock(&p->debug); + continue; + } + if(!waserror()) { + postnote(p, 0, buf, flag); + poperror(); + } + qunlock(&p->debug); + } + } +} +#endif + +Pgrp* +newpgrp(void) +{ + Pgrp *p; + + p = smalloc(sizeof(Pgrp)); + p->ref.ref = 1; + p->pgrpid = incref(&pgrpid); + return p; +} + +Rgrp* +newrgrp(void) +{ + Rgrp *r; + + r = smalloc(sizeof(Rgrp)); + r->ref.ref = 1; + return r; +} + +void +closergrp(Rgrp *r) +{ + if(decref(&r->ref) == 0) + free(r); +} + +void +closepgrp(Pgrp *p) +{ + Mhead **h, **e, *f, *next; + + if(decref(&p->ref) != 0) + return; + + qlock(&p->debug); + wlock(&p->ns); + p->pgrpid = -1; + + e = &p->mnthash[MNTHASH]; + for(h = p->mnthash; h < e; h++) { + for(f = *h; f; f = next) { + wlock(&f->lock); + cclose(f->from); + mountfree(f->mount); + f->mount = nil; + next = f->hash; + wunlock(&f->lock); + putmhead(f); + } + } + wunlock(&p->ns); + qunlock(&p->debug); + free(p); +} + +void +pgrpinsert(Mount **order, Mount *m) +{ + Mount *f; + + m->order = 0; + if(*order == 0) { + *order = m; + return; + } + for(f = *order; f; f = f->order) { + if(m->mountid < f->mountid) { + m->order = f; + *order = m; + return; + } + order = &f->order; + } + *order = m; +} + +/* + * pgrpcpy MUST preserve the mountid allocation order of the parent group + */ +void +pgrpcpy(Pgrp *to, Pgrp *from) +{ + int i; + Mount *n, *m, **link, *order; + Mhead *f, **tom, **l, *mh; + + wlock(&from->ns); + order = 0; + tom = to->mnthash; + for(i = 0; i < MNTHASH; i++) { + l = tom++; + for(f = from->mnthash[i]; f; f = f->hash) { + rlock(&f->lock); + mh = newmhead(f->from); + *l = mh; + l = &mh->hash; + link = &mh->mount; + for(m = f->mount; m; m = m->next) { + n = newmount(mh, m->to, m->mflag, m->spec); + m->copy = n; + pgrpinsert(&order, m); + *link = n; + link = &n->next; + } + runlock(&f->lock); + } + } + /* + * Allocate mount ids in the same sequence as the parent group + */ + lock(&mountid.lk); + for(m = order; m; m = m->order) + m->copy->mountid = mountid.ref++; + unlock(&mountid.lk); + wunlock(&from->ns); +} + +Fgrp* +dupfgrp(Fgrp *f) +{ + Fgrp *new; + Chan *c; + int i; + + new = smalloc(sizeof(Fgrp)); + if(f == nil){ + new->fd = smalloc(DELTAFD*sizeof(Chan*)); + new->nfd = DELTAFD; + new->ref.ref = 1; + return new; + } + + lock(&f->ref.lk); + /* Make new fd list shorter if possible, preserving quantization */ + new->nfd = f->maxfd+1; + i = new->nfd%DELTAFD; + if(i != 0) + new->nfd += DELTAFD - i; + new->fd = malloc(new->nfd*sizeof(Chan*)); + if(new->fd == 0){ + unlock(&f->ref.lk); + error("no memory for fgrp"); + } + new->ref.ref = 1; + + new->maxfd = f->maxfd; + for(i = 0; i <= f->maxfd; i++) { + if((c = f->fd[i])){ + incref(&c->ref); + new->fd[i] = c; + } + } + unlock(&f->ref.lk); + + return new; +} + +void +closefgrp(Fgrp *f) +{ + int i; + Chan *c; + + if(f == 0) + return; + + if(decref(&f->ref) != 0) + return; + + for(i = 0; i <= f->maxfd; i++) + if((c = f->fd[i])) + cclose(c); + + free(f->fd); + free(f); +} + +Mount* +newmount(Mhead *mh, Chan *to, int flag, char *spec) +{ + Mount *m; + + m = smalloc(sizeof(Mount)); + m->to = to; + m->head = mh; + incref(&to->ref); + m->mountid = incref(&mountid); + m->mflag = flag; + if(spec != 0) + kstrdup(&m->spec, spec); + + return m; +} + +void +mountfree(Mount *m) +{ + Mount *f; + + while(m) { + f = m->next; + cclose(m->to); + m->mountid = 0; + free(m->spec); + free(m); + m = f; + } +} + +#ifdef NOTDEF +void +resrcwait(char *reason) +{ + char *p; + + if(up == 0) + panic("resrcwait"); + + p = up->psstate; + if(reason) { + up->psstate = reason; + print("%s\n", reason); + } + + tsleep(&up->sleep, return0, 0, 300); + up->psstate = p; +} +#endif |