xref: /plan9/sys/src/cmd/unix/drawterm/kern/pgrp.c (revision 8ccd4a6360d974db7bd7bbd4f37e7018419ea908)
1*8ccd4a63SDavid du Colombier #include	"u.h"
2*8ccd4a63SDavid du Colombier #include	"lib.h"
3*8ccd4a63SDavid du Colombier #include	"dat.h"
4*8ccd4a63SDavid du Colombier #include	"fns.h"
5*8ccd4a63SDavid du Colombier #include	"error.h"
6*8ccd4a63SDavid du Colombier 
7*8ccd4a63SDavid du Colombier static Ref pgrpid;
8*8ccd4a63SDavid du Colombier static Ref mountid;
9*8ccd4a63SDavid du Colombier 
10*8ccd4a63SDavid du Colombier #ifdef NOTDEF
11*8ccd4a63SDavid du Colombier void
pgrpnote(ulong noteid,char * a,long n,int flag)12*8ccd4a63SDavid du Colombier pgrpnote(ulong noteid, char *a, long n, int flag)
13*8ccd4a63SDavid du Colombier {
14*8ccd4a63SDavid du Colombier 	Proc *p, *ep;
15*8ccd4a63SDavid du Colombier 	char buf[ERRMAX];
16*8ccd4a63SDavid du Colombier 
17*8ccd4a63SDavid du Colombier 	if(n >= ERRMAX-1)
18*8ccd4a63SDavid du Colombier 		error(Etoobig);
19*8ccd4a63SDavid du Colombier 
20*8ccd4a63SDavid du Colombier 	memmove(buf, a, n);
21*8ccd4a63SDavid du Colombier 	buf[n] = 0;
22*8ccd4a63SDavid du Colombier 	p = proctab(0);
23*8ccd4a63SDavid du Colombier 	ep = p+conf.nproc;
24*8ccd4a63SDavid du Colombier 	for(; p < ep; p++) {
25*8ccd4a63SDavid du Colombier 		if(p->state == Dead)
26*8ccd4a63SDavid du Colombier 			continue;
27*8ccd4a63SDavid du Colombier 		if(up != p && p->noteid == noteid && p->kp == 0) {
28*8ccd4a63SDavid du Colombier 			qlock(&p->debug);
29*8ccd4a63SDavid du Colombier 			if(p->pid == 0 || p->noteid != noteid){
30*8ccd4a63SDavid du Colombier 				qunlock(&p->debug);
31*8ccd4a63SDavid du Colombier 				continue;
32*8ccd4a63SDavid du Colombier 			}
33*8ccd4a63SDavid du Colombier 			if(!waserror()) {
34*8ccd4a63SDavid du Colombier 				postnote(p, 0, buf, flag);
35*8ccd4a63SDavid du Colombier 				poperror();
36*8ccd4a63SDavid du Colombier 			}
37*8ccd4a63SDavid du Colombier 			qunlock(&p->debug);
38*8ccd4a63SDavid du Colombier 		}
39*8ccd4a63SDavid du Colombier 	}
40*8ccd4a63SDavid du Colombier }
41*8ccd4a63SDavid du Colombier #endif
42*8ccd4a63SDavid du Colombier 
43*8ccd4a63SDavid du Colombier Pgrp*
newpgrp(void)44*8ccd4a63SDavid du Colombier newpgrp(void)
45*8ccd4a63SDavid du Colombier {
46*8ccd4a63SDavid du Colombier 	Pgrp *p;
47*8ccd4a63SDavid du Colombier 
48*8ccd4a63SDavid du Colombier 	p = smalloc(sizeof(Pgrp));
49*8ccd4a63SDavid du Colombier 	p->ref.ref = 1;
50*8ccd4a63SDavid du Colombier 	p->pgrpid = incref(&pgrpid);
51*8ccd4a63SDavid du Colombier 	return p;
52*8ccd4a63SDavid du Colombier }
53*8ccd4a63SDavid du Colombier 
54*8ccd4a63SDavid du Colombier Rgrp*
newrgrp(void)55*8ccd4a63SDavid du Colombier newrgrp(void)
56*8ccd4a63SDavid du Colombier {
57*8ccd4a63SDavid du Colombier 	Rgrp *r;
58*8ccd4a63SDavid du Colombier 
59*8ccd4a63SDavid du Colombier 	r = smalloc(sizeof(Rgrp));
60*8ccd4a63SDavid du Colombier 	r->ref.ref = 1;
61*8ccd4a63SDavid du Colombier 	return r;
62*8ccd4a63SDavid du Colombier }
63*8ccd4a63SDavid du Colombier 
64*8ccd4a63SDavid du Colombier void
closergrp(Rgrp * r)65*8ccd4a63SDavid du Colombier closergrp(Rgrp *r)
66*8ccd4a63SDavid du Colombier {
67*8ccd4a63SDavid du Colombier 	if(decref(&r->ref) == 0)
68*8ccd4a63SDavid du Colombier 		free(r);
69*8ccd4a63SDavid du Colombier }
70*8ccd4a63SDavid du Colombier 
71*8ccd4a63SDavid du Colombier void
closepgrp(Pgrp * p)72*8ccd4a63SDavid du Colombier closepgrp(Pgrp *p)
73*8ccd4a63SDavid du Colombier {
74*8ccd4a63SDavid du Colombier 	Mhead **h, **e, *f, *next;
75*8ccd4a63SDavid du Colombier 
76*8ccd4a63SDavid du Colombier 	if(decref(&p->ref) != 0)
77*8ccd4a63SDavid du Colombier 		return;
78*8ccd4a63SDavid du Colombier 
79*8ccd4a63SDavid du Colombier 	qlock(&p->debug);
80*8ccd4a63SDavid du Colombier 	wlock(&p->ns);
81*8ccd4a63SDavid du Colombier 	p->pgrpid = -1;
82*8ccd4a63SDavid du Colombier 
83*8ccd4a63SDavid du Colombier 	e = &p->mnthash[MNTHASH];
84*8ccd4a63SDavid du Colombier 	for(h = p->mnthash; h < e; h++) {
85*8ccd4a63SDavid du Colombier 		for(f = *h; f; f = next) {
86*8ccd4a63SDavid du Colombier 			wlock(&f->lock);
87*8ccd4a63SDavid du Colombier 			cclose(f->from);
88*8ccd4a63SDavid du Colombier 			mountfree(f->mount);
89*8ccd4a63SDavid du Colombier 			f->mount = nil;
90*8ccd4a63SDavid du Colombier 			next = f->hash;
91*8ccd4a63SDavid du Colombier 			wunlock(&f->lock);
92*8ccd4a63SDavid du Colombier 			putmhead(f);
93*8ccd4a63SDavid du Colombier 		}
94*8ccd4a63SDavid du Colombier 	}
95*8ccd4a63SDavid du Colombier 	wunlock(&p->ns);
96*8ccd4a63SDavid du Colombier 	qunlock(&p->debug);
97*8ccd4a63SDavid du Colombier 	free(p);
98*8ccd4a63SDavid du Colombier }
99*8ccd4a63SDavid du Colombier 
100*8ccd4a63SDavid du Colombier void
pgrpinsert(Mount ** order,Mount * m)101*8ccd4a63SDavid du Colombier pgrpinsert(Mount **order, Mount *m)
102*8ccd4a63SDavid du Colombier {
103*8ccd4a63SDavid du Colombier 	Mount *f;
104*8ccd4a63SDavid du Colombier 
105*8ccd4a63SDavid du Colombier 	m->order = 0;
106*8ccd4a63SDavid du Colombier 	if(*order == 0) {
107*8ccd4a63SDavid du Colombier 		*order = m;
108*8ccd4a63SDavid du Colombier 		return;
109*8ccd4a63SDavid du Colombier 	}
110*8ccd4a63SDavid du Colombier 	for(f = *order; f; f = f->order) {
111*8ccd4a63SDavid du Colombier 		if(m->mountid < f->mountid) {
112*8ccd4a63SDavid du Colombier 			m->order = f;
113*8ccd4a63SDavid du Colombier 			*order = m;
114*8ccd4a63SDavid du Colombier 			return;
115*8ccd4a63SDavid du Colombier 		}
116*8ccd4a63SDavid du Colombier 		order = &f->order;
117*8ccd4a63SDavid du Colombier 	}
118*8ccd4a63SDavid du Colombier 	*order = m;
119*8ccd4a63SDavid du Colombier }
120*8ccd4a63SDavid du Colombier 
121*8ccd4a63SDavid du Colombier /*
122*8ccd4a63SDavid du Colombier  * pgrpcpy MUST preserve the mountid allocation order of the parent group
123*8ccd4a63SDavid du Colombier  */
124*8ccd4a63SDavid du Colombier void
pgrpcpy(Pgrp * to,Pgrp * from)125*8ccd4a63SDavid du Colombier pgrpcpy(Pgrp *to, Pgrp *from)
126*8ccd4a63SDavid du Colombier {
127*8ccd4a63SDavid du Colombier 	int i;
128*8ccd4a63SDavid du Colombier 	Mount *n, *m, **link, *order;
129*8ccd4a63SDavid du Colombier 	Mhead *f, **tom, **l, *mh;
130*8ccd4a63SDavid du Colombier 
131*8ccd4a63SDavid du Colombier 	wlock(&from->ns);
132*8ccd4a63SDavid du Colombier 	order = 0;
133*8ccd4a63SDavid du Colombier 	tom = to->mnthash;
134*8ccd4a63SDavid du Colombier 	for(i = 0; i < MNTHASH; i++) {
135*8ccd4a63SDavid du Colombier 		l = tom++;
136*8ccd4a63SDavid du Colombier 		for(f = from->mnthash[i]; f; f = f->hash) {
137*8ccd4a63SDavid du Colombier 			rlock(&f->lock);
138*8ccd4a63SDavid du Colombier 			mh = newmhead(f->from);
139*8ccd4a63SDavid du Colombier 			*l = mh;
140*8ccd4a63SDavid du Colombier 			l = &mh->hash;
141*8ccd4a63SDavid du Colombier 			link = &mh->mount;
142*8ccd4a63SDavid du Colombier 			for(m = f->mount; m; m = m->next) {
143*8ccd4a63SDavid du Colombier 				n = newmount(mh, m->to, m->mflag, m->spec);
144*8ccd4a63SDavid du Colombier 				m->copy = n;
145*8ccd4a63SDavid du Colombier 				pgrpinsert(&order, m);
146*8ccd4a63SDavid du Colombier 				*link = n;
147*8ccd4a63SDavid du Colombier 				link = &n->next;
148*8ccd4a63SDavid du Colombier 			}
149*8ccd4a63SDavid du Colombier 			runlock(&f->lock);
150*8ccd4a63SDavid du Colombier 		}
151*8ccd4a63SDavid du Colombier 	}
152*8ccd4a63SDavid du Colombier 	/*
153*8ccd4a63SDavid du Colombier 	 * Allocate mount ids in the same sequence as the parent group
154*8ccd4a63SDavid du Colombier 	 */
155*8ccd4a63SDavid du Colombier 	lock(&mountid.lk);
156*8ccd4a63SDavid du Colombier 	for(m = order; m; m = m->order)
157*8ccd4a63SDavid du Colombier 		m->copy->mountid = mountid.ref++;
158*8ccd4a63SDavid du Colombier 	unlock(&mountid.lk);
159*8ccd4a63SDavid du Colombier 	wunlock(&from->ns);
160*8ccd4a63SDavid du Colombier }
161*8ccd4a63SDavid du Colombier 
162*8ccd4a63SDavid du Colombier Fgrp*
dupfgrp(Fgrp * f)163*8ccd4a63SDavid du Colombier dupfgrp(Fgrp *f)
164*8ccd4a63SDavid du Colombier {
165*8ccd4a63SDavid du Colombier 	Fgrp *new;
166*8ccd4a63SDavid du Colombier 	Chan *c;
167*8ccd4a63SDavid du Colombier 	int i;
168*8ccd4a63SDavid du Colombier 
169*8ccd4a63SDavid du Colombier 	new = smalloc(sizeof(Fgrp));
170*8ccd4a63SDavid du Colombier 	if(f == nil){
171*8ccd4a63SDavid du Colombier 		new->fd = smalloc(DELTAFD*sizeof(Chan*));
172*8ccd4a63SDavid du Colombier 		new->nfd = DELTAFD;
173*8ccd4a63SDavid du Colombier 		new->ref.ref = 1;
174*8ccd4a63SDavid du Colombier 		return new;
175*8ccd4a63SDavid du Colombier 	}
176*8ccd4a63SDavid du Colombier 
177*8ccd4a63SDavid du Colombier 	lock(&f->ref.lk);
178*8ccd4a63SDavid du Colombier 	/* Make new fd list shorter if possible, preserving quantization */
179*8ccd4a63SDavid du Colombier 	new->nfd = f->maxfd+1;
180*8ccd4a63SDavid du Colombier 	i = new->nfd%DELTAFD;
181*8ccd4a63SDavid du Colombier 	if(i != 0)
182*8ccd4a63SDavid du Colombier 		new->nfd += DELTAFD - i;
183*8ccd4a63SDavid du Colombier 	new->fd = malloc(new->nfd*sizeof(Chan*));
184*8ccd4a63SDavid du Colombier 	if(new->fd == 0){
185*8ccd4a63SDavid du Colombier 		unlock(&f->ref.lk);
186*8ccd4a63SDavid du Colombier 		error("no memory for fgrp");
187*8ccd4a63SDavid du Colombier 	}
188*8ccd4a63SDavid du Colombier 	new->ref.ref = 1;
189*8ccd4a63SDavid du Colombier 
190*8ccd4a63SDavid du Colombier 	new->maxfd = f->maxfd;
191*8ccd4a63SDavid du Colombier 	for(i = 0; i <= f->maxfd; i++) {
192*8ccd4a63SDavid du Colombier 		if((c = f->fd[i])){
193*8ccd4a63SDavid du Colombier 			incref(&c->ref);
194*8ccd4a63SDavid du Colombier 			new->fd[i] = c;
195*8ccd4a63SDavid du Colombier 		}
196*8ccd4a63SDavid du Colombier 	}
197*8ccd4a63SDavid du Colombier 	unlock(&f->ref.lk);
198*8ccd4a63SDavid du Colombier 
199*8ccd4a63SDavid du Colombier 	return new;
200*8ccd4a63SDavid du Colombier }
201*8ccd4a63SDavid du Colombier 
202*8ccd4a63SDavid du Colombier void
closefgrp(Fgrp * f)203*8ccd4a63SDavid du Colombier closefgrp(Fgrp *f)
204*8ccd4a63SDavid du Colombier {
205*8ccd4a63SDavid du Colombier 	int i;
206*8ccd4a63SDavid du Colombier 	Chan *c;
207*8ccd4a63SDavid du Colombier 
208*8ccd4a63SDavid du Colombier 	if(f == 0)
209*8ccd4a63SDavid du Colombier 		return;
210*8ccd4a63SDavid du Colombier 
211*8ccd4a63SDavid du Colombier 	if(decref(&f->ref) != 0)
212*8ccd4a63SDavid du Colombier 		return;
213*8ccd4a63SDavid du Colombier 
214*8ccd4a63SDavid du Colombier 	for(i = 0; i <= f->maxfd; i++)
215*8ccd4a63SDavid du Colombier 		if((c = f->fd[i]))
216*8ccd4a63SDavid du Colombier 			cclose(c);
217*8ccd4a63SDavid du Colombier 
218*8ccd4a63SDavid du Colombier 	free(f->fd);
219*8ccd4a63SDavid du Colombier 	free(f);
220*8ccd4a63SDavid du Colombier }
221*8ccd4a63SDavid du Colombier 
222*8ccd4a63SDavid du Colombier Mount*
newmount(Mhead * mh,Chan * to,int flag,char * spec)223*8ccd4a63SDavid du Colombier newmount(Mhead *mh, Chan *to, int flag, char *spec)
224*8ccd4a63SDavid du Colombier {
225*8ccd4a63SDavid du Colombier 	Mount *m;
226*8ccd4a63SDavid du Colombier 
227*8ccd4a63SDavid du Colombier 	m = smalloc(sizeof(Mount));
228*8ccd4a63SDavid du Colombier 	m->to = to;
229*8ccd4a63SDavid du Colombier 	m->head = mh;
230*8ccd4a63SDavid du Colombier 	incref(&to->ref);
231*8ccd4a63SDavid du Colombier 	m->mountid = incref(&mountid);
232*8ccd4a63SDavid du Colombier 	m->mflag = flag;
233*8ccd4a63SDavid du Colombier 	if(spec != 0)
234*8ccd4a63SDavid du Colombier 		kstrdup(&m->spec, spec);
235*8ccd4a63SDavid du Colombier 
236*8ccd4a63SDavid du Colombier 	return m;
237*8ccd4a63SDavid du Colombier }
238*8ccd4a63SDavid du Colombier 
239*8ccd4a63SDavid du Colombier void
mountfree(Mount * m)240*8ccd4a63SDavid du Colombier mountfree(Mount *m)
241*8ccd4a63SDavid du Colombier {
242*8ccd4a63SDavid du Colombier 	Mount *f;
243*8ccd4a63SDavid du Colombier 
244*8ccd4a63SDavid du Colombier 	while(m) {
245*8ccd4a63SDavid du Colombier 		f = m->next;
246*8ccd4a63SDavid du Colombier 		cclose(m->to);
247*8ccd4a63SDavid du Colombier 		m->mountid = 0;
248*8ccd4a63SDavid du Colombier 		free(m->spec);
249*8ccd4a63SDavid du Colombier 		free(m);
250*8ccd4a63SDavid du Colombier 		m = f;
251*8ccd4a63SDavid du Colombier 	}
252*8ccd4a63SDavid du Colombier }
253*8ccd4a63SDavid du Colombier 
254*8ccd4a63SDavid du Colombier #ifdef NOTDEF
255*8ccd4a63SDavid du Colombier void
resrcwait(char * reason)256*8ccd4a63SDavid du Colombier resrcwait(char *reason)
257*8ccd4a63SDavid du Colombier {
258*8ccd4a63SDavid du Colombier 	char *p;
259*8ccd4a63SDavid du Colombier 
260*8ccd4a63SDavid du Colombier 	if(up == 0)
261*8ccd4a63SDavid du Colombier 		panic("resrcwait");
262*8ccd4a63SDavid du Colombier 
263*8ccd4a63SDavid du Colombier 	p = up->psstate;
264*8ccd4a63SDavid du Colombier 	if(reason) {
265*8ccd4a63SDavid du Colombier 		up->psstate = reason;
266*8ccd4a63SDavid du Colombier 		print("%s\n", reason);
267*8ccd4a63SDavid du Colombier 	}
268*8ccd4a63SDavid du Colombier 
269*8ccd4a63SDavid du Colombier 	tsleep(&up->sleep, return0, 0, 300);
270*8ccd4a63SDavid du Colombier 	up->psstate = p;
271*8ccd4a63SDavid du Colombier }
272*8ccd4a63SDavid du Colombier #endif
273