plan 9 kernel history: overview | file list | diff list

1999/1230/port/chan.c (diff list | history)

1999/1224/sys/src/9/port/chan.c:19,251999/1230/sys/src/9/port/chan.c:19,25 (short | long | prev | next)
1990/0227    
}chanalloc; 
 
1999/0629    
#define SEP(c) ((c) == 0 || (c) == '/') 
1999/0811    
void cleancname(Cname*, int); 
1999/1230    
void cleancname(Cname*); 
1999/0629    
 
1990/0227    
int 
incref(Ref *r) 
1999/1224/sys/src/9/port/chan.c:483,4891999/1230/sys/src/9/port/chan.c:483,489
1999/1224    
		c->name = addelem(c->name, name); 
	 
	if(dotdot){ 
		cleancname(c->name, c->name->s[0]=='#');	/* could be cheaper */ 
1999/1230    
		cleancname(c->name);	/* could be cheaper */ 
1999/1224    
		c = undomount(c); 
	} 
	return c; 
1999/1224/sys/src/9/port/chan.c:644,6931999/1230/sys/src/9/port/chan.c:644,668
1999/0629    
 * In place, rewrite name to compress multiple /, eliminate ., and process .. 
 */ 
void 
1999/0716    
cleancname(Cname *n, int offset) 
1999/1230    
cleancname(Cname *n) 
1999/0629    
{ 
	char *p, *q, *dotdot, *name; 
	int rooted; 
1999/1230    
	char *p; 
1999/0629    
 
	name = n->s+offset; 
	rooted = name[0] == '/'; 
1999/1230    
	if(n->s[0] == '#'){ 
		p = strchr(n->s, '/'); 
		if(p == nil) 
			return; 
		cleanname(p); 
1999/0629    
 
	/* 
	 * invariants: 
	 *	p points at beginning of path element we're considering. 
	 *	q points just past the last path element we wrote (no slash). 
	 *	dotdot points just past the point where .. cannot backtrack 
	 *		any further (no slash). 
	 */ 
	p = q = dotdot = name+rooted; 
	while(*p) { 
		if(p[0] == '/')	/* null element */ 
			p++; 
		else if(p[0] == '.' && SEP(p[1])) 
			p += 1;	/* don't count the separator in case it is nul */ 
		else if(p[0] == '.' && p[1] == '.' && SEP(p[2])) { 
			p += 2; 
			if(q > dotdot) {	/* can backtrack */ 
				while(--q > dotdot && *q != '/') 
					; 
1999/0716    
			} else if(!rooted) {	/* /.. is / but ./../ is .. */ 
1999/0629    
				if(q != name) 
					*q++ = '/'; 
				*q++ = '.'; 
				*q++ = '.'; 
				dotdot = q; 
			} 
		} else {	/* real path element */ 
			if(q != name+rooted) 
				*q++ = '/'; 
			while((*q = *p) != '/' && *q != 0) 
				p++, q++; 
		} 
	} 
	if(q == name)	/* empty string is really ``.'' */ 
		*q++ = '.'; 
1999/0716    
	*q = '\0'; 
1999/0629    
	n->len = (q-name) + offset; 
1999/1230    
		/* 
		 * The correct name is #i rather than #i/, 
		 * but the correct name of #/ is #/. 
		 */ 
		if(strcmp(p, "/")==0 && n->s[1] != '/') 
			*p = '\0'; 
	}else 
		cleanname(n->s); 
	n->len = strlen(n->s); 
1999/0629    
} 
 
/* 
1999/1224/sys/src/9/port/chan.c:911,9221999/1230/sys/src/9/port/chan.c:886,893
1999/0629    
 
	poperror(); 
 
	/* peculiar workaround for #/ */ 
	if(newname){ 
		if(cname->s[0]=='#' && cname->s[1]=='/') 
1999/0716    
			cleancname(cname, 1); 
1999/0629    
		else 
1999/0716    
			cleancname(cname, 0); 
1999/1230    
		cleancname(cname); 
1999/0629    
		cnameclose(c->name); 
		c->name = cname; 
	}else 


source code copyright © 1990-2005 Lucent Technologies; see license
Plan 9 distribution
comments to russ cox (rsc@swtch.com)