Warning: Attempt to read property "date" on null in /usr/local/www/websvn.planix.org/blame.php on line 247

Warning: Attempt to read property "msg" on null in /usr/local/www/websvn.planix.org/blame.php on line 247
WebSVN – planix.SVN – Blame – /os/branches/feature_posix/sys/src/9/port/chan.c – Rev 2

Subversion Repositories planix.SVN

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 - 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
int chandebug=0;		/* toggled by sysr1 */
9
#define DBG if(chandebug)iprint
10
 
11
enum
12
{
13
	PATHSLOP	= 20,
14
	PATHMSLOP	= 20,
15
};
16
 
17
struct
18
{
19
	Lock;
20
	int	fid;
21
	Chan	*free;
22
	Chan	*list;
23
}chanalloc;
24
 
25
typedef struct Elemlist Elemlist;
26
 
27
struct Elemlist
28
{
29
	char	*aname;	/* original name */
30
	char	*name;	/* copy of name, so '/' can be overwritten */
31
	int	nelems;
32
	char	**elems;
33
	int	*off;
34
	int	mustbedir;
35
	int	nerror;
36
	int	prefix;
37
};
38
 
39
#define SEP(c) ((c) == 0 || (c) == '/')
40
 
41
static void
42
dumpmount(void)		/* DEBUGGING */
43
{
44
	Pgrp *pg;
45
	Mount *t;
46
	Mhead **h, **he, *f;
47
 
48
	if(up == nil){
49
		print("no process for dumpmount\n");
50
		return;
51
	}
52
	pg = up->pgrp;
53
	if(pg == nil){
54
		print("no pgrp for dumpmount\n");
55
		return;
56
	}
57
	rlock(&pg->ns);
58
	if(waserror()){
59
		runlock(&pg->ns);
60
		nexterror();
61
	}
62
 
63
	he = &pg->mnthash[MNTHASH];
64
	for(h = pg->mnthash; h < he; h++){
65
		for(f = *h; f; f = f->hash){
66
			print("head: %#p: %s %#llux.%lud %C %lud -> \n", f,
67
				f->from->path->s, f->from->qid.path,
68
				f->from->qid.vers, devtab[f->from->type]->dc,
69
				f->from->dev);
70
			for(t = f->mount; t; t = t->next)
71
				print("\t%#p: %s (umh %#p) (path %#.8llux dev %C %lud)\n", t, t->to->path->s, t->to->umh, t->to->qid.path, devtab[t->to->type]->dc, t->to->dev);
72
		}
73
	}
74
	poperror();
75
	runlock(&pg->ns);
76
}
77
 
78
char*
79
chanpath(Chan *c)
80
{
81
	if(c == nil)
82
		return "<nil chan>";
83
	if(c->path == nil)
84
		return "<nil path>";
85
	if(c->path->s == nil)
86
		return "<nil path.s>";
87
	return c->path->s;
88
}
89
 
90
int
91
isdotdot(char *p)
92
{
93
	return p[0]=='.' && p[1]=='.' && p[2]=='\0';
94
}
95
 
96
long
97
incref(Ref *r)
98
{
99
	long x;
100
 
101
	lock(r);
102
	x = ++r->ref;
103
	unlock(r);
104
	return x;
105
}
106
 
107
long
108
decref(Ref *r)
109
{
110
	long x;
111
 
112
	lock(r);
113
	x = --r->ref;
114
	unlock(r);
115
	if(x < 0)
116
		panic("decref pc=%#p", getcallerpc(&r));
117
 
118
	return x;
119
}
120
 
121
/*
122
 * Rather than strncpy, which zeros the rest of the buffer, kstrcpy
123
 * truncates if necessary, always zero terminates, does not zero fill,
124
 * and puts ... at the end of the string if it's too long.  Usually used to
125
 * save a string in up->genbuf;
126
 */
127
void
128
kstrcpy(char *s, char *t, int ns)
129
{
130
	int nt;
131
 
132
	nt = strlen(t);
133
	if(nt+1 <= ns){
134
		memmove(s, t, nt+1);
135
		return;
136
	}
137
	/* too long */
138
	if(ns < 4){
139
		/* but very short! */
140
		strncpy(s, t, ns);
141
		return;
142
	}
143
	/* truncate with ... at character boundary (very rare case) */
144
	memmove(s, t, ns-4);
145
	ns -= 4;
146
	s[ns] = '\0';
147
	/* look for first byte of UTF-8 sequence by skipping continuation bytes */
148
	while(ns>0 && (s[--ns]&0xC0)==0x80)
149
		;
150
	strcpy(s+ns, "...");
151
}
152
 
153
int
154
emptystr(char *s)
155
{
156
	if(s == nil)
157
		return 1;
158
	if(s[0] == '\0')
159
		return 1;
160
	return 0;
161
}
162
 
163
/*
164
 * Atomically replace *p with copy of s
165
 */
166
void
167
kstrdup(char **p, char *s)
168
{
169
	int n;
170
	char *t, *prev;
171
 
172
	n = strlen(s)+1;
173
	/* if it's a user, we can wait for memory; if not, something's very wrong */
174
	if(up){
175
		t = smalloc(n);
176
		setmalloctag(t, getcallerpc(&p));
177
	}else{
178
		t = malloc(n);
179
		if(t == nil)
180
			panic("kstrdup: no memory");
181
	}
182
	memmove(t, s, n);
183
	prev = *p;
184
	*p = t;
185
	free(prev);
186
}
187
 
188
static int debugstart = 1;
189
 
190
void
191
chandevreset(void)
192
{
193
	int i;
194
 
195
	todinit();	/* avoid later reentry causing infinite recursion */
196
	debugstart = getconf("*debugstart") != nil;
197
	if(debugstart)
198
		iprint("reset:");
199
	for(i=0; devtab[i] != nil; i++) {
200
		if(debugstart)
201
			iprint(" %s", devtab[i]->name);
202
		devtab[i]->reset();
203
	}
204
	if(debugstart)
205
		iprint("\n");
206
}
207
 
208
void
209
chandevinit(void)
210
{
211
	int i;
212
 
213
	if(debugstart)
214
		iprint("init:");
215
	for(i=0; devtab[i] != nil; i++) {
216
		if(debugstart)
217
			iprint(" %s", devtab[i]->name);
218
		devtab[i]->init();
219
	}
220
	if(debugstart)
221
		iprint("\n");
222
}
223
 
224
void
225
chandevshutdown(void)
226
{
227
	int i;
228
 
229
	/* shutdown in reverse order */
230
	for(i=0; devtab[i] != nil; i++)
231
		;
232
	for(i--; i >= 0; i--)
233
		devtab[i]->shutdown();
234
}
235
 
