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