summaryrefslogtreecommitdiff
path: root/sys/src/cmd/unix/drawterm/kern/pgrp.c
diff options
context:
space:
mode:
authorTaru Karttunen <taruti@taruti.net>2011-03-30 15:46:40 +0300
committerTaru Karttunen <taruti@taruti.net>2011-03-30 15:46:40 +0300
commite5888a1ffdae813d7575f5fb02275c6bb07e5199 (patch)
treed8d51eac403f07814b9e936eed0c9a79195e2450 /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-xsys/src/cmd/unix/drawterm/kern/pgrp.c272
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