236
Chan*
237
newchan(void)
238
{
239
	Chan *c;
240
 
241
	lock(&chanalloc);
242
	c = chanalloc.free;
243
	if(c != 0)
244
		chanalloc.free = c->next;
245
	unlock(&chanalloc);
246
 
247
	if(c == nil){
248
		c = smalloc(sizeof(Chan));
249
		lock(&chanalloc);
250
		c->fid = ++chanalloc.fid;
251
		c->link = chanalloc.list;
252
		chanalloc.list = c;
253
		unlock(&chanalloc);
254
	}
255
 
256
	/* if you get an error before associating with a dev,
257
	   close calls rootclose, a nop */
258
	c->type = 0;
259
	c->flag = 0;
260
	c->ref = 1;
261
	c->dev = 0;
262
	c->offset = 0;
263
	c->devoffset = 0;
264
	c->iounit = 0;
265
	c->umh = 0;
266
	c->uri = 0;
267
	c->dri = 0;
268
	c->aux = 0;
269
	c->mchan = 0;
270
	c->mcp = 0;
271
	c->mux = 0;
272
	memset(&c->mqid, 0, sizeof(c->mqid));
273
	c->path = 0;
274
	c->ismtpt = 0;
275
 
276
	return c;
277
}
278
 
279
Ref npath;
280
 
281
Path*
282
newpath(char *s)
283
{
284
	int i;
285
	Path *p;
286
 
287
	p = smalloc(sizeof(Path));
288
	i = strlen(s);
289
	p->len = i;
290
	p->alen = i+PATHSLOP;
291
	p->s = smalloc(p->alen);
292
	memmove(p->s, s, i+1);
293
	p->ref = 1;
294
	incref(&npath);
295
 
296
	/*
297
	 * Cannot use newpath for arbitrary names because the mtpt 
298
	 * array will not be populated correctly.  The names #/ and / are
299
	 * allowed, but other names with / in them draw warnings.
300
	 */
301
	if(strchr(s, '/') && strcmp(s, "#/") != 0 && strcmp(s, "/") != 0)
302
		print("newpath: %s from %#p\n", s, getcallerpc(&s));
303
 
304
	p->mlen = 1;
305
	p->malen = PATHMSLOP;
306
	p->mtpt = smalloc(p->malen*sizeof p->mtpt[0]);
307
	return p;
308
}
309
 
310
static Path*
311
copypath(Path *p)
312
{
313
	int i;
314
	Path *pp;
315
 
316
	pp = smalloc(sizeof(Path));
317
	pp->ref = 1;
318
	incref(&npath);
319
	DBG("copypath %s %p => %p\n", p->s, p, pp);
320
 
321
	pp->len = p->len;
322
	pp->alen = p->alen;
323
	pp->s = smalloc(p->alen);
324
	memmove(pp->s, p->s, p->len+1);
325
 
326
	pp->mlen = p->mlen;
327
	pp->malen = p->malen;
328
	pp->mtpt = smalloc(p->malen*sizeof pp->mtpt[0]);
329
	for(i=0; i<pp->mlen; i++){
330
		pp->mtpt[i] = p->mtpt[i];
331
		if(pp->mtpt[i])
332
			incref(pp->mtpt[i]);
333
	}
334
 
335
	return pp;
336
}
337
 
338
void
339
pathclose(Path *p)
340
{
341
	int i;
342
 
343
	if(p == nil)
344
		return;
345
//XXX
346
	DBG("pathclose %p %s ref=%ld =>", p, p->s, p->ref);
347
	for(i=0; i<p->mlen; i++)
348
		DBG(" %p", p->mtpt[i]);
349
	DBG("\n");
350
 
351
	if(decref(p))
352
		return;
353
	decref(&npath);
354
	free(p->s);
355
	for(i=0; i<p->mlen; i++)
356
		if(p->mtpt[i])
357
			cclose(p->mtpt[i]);
358
	free(p->mtpt);
359
	free(p);
360
}
361
 
362
/*
363
 * In place, rewrite name to compress multiple /, eliminate ., and process ..
364
 * (Really only called to remove a trailing .. that has been added.
365
 * Otherwise would need to update n->mtpt as well.)
366
 */
367
static void
368
fixdotdotname(Path *p)
369
{
370
	char *r;
371
 
372
	if(p->s[0] == '#'){
373
		r = strchr(p->s, '/');
374
		if(r == nil)
375
			return;
376
		cleanname(r);
377
 
378
		/*
379
		 * The correct name is #i rather than #i/,
380
		 * but the correct name of #/ is #/.
381
		 */
382
		if(strcmp(r, "/")==0 && p->s[1] != '/')
383
			*r = '\0';
384
	}else
385
		cleanname(p->s);
386
	p->len = strlen(p->s);
387
}
388
 
389
static Path*
390
uniquepath(Path *p)
391
{
392
	Path *new;
393
 
394
	if(p->ref > 1){
395
		/* copy on write */
396
		new = copypath(p);
397
		pathclose(p);
398
		p = new;
399
	}
400
	return p;
401
}
402
 
403
static Path*
404
addelem(Path *p, char *s, Chan *from)
405
{
406
	char *t;
407
	int a, i;
408
	Chan *c, **tt;
409
 
410
	if(s[0]=='.' && s[1]=='\0')
411
		return p;
412
 
413
	p = uniquepath(p);
414
 
415
	i = strlen(s);
416
	if(p->len+1+i+1 > p->alen){
417
		a = p->len+1+i+1 + PATHSLOP;
418
		t = smalloc(a);
419
		memmove(t, p->s, p->len+1);
420
		free(p->s);
421
		p->s = t;
422
		p->alen = a;
423
	}
424
	/* don't insert extra slash if one is present */
425
	if(p->len>0 && p->s[p->len-1]!='/' && s[0]!='/')
426
		p->s[p->len++] = '/';
427
	memmove(p->s+p->len, s, i+1);
428
	p->len += i;
429
	if(isdotdot(s)){
430
		fixdotdotname(p);
431
		DBG("addelem %s .. => rm %p\n", p->s, p->mtpt[p->mlen-1]);
432
		if(p->mlen>1 && (c = p->mtpt[--p->mlen])){
433
			p->mtpt[p->mlen] = nil;
434
			cclose(c);
435
		}
436
	}else{
437
		if(p->mlen >= p->malen){
438
			p->malen = p->mlen+1+PATHMSLOP;
439
			tt = smalloc(p->malen*sizeof tt[0]);
440
			memmove(tt, p->mtpt, p->mlen*sizeof tt[0]);
441
			free(p->mtpt);
442
			p->mtpt = tt;
443
		}
444
		DBG("addelem %s %s => add %p\n", p->s, s, from);
445
		p->mtpt[p->mlen++] = from;
446
		if(from)
447
			incref(from);
448
	}
449
	return p;
450
}
451
 
452
void
453
chanfree(Chan *c)
454
{
455
	c->flag = CFREE;
456
 
457
	if(c->dirrock != nil){
458
		free(c->dirrock);
459
		c->dirrock = 0;
460
		c->nrock = 0;
461
		c->mrock = 0;
462
	}
463
	if(c->umh != nil){
464
		putmhead(c->umh);
465
		c->umh = nil;
466
	}
467
	if(c->umc != nil){
468
		cclose(c->umc);
469
		c->umc = nil;
470
	}
471
	if(c->mux != nil){
472
		muxclose(c->mux);
473
		c->mux = nil;
474
	}
475
	if(c->mchan != nil){
476
		cclose(c->mchan);
477
		c->mchan = nil;
478
	}
479
 
480
	pathclose(c->path);
481
	c->path = nil;
482
 
483
	lock(&chanalloc);
484
	c->next = chanalloc.free;
485
	chanalloc.free = c;
486
	unlock(&chanalloc);
487
}
488
 
