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