489
void
490
cclose(Chan *c)
491
{
492
	if(c->flag&CFREE)
493
		panic("cclose %#p", getcallerpc(&c));
494
 
495
	DBG("cclose %p name=%s ref=%ld\n", c, c->path->s, c->ref);
496
	if(decref(c))
497
		return;
498
 
499
	if(!waserror()){
500
		devtab[c->type]->close(c);
501
		poperror();
502
	}
503
	chanfree(c);
504
}
505
 
506
/*
507
 * Queue a chan to be closed by one of the clunk procs.
508
 */
509
struct {
510
	Chan *head;
511
	Chan *tail;
512
	int nqueued;
513
	int nclosed;
514
	Lock l;
515
	QLock q;
516
	Rendez r;
517
} clunkq;
518
void closeproc(void*);
519
 
520
void
521
ccloseq(Chan *c)
522
{
523
	if(c->flag&CFREE)
524
		panic("cclose %#p", getcallerpc(&c));
525
 
526
	DBG("ccloseq %p name=%s ref=%ld\n", c, c->path->s, c->ref);
527
 
528
	if(decref(c))
529
		return;
530
 
531
	lock(&clunkq.l);
532
	clunkq.nqueued++;
533
	c->next = nil;
534
	if(clunkq.head)
535
		clunkq.tail->next = c;
536
	else
537
		clunkq.head = c;
538
	clunkq.tail = c;
539
	unlock(&clunkq.l);
540
 
541
	if(!wakeup(&clunkq.r))
542
		kproc("closeproc", closeproc, nil);	
543
}
544
 
545
static int
546
clunkwork(void*)
547
{
548
	return clunkq.head != nil;
549
}
550
 
551
void
552
closeproc(void*)
553
{
554
	Chan *c;
555
 
556
	for(;;){
557
		qlock(&clunkq.q);
558
		if(clunkq.head == nil){
559
			if(!waserror()){
560
				tsleep(&clunkq.r, clunkwork, nil, 5000);
561
				poperror();
562
			}
563
			if(clunkq.head == nil){
564
				qunlock(&clunkq.q);
565
				pexit("no work", 1);
566
			}
567
		}
568
		lock(&clunkq.l);
569
		c = clunkq.head;
570
		clunkq.head = c->next;
571
		clunkq.nclosed++;
572
		unlock(&clunkq.l);
573
		qunlock(&clunkq.q);
574
		if(!waserror()){
575
			devtab[c->type]->close(c);
576
			poperror();
577
		}
578
		chanfree(c);
579
	}
580
}
581
 
582
/*
583
 * Make sure we have the only copy of c.  (Copy on write.)
584
 */
585
Chan*
586
cunique(Chan *c)
587
{
588
	Chan *nc;
589
 
590
	if(c->ref != 1){
591
		nc = cclone(c);
592
		cclose(c);
593
		c = nc;
594
	}
595
 
596
	return c;
597
}
598
 
599
int
600
eqqid(Qid a, Qid b)
601
{
602
	return a.path==b.path && a.vers==b.vers;
603
}
604
 
605
int
606
eqchan(Chan *a, Chan *b, int skipvers)
607
{
608
	if(a->qid.path != b->qid.path)
609
		return 0;
610
	if(!skipvers && a->qid.vers!=b->qid.vers)
611
		return 0;
612
	if(a->type != b->type)
613
		return 0;
614
	if(a->dev != b->dev)
615
		return 0;
616
	return 1;
617
}
618
 
619
int
620
eqchantdqid(Chan *a, int type, int dev, Qid qid, int skipvers)
621
{
622
	if(a->qid.path != qid.path)
623
		return 0;
624
	if(!skipvers && a->qid.vers!=qid.vers)
625
		return 0;
626
	if(a->type != type)
627
		return 0;
628
	if(a->dev != dev)
629
		return 0;
630
	return 1;
631
}
632
 
633
Mhead*
634
newmhead(Chan *from)
635
{
636
	Mhead *mh;
637
 
638
	mh = smalloc(sizeof(Mhead));
639
	mh->ref = 1;
640
	mh->from = from;
641
	incref(from);
642
	return mh;
643
}
644
 
645
int
646
cmount(Chan **newp, Chan *old, int flag, char *spec)
647
{
648
	int order, flg;
649
	Chan *new;
650
	Mhead *m, **l, *mh;
651
	Mount *nm, *f, *um, **h;
652
	Pgrp *pg;
653
 
654
	if(QTDIR & (old->qid.type^(*newp)->qid.type))
655
		error(Emount);
656
 
657
	if(old->umh)
658
		print("cmount: unexpected umh, caller %#p\n", getcallerpc(&newp));
659
 
660
	order = flag&MORDER;
661
 
662
	if((old->qid.type&QTDIR)==0 && order != MREPL)
663
		error(Emount);
664
 
665
	new = *newp;
666
	mh = new->umh;
667
 
668
	/*
669
	 * Not allowed to bind when the old directory is itself a union. 
670
	 * (Maybe it should be allowed, but I don't see what the semantics
671
	 * would be.)
672
	 *
673
	 * We need to check mh->mount->next to tell unions apart from
674
	 * simple mount points, so that things like
675
	 *	mount -c fd /root
676
	 *	bind -c /root /
677
	 * work.  
678
	 * 
679
	 * The check of mount->mflag allows things like
680
	 *	mount fd /root
681
	 *	bind -c /root /
682
	 * 
683
	 * This is far more complicated than it should be, but I don't
684
	 * see an easier way at the moment.
685
	 */
686
	if((flag&MCREATE) && mh && mh->mount
687
	&& (mh->mount->next || !(mh->mount->mflag&MCREATE)))
688
		error(Emount);
689
 
690
	pg = up->pgrp;
691
	wlock(&pg->ns);
692
 
693
	l = &MOUNTH(pg, old->qid);
694
	for(m = *l; m; m = m->hash){
695
		if(eqchan(m->from, old, 1))
696
			break;
697
		l = &m->hash;
698
	}
699
 
700
	if(m == nil){
701
		/*
702
		 *  nothing mounted here yet.  create a mount
703
		 *  head and add to the hash table.
704
		 */
705
		m = newmhead(old);
706
		*l = m;
707
 
708
		/*
709
		 *  if this is a union mount, add the old
710
		 *  node to the mount chain.
711
		 */
712
		if(order != MREPL)
713
			m->mount = newmount(m, old, 0, 0);
714
	}
715
	wlock(&m->lock);
716
	if(waserror()){
717
		wunlock(&m->lock);
718
		nexterror();
719
	}
720
	wunlock(&pg->ns);
721
 
722
	nm = newmount(m, new, flag, spec);
723
	if(mh != nil && mh->mount != nil){
724
		/*
725
		 *  copy a union when binding it onto a directory
726
		 */
727
		flg = order;
728
		if(order == MREPL)
729
			flg = MAFTER;
730
		h = &nm->next;
731
		um = mh->mount;
732
		for(um = um->next; um; um = um->next){
733
			f = newmount(m, um->to, flg, um->spec);
734
			*h = f;
735
			h = &f->next;
736
		}
737
	}
738
 
739
	if(m->mount && order == MREPL){
740
		mountfree(m->mount);
741
		m->mount = 0;
742
	}
743
 
744
	if(flag & MCREATE)
745
		nm->mflag |= MCREATE;
746
 
747
	if(m->mount && order == MAFTER){
748
		for(f = m->mount; f->next; f = f->next)
749
			;
750
		f->next = nm;
751
	}else{
752
		for(f = nm; f->next; f = f->next)
753
			;
754
		f->next = m->mount;
755
		m->mount = nm;
756
	}
757
 
758
	wunlock(&m->lock);
759
	poperror();
760
	return nm->mountid;
761
}
762
 
763
void
764
cunmount(Chan *mnt, Chan *mounted)
765
{
766
	Pgrp *pg;
767
	Mhead *m, **l;
768
	Mount *f, **p;
769
 
770
	if(mnt->umh)	/* should not happen */
771
		print("cunmount newp extra umh %p has %p\n", mnt, mnt->umh);
772
 
773
	/*
774
	 * It _can_ happen that mounted->umh is non-nil, 
775
	 * because mounted is the result of namec(Aopen)
776
	 * (see sysfile.c:/^sysunmount).
777
	 * If we open a union directory, it will have a umh.
778
	 * Although surprising, this is okay, since the
779
	 * cclose will take care of freeing the umh.
780
	 */
781
 
782
	pg = up->pgrp;
783
	wlock(&pg->ns);
784
 
785
	l = &MOUNTH(pg, mnt->qid);
786
	for(m = *l; m; m = m->hash){
787
		if(eqchan(m->from, mnt, 1))
788
			break;
789
		l = &m->hash;
790
	}
791
 
792
	if(m == 0){
793
		wunlock(&pg->ns);
794
		error(Eunmount);
795
	}
796
 
797
	wlock(&m->lock);
798
	if(mounted == 0){
799
		*l = m->hash;
800
		wunlock(&pg->ns);
801
		mountfree(m->mount);
802
		m->mount = nil;
803
		cclose(m->from);
804
		wunlock(&m->lock);
805
		putmhead(m);
806
		return;
807
	}
808
 
809
	p = &m->mount;
810
	for(f = *p; f; f = f->next){
811
		/* BUG: Needs to be 2 pass */
812
		if(eqchan(f->to, mounted, 1) ||
813
		  (f->to->mchan && eqchan(f->to->mchan, mounted, 1))){
814
			*p = f->next;
815
			f->next = 0;
816
			mountfree(f);
817
			if(m->mount == nil){
818
				*l = m->hash;
819
				cclose(m->from);
820
				wunlock(&m->lock);
821
				wunlock(&pg->ns);
822
				putmhead(m);
823
				return;
824
			}
825
			wunlock(&m->lock);
826
			wunlock(&pg->ns);
827
			return;
828
		}
829
		p = &f->next;
830
	}
831
	wunlock(&m->lock);
832
	wunlock(&pg->ns);
833
	error(Eunion);
834
}
835
 
836
Chan*
837
cclone(Chan *c)
838
{
839
	Chan *nc;
840
	Walkqid *wq;
841
 
842
	wq = devtab[c->type]->walk(c, nil, nil, 0);
843
	if(wq == nil)
844
		error("clone failed");
845
	nc = wq->clone;
846
	free(wq);
847
	nc->path = c->path;
848
	if(c->path)
849
		incref(c->path);
850
	return nc;
851
}
852
 
853
/* also used by sysfile.c:/^mountfix */
854
int
855
findmount(Chan **cp, Mhead **mp, int type, int dev, Qid qid)
856
{
857
	Pgrp *pg;
858
	Mhead *m;
859
 
860
	pg = up->pgrp;
861
	rlock(&pg->ns);
862
	for(m = MOUNTH(pg, qid); m; m = m->hash){
863
		rlock(&m->lock);
864
		if(m->from == nil){
865
			print("m %p m->from 0\n", m);
866
			runlock(&m->lock);
867
			continue;
868
		}
869
		if(eqchantdqid(m->from, type, dev, qid, 1)){
870
			runlock(&pg->ns);
871
			if(mp != nil){
872
				incref(m);
873
				if(*mp != nil)
874
					putmhead(*mp);
875
				*mp = m;
876
			}
877
			if(*cp != nil)
878
				cclose(*cp);
879
			incref(m->mount->to);
880
			*cp = m->mount->to;
881
			runlock(&m->lock);
882
			return 1;
883
		}
884
		runlock(&m->lock);
885
	}
886
 
887
	runlock(&pg->ns);
888
	return 0;
889
}
890
 
891
/*
892
 * Calls findmount but also updates path.
893
 */
894
static int
895
domount(Chan **cp, Mhead **mp, Path **path)
896
{
897
	Chan **lc;
898
	Path *p;
899
 
900
	if(findmount(cp, mp, (*cp)->type, (*cp)->dev, (*cp)->qid) == 0)
901
		return 0;
902
 
903
	if(path){
904
		p = *path;
905
		p = uniquepath(p);
906
		if(p->mlen <= 0)
907
			print("domount: path %s has mlen==%d\n", p->s, p->mlen);
908
		else{
909
			lc = &p->mtpt[p->mlen-1];
910
DBG("domount %p %s => add %p (was %p)\n", p, p->s, (*mp)->from, p->mtpt[p->mlen-1]);
911
			incref((*mp)->from);
912
			if(*lc)
913
				cclose(*lc);
914
			*lc = (*mp)->from;
915
		}
916
		*path = p;
917
	}
918
	return 1;
919
}
920
 
921
/*
922
 * If c is the right-hand-side of a mount point, returns the left hand side.
923
 * Changes name to reflect the fact that we've uncrossed the mountpoint,
924
 * so name had better be ours to change!
925
 */
926
static Chan*
927
undomount(Chan *c, Path *path)
928
{
929
	Chan *nc;
930
 
931
	if(path->ref != 1 || path->mlen == 0)
932
		print("undomount: path %s ref %ld mlen %d caller %#p\n",
933
			path->s, path->ref, path->mlen, getcallerpc(&c));
934
 
935
	if(path->mlen>0 && (nc=path->mtpt[path->mlen-1]) != nil){
936
DBG("undomount %p %s => remove %p\n", path, path->s, nc);
937
		cclose(c);
938
		path->mtpt[path->mlen-1] = nil;
939
		c = nc;
940
	}
941
	return c;
942
}
943
 
944
/*
945
 * Call dev walk but catch errors.
946
 */
947
static Walkqid*
948
ewalk(Chan *c, Chan *nc, char **name, int nname)
949
{
950
	Walkqid *wq;
951
 
952
	if(waserror())
953
		return nil;
954
	wq = devtab[c->type]->walk(c, nc, name, nname);
955
	poperror();
956
	return wq;
957
}
958
 
959
/*
960
 * Either walks all the way or not at all.  No partial results in *cp.
961
 * *nerror is the number of names to display in an error message.
962
 */
963
static char Edoesnotexist[] = "does not exist";
964
int
965
walk(Chan **cp, char **names, int nnames, int nomount, int *nerror)
966
{
967
	int dev, didmount, dotdot, i, n, nhave, ntry, type;
968
	Chan *c, *nc, *mtpt;
969
	Path *path;
970
	Mhead *mh, *nmh;
971
	Mount *f;
972
	Walkqid *wq;
973
 
974
	c = *cp;
975
	incref(c);
976
	path = c->path;
977
	incref(path);
978
	mh = nil;
979
 
980
	/*
981
	 * While we haven't gotten all the way down the path:
982
	 *    1. step through a mount point, if any
983
	 *    2. send a walk request for initial dotdot or initial prefix without dotdot
984
	 *    3. move to the first mountpoint along the way.
985
	 *    4. repeat.
986
	 *
987
	 * Each time through the loop:
988
	 *
989
	 *	If didmount==0, c is on the undomount side of the mount point.
990
	 *	If didmount==1, c is on the domount side of the mount point.
991
	 * 	Either way, c's full path is path.
992
	 */
993
	didmount = 0;
994
	for(nhave=0; nhave<nnames; nhave+=n){
995
		if((c->qid.type&QTDIR)==0){
996
			if(nerror)
997
				*nerror = nhave;
998
			pathclose(path);
999
			cclose(c);
1000
			strcpy(up->errstr, Enotdir);
1001
			if(mh != nil)
1002
				putmhead(mh);
1003
			return -1;
1004
		}
1005
		ntry = nnames - nhave;
1006
		if(ntry > MAXWELEM)
1007
			ntry = MAXWELEM;
1008
		dotdot = 0;
1009
		for(i=0; i<ntry; i++){
1010
			if(isdotdot(names[nhave+i])){
1011
				if(i==0){
1012
					dotdot = 1;
1013
					ntry = 1;
1014
				}else
1015
					ntry = i;
1016
				break;
1017
			}
1018
		}
1019
 
1020
		if(!dotdot && !nomount && !didmount)
1021
			domount(&c, &mh, &path);
1022
 
1023
		type = c->type;
1024
		dev = c->dev;
1025
 
1026
		if((wq = ewalk(c, nil, names+nhave, ntry)) == nil){
1027
			/* try a union mount, if any */
1028
			if(mh && !nomount){
1029
				/*
1030
				 * mh->mount->to == c, so start at mh->mount->next
1031
				 */
1032
				rlock(&mh->lock);
1033
				f = mh->mount;
1034
				for(f = (f? f->next: f); f; f = f->next)
1035
					if((wq = ewalk(f->to, nil, names+nhave, ntry)) != nil)
1036
						break;
1037
				runlock(&mh->lock);
1038
				if(f != nil){
1039
					type = f->to->type;
1040
					dev = f->to->dev;
1041
				}
1042
			}
1043
			if(wq == nil){
1044
				cclose(c);
1045
				pathclose(path);
1046
				if(nerror)
1047
					*nerror = nhave+1;
1048
				if(mh != nil)
1049
					putmhead(mh);
1050
				return -1;
1051
			}
1052
		}
1053
 
1054
		didmount = 0;
1055
		if(dotdot){
1056
			assert(wq->nqid == 1);
1057
			assert(wq->clone != nil);
1058
 
1059
			path = addelem(path, "..", nil);
1060
			nc = undomount(wq->clone, path);
1061
			nmh = nil;
1062
			n = 1;
1063
		}else{
1064
			nc = nil;
1065
			nmh = nil;
1066
			if(!nomount){
1067
				for(i=0; i<wq->nqid && i<ntry-1; i++){
1068
					if(findmount(&nc, &nmh, type, dev, wq->qid[i])){
1069
						didmount = 1;
1070
						break;
1071
					}
1072
				}
1073
			}
1074
			if(nc == nil){	/* no mount points along path */
1075
				if(wq->clone == nil){
1076
					cclose(c);
1077
					pathclose(path);
1078
					if(wq->nqid==0 || (wq->qid[wq->nqid-1].type&QTDIR)){
1079
						if(nerror)
1080
							*nerror = nhave+wq->nqid+1;
1081
						strcpy(up->errstr, Edoesnotexist);
1082
					}else{
1083
						if(nerror)
1084
							*nerror = nhave+wq->nqid;
1085
						strcpy(up->errstr, Enotdir);
1086
					}
1087
					free(wq);
1088
					if(mh != nil)
1089
						putmhead(mh);
1090
					return -1;
1091
				}
1092
				n = wq->nqid;
1093
				nc = wq->clone;
1094
			}else{		/* stopped early, at a mount point */
1095
				didmount = 1;
1096
				if(wq->clone != nil){
1097
					cclose(wq->clone);
1098
					wq->clone = nil;
1099
				}
1100
				n = i+1;
1101
			}
1102
			for(i=0; i<n; i++){
1103
				mtpt = nil;
1104
				if(i==n-1 && nmh)
1105
					mtpt = nmh->from;
1106
				path = addelem(path, names[nhave+i], mtpt);
1107
			}
1108
		}
1109
		cclose(c);
1110
		c = nc;
1111
		putmhead(mh);
1112
		mh = nmh;
1113
		free(wq);
1114
	}
1115
 
1116
	putmhead(mh);
1117
 
1118
	c = cunique(c);
1119
 
1120
	if(c->umh != nil){	//BUG
1121
		print("walk umh\n");
1122
		putmhead(c->umh);
1123
		c->umh = nil;
1124
	}
1125
 
1126
	pathclose(c->path);
1127
	c->path = path;
1128
 
1129
	cclose(*cp);
1130
	*cp = c;
1131
	if(nerror)
1132
		*nerror = nhave;
1133
	return 0;
1134
}
1135
 
1136
/*
1137
 * c is a mounted non-creatable directory.  find a creatable one.
1138
 */
1139
Chan*
1140
createdir(Chan *c, Mhead *m)
1141
{
1142
	Chan *nc;
1143
	Mount *f;
1144
 
1145
	rlock(&m->lock);
1146
	if(waserror()){
1147
		runlock(&m->lock);
1148
		nexterror();
1149
	}
1150
	for(f = m->mount; f; f = f->next){
1151
		if(f->mflag&MCREATE){
1152
			nc = cclone(f->to);
1153
			runlock(&m->lock);
1154
			poperror();
1155
			cclose(c);
1156
			return nc;
1157
		}
1158
	}
1159
	error(Enocreate);
1160
	return 0;
1161
}
1162
 
1163
void
1164
saveregisters(void)
1165
{
1166
}
1167
 
1168
static void
1169
growparse(Elemlist *e)
1170
{
1171
	char **new;
1172
	int *inew;
1173
	enum { Delta = 8 };
1174
 
1175
	if(e->nelems % Delta == 0){
1176
		new = smalloc((e->nelems+Delta) * sizeof(char*));
1177
		memmove(new, e->elems, e->nelems*sizeof(char*));
1178
		free(e->elems);
1179
		e->elems = new;
1180
		inew = smalloc((e->nelems+Delta+1) * sizeof(int));
1181
		memmove(inew, e->off, (e->nelems+1)*sizeof(int));
1182
		free(e->off);
1183
		e->off = inew;
1184
	}
1185
}
1186
 
1187
/*
1188
 * The name is known to be valid.
1189
 * Copy the name so slashes can be overwritten.
1190
 * An empty string will set nelem=0.
1191
 * A path ending in / or /. or /.//./ etc. will have
1192
 * e.mustbedir = 1, so that we correctly
1193
 * reject, e.g., "/adm/users/." when /adm/users is a file
1194
 * rather than a directory.
1195
 */
1196
static void
1197
parsename(char *aname, Elemlist *e)
1198
{
1199
	char *name, *slash;
1200
 
1201
	kstrdup(&e->name, aname);
1202
	name = e->name;
1203
	e->nelems = 0;
1204
	e->elems = nil;
1205
	e->off = smalloc(sizeof(int));
1206
	e->off[0] = skipslash(name) - name;
1207
	for(;;){
1208
		name = skipslash(name);
1209
		if(*name == '\0'){
1210
			e->off[e->nelems] = name+strlen(name) - e->name;
1211
			e->mustbedir = 1;
1212
			break;
1213
		}
1214
		growparse(e);
1215
		e->elems[e->nelems++] = name;
1216
		slash = utfrune(name, '/');
1217
		if(slash == nil){
1218
			e->off[e->nelems] = name+strlen(name) - e->name;
1219
			e->mustbedir = 0;
1220
			break;
1221
		}
1222
		e->off[e->nelems] = slash - e->name;
1223
		*slash++ = '\0';
1224
		name = slash;
1225
	}
1226
 
1227
	if(0 && chandebug){
1228
		int i;
1229
 
1230
		print("parsename %s:", e->name);
1231
		for(i=0; i<=e->nelems; i++)
1232
			print(" %d", e->off[i]);
1233
		print("\n");
1234
	}
1235
}
1236
 
1237
void*
1238
memrchr(void *va, int c, long n)
1239
{
1240
	uchar *a, *e;
1241
 
1242
	a = va;
1243
	for(e=a+n-1; e>a; e--)
1244
		if(*e == c)
1245
			return e;
1246
	return nil;
1247
}
1248
 
1249
void
1250
namelenerror(char *aname, int len, char *err)
1251
{
1252
	char *ename, *name, *next;
1253
	int i, errlen;
1254
 
1255
	/*
1256
	 * If the name is short enough, just use the whole thing.
1257
	 */
1258
	errlen = strlen(err);
1259
	if(len < ERRMAX/3 || len+errlen < 2*ERRMAX/3)
1260
		snprint(up->genbuf, sizeof up->genbuf, "%.*s", 
1261
			utfnlen(aname, len), aname);
1262
	else{
1263
		/*
1264
		 * Print a suffix of the name, but try to get a little info.
1265
		 */
1266
		ename = aname+len;
1267
		next = ename;
1268
		do{
1269
			name = next;
1270
			next = memrchr(aname, '/', name-aname);
1271
			if(next == nil)
1272
				next = aname;
1273
			len = ename-next;
1274
		}while(len < ERRMAX/3 || len + errlen < 2*ERRMAX/3);
1275
 
1276
		/*
1277
		 * If the name is ridiculously long, chop it.
1278
		 */
1279
		if(name == ename){
1280
			name = ename-ERRMAX/4;
1281
			if(name <= aname)
1282
				panic("bad math in namelenerror");
1283
			/* walk out of current UTF sequence */
1284
			for(i=0; (*name&0xC0)==0x80 && i<UTFmax; i++)
1285
				name++;
1286
		}
1287
		snprint(up->genbuf, sizeof up->genbuf, "...%.*s",
1288
			utfnlen(name, ename-name), name);
1289
	}				
1290
	snprint(up->errstr, ERRMAX, "%#q %s", up->genbuf, err);
1291
	nexterror();
1292
}
1293
 
1294
void
1295
nameerror(char *name, char *err)
1296
{
1297
	namelenerror(name, strlen(name), err);
1298
}
1299
 
1300
/*
1301
 * Turn a name into a channel.
1302
 * &name[0] is known to be a valid address.  It may be a kernel address.
1303
 *
1304
 * Opening with amode Aopen, Acreate, Aremove, or Aaccess guarantees
1305
 * that the result will be the only reference to that particular fid.
1306
 * This is necessary since we might pass the result to
1307
 * devtab[]->remove().
1308
 *
1309
 * Opening Atodir or Amount does not guarantee this.
1310
 *
1311
 * Under certain circumstances, opening Aaccess will cause
1312
 * an unnecessary clone in order to get a cunique Chan so it
1313
 * can attach the correct name.  Sysstat and sys_stat need the
1314
 * correct name so they can rewrite the stat info.
1315
 */
1316
Chan*
1317
namec(char *aname, int amode, int omode, ulong perm)
1318
{
1319
	int len, n, t, nomount;
1320
	Chan *c, *cnew;
1321
	Path *path;
1322
	Elemlist e;
1323
	Rune r;
1324
	Mhead *m;
1325
	char *createerr, tmperrbuf[ERRMAX];
1326
	char *name;
1327
 
1328
	if(aname[0] == '\0')
1329
		error("empty file name");
1330
	aname = validnamedup(aname, 1);
1331
	if(waserror()){
1332
		free(aname);
1333
		nexterror();
1334
	}
1335
	DBG("namec %s %d %d\n", aname, amode, omode);
1336
	name = aname;
1337
 
1338
	/*
1339
	 * Find the starting off point (the current slash, the root of
1340
	 * a device tree, or the current dot) as well as the name to
1341
	 * evaluate starting there.
1342
	 */
1343
	nomount = 0;
1344
	switch(name[0]){
1345
	case '/':
1346
		c = up->slash;
1347
		incref(c);
1348
		break;
1349
 
1350
	case '#':
1351
		nomount = 1;
1352
		up->genbuf[0] = '\0';
1353
		n = 0;
1354
		while(*name != '\0' && (*name != '/' || n < 2)){
1355
			if(n >= sizeof(up->genbuf)-1)
1356
				error(Efilename);
1357
			up->genbuf[n++] = *name++;
1358
		}
1359
		up->genbuf[n] = '\0';
1360
		/*
1361
		 *  noattach is sandboxing.
1362
		 *
1363
		 *  the OK exceptions are:
1364
		 *	|  it only gives access to pipes you create
1365
		 *	d  this process's file descriptors
1366
		 *	e  this process's environment
1367
		 *  the iffy exceptions are:
1368
		 *	c  time and pid, but also cons and consctl
1369
		 *	p  control of your own processes (and unfortunately
1370
		 *	   any others left unprotected)
1371
		 */
1372
		n = chartorune(&r, up->genbuf+1)+1;
1373
		/* actually / is caught by parsing earlier */
1374
		if(utfrune("M", r))
1375
			error(Enoattach);
1376
		if(up->pgrp->noattach && utfrune("|decp", r)==nil)
1377
			error(Enoattach);
1378
		t = devno(r, 1);
1379
		if(t == -1)
1380
			error(Ebadsharp);
1381
		if(debugstart && !devtab[t]->attached)
1382
			print("#%C...", devtab[t]->dc);
1383
		c = devtab[t]->attach(up->genbuf+n);
1384
		if(debugstart && c != nil)
1385
			devtab[t]->attached = 1;
1386
		break;
1387
 
1388
	default:
1389
		c = up->dot;
1390
		incref(c);
1391
		break;
1392
	}
1393
 
1394
	e.aname = aname;
1395
	e.prefix = name - aname;
1396
	e.name = nil;
1397
	e.elems = nil;
1398
	e.off = nil;
1399
	e.nelems = 0;
1400
	e.nerror = 0;
1401
	if(waserror()){
1402
		cclose(c);
1403
		free(e.name);
1404
		free(e.elems);
1405
		/*
1406
		 * Prepare nice error, showing first e.nerror elements of name.
1407
		 */
1408
		if(e.nerror == 0)
1409
			nexterror();
1410
		strcpy(tmperrbuf, up->errstr);
1411
		if(e.off[e.nerror]==0)
1412
			print("nerror=%d but off=%d\n",
1413
				e.nerror, e.off[e.nerror]);
1414
		if(0 && chandebug)
1415
			print("showing %d+%d/%d (of %d) of %s (%d %d)\n", e.prefix, e.off[e.nerror], e.nerror, e.nelems, aname, e.off[0], e.off[1]);
1416
		len = e.prefix+e.off[e.nerror];
1417
		free(e.off);
1418
		namelenerror(aname, len, tmperrbuf);
1419
	}
1420
 
1421
	/*
1422
	 * Build a list of elements in the name.
1423
	 */
1424
	parsename(name, &e);
1425
 
1426
	/*
1427
	 * On create, ....
1428
	 */
1429
	if(amode == Acreate){
1430
		/* perm must have DMDIR if last element is / or /. */
1431
		if(e.mustbedir && !(perm&DMDIR)){
1432
			e.nerror = e.nelems;
1433
			error("create without DMDIR");
1434
		}
1435
 
1436
		/* don't try to walk the last path element just yet. */
1437
		if(e.nelems == 0)
1438
			error(Eexist);
1439
		e.nelems--;
1440
	}
1441
 
1442
	if(walk(&c, e.elems, e.nelems, nomount, &e.nerror) < 0){
1443
		if(e.nerror < 0 || e.nerror > e.nelems){
1444
			print("namec %s walk error nerror=%d\n", aname, e.nerror);
1445
			e.nerror = 0;
1446
		}
1447
		nexterror();
1448
	}
1449
 
1450
	if(e.mustbedir && !(c->qid.type&QTDIR))
1451
		error("not a directory");
1452
 
1453
	if(amode == Aopen && (omode&3) == OEXEC && (c->qid.type&QTDIR))
1454
		error("cannot exec directory");
1455
 
1456
	switch(amode){
1457
	case Abind:
1458
		/* no need to maintain path - cannot dotdot an Abind */
1459
		m = nil;
1460
		if(!nomount)
1461
			domount(&c, &m, nil);
1462
		if(c->umh != nil)
1463
			putmhead(c->umh);
1464
		c->umh = m;
1465
		break;
1466
 
1467
	case Aaccess:
1468
	case Aremove:
1469
	case Aopen:
1470
	Open:
1471
		/* save&update the name; domount might change c */
1472
		path = c->path;
1473
		incref(path);
1474
		m = nil;
1475
		if(!nomount)
1476
			domount(&c, &m, &path);
1477
 
1478
		/* our own copy to open or remove */
1479
		c = cunique(c);
1480
 
1481
		/* now it's our copy anyway, we can put the name back */
1482
		pathclose(c->path);
1483
		c->path = path;
1484
 
1485
		/* record whether c is on a mount point */
1486
		c->ismtpt = m!=nil;
1487
 
1488
		switch(amode){
1489
		case Aaccess:
1490
		case Aremove:
1491
			putmhead(m);
1492
			break;
1493
 
1494
		case Aopen:
1495
		case Acreate:
1496
if(c->umh != nil){
1497
	print("cunique umh Open\n");
1498
	putmhead(c->umh);
1499
	c->umh = nil;
1500
}
1501
			/* only save the mount head if it's a multiple element union */
1502
			if(m && m->mount && m->mount->next)
1503
				c->umh = m;
1504
			else
1505
				putmhead(m);
1506
 
1507
			/* save registers else error() in open has wrong value of c saved */
1508
			saveregisters();
1509
 
1510
			if(omode == OEXEC)
1511
				c->flag &= ~CCACHE;
1512
 
1513
			c = devtab[c->type]->open(c, omode&~OCEXEC);
1514
 
1515
			if(omode & OCEXEC)
1516
				c->flag |= CCEXEC;
1517
			if(omode & ORCLOSE)
1518
				c->flag |= CRCLOSE;
1519
			break;
1520
		}
1521
		break;
1522
 
1523
	case Atodir:
1524
		/*
1525
		 * Directories (e.g. for cd) are left before the mount point,
1526
		 * so one may mount on / or . and see the effect.
1527
		 */
1528
		if(!(c->qid.type & QTDIR))
1529
			error(Enotdir);
1530
		break;
1531
 
1532
	case Amount:
1533
		/*
1534
		 * When mounting on an already mounted upon directory,
1535
		 * one wants subsequent mounts to be attached to the
1536
		 * original directory, not the replacement.  Don't domount.
1537
		 */
1538
		break;
1539
 
1540
	case Acreate:
1541
		/*
1542
		 * We've already walked all but the last element.
1543
		 * If the last exists, try to open it OTRUNC.
1544
		 * If omode&OEXCL is set, just give up.
1545
		 */
1546
		e.nelems++;
1547
		e.nerror++;
1548
		if(walk(&c, e.elems+e.nelems-1, 1, nomount, nil) == 0){
1549
			if(omode&OEXCL)
1550
				error(Eexist);
1551
			omode |= OTRUNC;
1552
			goto Open;
1553
		}
1554
 
1555
		/*
1556
		 * The semantics of the create(2) system call are that if the
1557
		 * file exists and can be written, it is to be opened with truncation.
1558
		 * On the other hand, the create(5) message fails if the file exists.
1559
		 * If we get two create(2) calls happening simultaneously, 
1560
		 * they might both get here and send create(5) messages, but only 
1561
		 * one of the messages will succeed.  To provide the expected create(2)
1562
		 * semantics, the call with the failed message needs to try the above
1563
		 * walk again, opening for truncation.  This correctly solves the 
1564
		 * create/create race, in the sense that any observable outcome can
1565
		 * be explained as one happening before the other.
1566
		 * The create/create race is quite common.  For example, it happens
1567
		 * when two rc subshells simultaneously update the same
1568
		 * environment variable.
1569
		 *
1570
		 * The implementation still admits a create/create/remove race:
1571
		 * (A) walk to file, fails
1572
		 * (B) walk to file, fails
1573
		 * (A) create file, succeeds, returns 
1574
		 * (B) create file, fails
1575
		 * (A) remove file, succeeds, returns
1576
		 * (B) walk to file, return failure.
1577
		 *
1578
		 * This is hardly as common as the create/create race, and is really
1579
		 * not too much worse than what might happen if (B) got a hold of a
1580
		 * file descriptor and then the file was removed -- either way (B) can't do
1581
		 * anything with the result of the create call.  So we don't care about this race.
1582
		 *
1583
		 * Applications that care about more fine-grained decision of the races
1584
		 * can use the OEXCL flag to get at the underlying create(5) semantics;
1585
		 * by default we provide the common case.
1586
		 *
1587
		 * We need to stay behind the mount point in case we
1588
		 * need to do the first walk again (should the create fail).
1589
		 *
1590
		 * We also need to cross the mount point and find the directory
1591
		 * in the union in which we should be creating.
1592
		 *
1593
		 * The channel staying behind is c, the one moving forward is cnew.
1594
		 */
1595
		m = nil;
1596
		cnew = nil;	/* is this assignment necessary? */
1597
		if(!waserror()){	/* try create */
1598
			if(!nomount && findmount(&cnew, &m, c->type, c->dev, c->qid))
1599
				cnew = createdir(cnew, m);
1600
			else{
1601
				cnew = c;
1602
				incref(cnew);
1603
			}
1604
 
1605
			/*
1606
			 * We need our own copy of the Chan because we're
1607
			 * about to send a create, which will move it.  Once we have
1608
			 * our own copy, we can fix the name, which might be wrong
1609
			 * if findmount gave us a new Chan.
1610
			 */
1611
			cnew = cunique(cnew);
1612
			pathclose(cnew->path);
1613
			cnew->path = c->path;
1614
			incref(cnew->path);
1615
 
1616
			devtab[cnew->type]->create(cnew, e.elems[e.nelems-1], omode&~(OEXCL|OCEXEC), perm);
1617
			poperror();
1618
			if(omode & OCEXEC)
1619
				cnew->flag |= CCEXEC;
1620
			if(omode & ORCLOSE)
1621
				cnew->flag |= CRCLOSE;
1622
			if(m)
1623
				putmhead(m);
1624
			cclose(c);
1625
			c = cnew;
1626
			c->path = addelem(c->path, e.elems[e.nelems-1], nil);
1627
			break;
1628
		}
1629
 
1630
		/* create failed */
1631
		cclose(cnew);
1632
		if(m)
1633
			putmhead(m);
1634
		if(omode & OEXCL)
1635
			nexterror();
1636
		/* save error */
1637
		createerr = up->errstr;
1638
		up->errstr = tmperrbuf;
1639
		/* note: we depend that walk does not error */
1640
		if(walk(&c, e.elems+e.nelems-1, 1, nomount, nil) < 0){
1641
			up->errstr = createerr;
1642
			error(createerr);	/* report true error */
1643
		}
1644
		up->errstr = createerr;
1645
		omode |= OTRUNC;
1646
		goto Open;
1647
 
1648
	default:
1649
		panic("unknown namec access %d\n", amode);
1650
	}
1651
 
1652
	/* place final element in genbuf for e.g. exec */
1653
	if(e.nelems > 0)
1654
		kstrcpy(up->genbuf, e.elems[e.nelems-1], sizeof up->genbuf);
1655
	else
1656
		kstrcpy(up->genbuf, ".", sizeof up->genbuf);
1657
	free(e.name);
1658
	free(e.elems);
1659
	free(e.off);
1660
	poperror();	/* e c */
1661
	free(aname);
1662
	poperror();	/* aname */
1663
 
1664
	return c;
1665
}
1666
 
1667
/*
1668
 * name is valid. skip leading / and ./ as much as possible
1669
 */
1670
char*
1671
skipslash(char *name)
1672
{
1673
	while(name[0]=='/' || (name[0]=='.' && (name[1]==0 || name[1]=='/')))
1674
		name++;
1675
	return name;
1676
}
1677
 
1678
char isfrog[256]={
1679
	/*NUL*/	1, 1, 1, 1, 1, 1, 1, 1,
1680
	/*BKS*/	1, 1, 1, 1, 1, 1, 1, 1,
1681
	/*DLE*/	1, 1, 1, 1, 1, 1, 1, 1,
1682
	/*CAN*/	1, 1, 1, 1, 1, 1, 1, 1,
1683
	['/']	1,
1684
	[0x7f]	1,
1685
};
1686
 
1687
/*
1688
 * Check that the name
1689
 *  a) is in valid memory.
1690
 *  b) is shorter than 2^16 bytes, so it can fit in a 9P string field.
1691
 *  c) contains no frogs.
1692
 * The first byte is known to be addressible by the requester, so the
1693
 * routine works for kernel and user memory both.
1694
 * The parameter slashok flags whether a slash character is an error
1695
 * or a valid character.
1696
 *
1697
 * The parameter dup flags whether the string should be copied
1698
 * out of user space before being scanned the second time.
1699
 * (Otherwise a malicious thread could remove the NUL, causing us
1700
 * to access unchecked addresses.) 
1701
 */
1702
static char*
1703
validname0(char *aname, int slashok, int dup, ulong pc)
1704
{
1705
	char *ename, *name, *s;
1706
	int c, n;
1707
	Rune r;
1708
 
1709
	name = aname;
1710
	if((ulong)name < KZERO){
1711
		if(!dup)
1712
			print("warning: validname called from %#p with user pointer", pc);
1713
		ename = vmemchr(name, 0, (1<<16));
1714
	}else
1715
		ename = memchr(name, 0, (1<<16));
1716
 
1717
	if(ename==nil || ename-name>=(1<<16))
1718
		error("name too long");
1719
 
1720
	s = nil;
1721
	if(dup){
1722
		n = ename-name;
1723
		s = smalloc(n+1);
1724
		memmove(s, name, n);
1725
		s[n] = 0;
1726
		aname = s;
1727
		name = s;
1728
		setmalloctag(s, pc);
1729
	}
1730
 
1731
	while(*name){
1732
		/* all characters above '~' are ok */
1733
		c = *(uchar*)name;
1734
		if(c >= Runeself)
1735
			name += chartorune(&r, name);
1736
		else{
1737
			if(isfrog[c])
1738
				if(!slashok || c!='/'){
1739
					snprint(up->genbuf, sizeof(up->genbuf), "%s: %q", Ebadchar, aname);
1740
					free(s);
1741
					error(up->genbuf);
1742
			}
1743
			name++;
1744
		}
1745
	}
1746
	return s;
1747
}
1748
 
1749
void
1750
validname(char *aname, int slashok)
1751
{
1752
	validname0(aname, slashok, 0, getcallerpc(&aname));
1753
}
1754
 
1755
char*
1756
validnamedup(char *aname, int slashok)
1757
{
1758
	return validname0(aname, slashok, 1, getcallerpc(&aname));
1759
}
1760
 
1761
void
1762
isdir(Chan *c)
1763
{
1764
	if(c->qid.type & QTDIR)
1765
		return;
1766
	error(Enotdir);
1767
}
1768
 
1769
/*
1770
 * This is necessary because there are many
1771
 * pointers to the top of a given mount list:
1772
 *
1773
 *	- the mhead in the namespace hash table
1774
 *	- the mhead in chans returned from findmount:
1775
 *	  used in namec and then by unionread.
1776
 *	- the mhead in chans returned from createdir:
1777
 *	  used in the open/create race protect, which is gone.
1778
 *
1779
 * The RWlock in the Mhead protects the mount list it contains.
1780
 * The mount list is deleted when we cunmount.
1781
 * The RWlock ensures that nothing is using the mount list at that time.
1782
 *
1783
 * It is okay to replace c->mh with whatever you want as 
1784
 * long as you are sure you have a unique reference to it.
1785
 *
1786
 * This comment might belong somewhere else.
1787
 */
1788
void
1789
putmhead(Mhead *m)
1790
{
1791
	if(m && decref(m) == 0){
1792
		m->mount = (Mount*)0xCafeBeef;
1793
		free(m);
1794
	}
1795
}
1796