| plan 9 kernel history: overview | file list | diff list |
1999/0629/port/chan.c (diff list | history)
| 1999/0501/sys/src/9/port/chan.c:5,10 – 1999/0629/sys/src/9/port/chan.c:5,15 (short | long | prev | next) | ||
| 1990/0227 | #include "fns.h" | |
| 1992/0111 | #include "../port/error.h" | |
| 1990/0227 | ||
| 1999/0629 | enum { CNAMESLOP = 20 }; | |
| 1992/0620 | struct { | |
| 1990/0227 | Lock; | |
| 1999/0501/sys/src/9/port/chan.c:13,18 – 1999/0629/sys/src/9/port/chan.c:18,25 | ||
| 1993/0501 | Chan *list; | |
| 1990/0227 | }chanalloc; | |
| 1999/0629 | #define SEP(c) ((c) == 0 || (c) == '/') | |
| 1990/0227 | int incref(Ref *r) { | |
| 1999/0501/sys/src/9/port/chan.c:100,112 – 1999/0629/sys/src/9/port/chan.c:107,179 | ||
| 1998/0829 | c->uri = 0; | |
| 1992/0620 | c->aux = 0; c->mchan = 0; | |
| 1993/0501 |
| |
| 1993/1013 | c->mcp = 0; | |
| 1992/0620 | c->mqid = (Qid){0, 0}; | |
| 1999/0629 | c->name = 0; | |
| 1992/0620 | return c; | |
| 1990/0227 | } | |
| 1999/0629 | static Ref ncname; Cname* newcname(char *s) { Cname *n; int i; n = smalloc(sizeof(Cname)); i = strlen(s); n->len = i; n->alen = i+CNAMESLOP; n->s = smalloc(n->alen); memmove(n->s, s, i+1); n->ref = 1; incref(&ncname); return n; } | |
| 1997/1210 | void | |
| 1999/0629 | cnameclose(Cname *n) { if(n == 0) return; if(decref(n)) return; decref(&ncname); free(n->s); free(n); } Cname* addelem(Cname *n, char *s) { int i, a; char *t; Cname *new; if(n->ref > 1){ /* copy on write */ new = newcname(n->s); cnameclose(n); n = new; } i = strlen(s); if(n->len+1+i+1 < n->alen){ a = n->len+1+i+1 + CNAMESLOP; t = smalloc(a); memmove(t, n->s, n->len+1); free(n->s); n->s = t; n->alen = a; } n->s[n->len++] = '/'; memmove(n->s+n->len, s, i+1); n->len += i; return n; } void | |
| 1992/0320 | chanfree(Chan *c) { c->flag = CFREE; | |
| 1999/0501/sys/src/9/port/chan.c:121,138 – 1999/0629/sys/src/9/port/chan.c:188,194 | ||
| 1998/0829 | c->mh = nil; } | |
| 1993/0501 |
| |
| 1998/0416 |
| |
| 1998/0512 |
| |
| 1993/0501 |
| |
| 1998/0512 |
| |
| 1999/0629 | cnameclose(c->name); | |
| 1993/0501 | ||
| 1992/0320 | lock(&chanalloc); c->next = chanalloc.free; | |
| 1999/0501/sys/src/9/port/chan.c:333,339 – 1999/0629/sys/src/9/port/chan.c:389,401 | ||
| 1990/0227 | Chan* | |
| 1997/0327 | cclone(Chan *c, Chan *nc) | |
| 1990/0227 | { | |
| 1997/0327 |
| |
| 1999/0629 | nc = devtab[c->type]->clone(c, nc); if(nc != nil){ nc->name = c->name; if(c->name) incref(c->name); } return nc; | |
| 1990/0227 | } | |
| 1991/0427 | Chan* | |
| 1999/0501/sys/src/9/port/chan.c:411,416 – 1999/0629/sys/src/9/port/chan.c:473,493 | ||
| 1991/1011 | } | |
| 1990/0914 | ||
| 1998/0224 | int | |
| 1999/0629 | walkname(Chan **cp, char *name, int domnt) { Chan *c; if(walk(cp, name, domnt) < 0) return -1; c = *cp; if(c->name == nil) c->name = newcname(name); else c->name = addelem(c->name, name); return 0; } int | |
| 1998/0224 | walk(Chan **cp, char *name, int domnt) | |
| 1991/1011 | { | |
| 1998/0224 | Chan *c, *ac; | |
| 1999/0501/sys/src/9/port/chan.c:563,568 – 1999/0629/sys/src/9/port/chan.c:640,695 | ||
| 1990/0914 | } | |
| 1990/0227 | /* | |
| 1999/0629 | * In place, rewrite name to compress multiple /, eliminate ., and process .. */ void cleanname(Cname *n, int offset) { char *p, *q, *dotdot, *name; int rooted; name = n->s+offset; rooted = name[0] == '/'; /* * 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 != '/') ; } else if(!rooted) { /* ``/..'' ≡ ``/'', but ``./../'' ≡ ``..'' */ 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++ = '.'; *q = 0; n->len = (q-name) + offset; } /* | |
| 1990/0227 | * Turn a name into a channel. * &name[0] is known to be a valid address. It may be a kernel address. */ | |
| 1999/0501/sys/src/9/port/chan.c:572,578 – 1999/0629/sys/src/9/port/chan.c:699,706 | ||
| 1992/1217 | Rune r; | |
| 1990/0821 | char *p; | |
| 1992/0711 | char *elem; | |
| 1993/0501 |
| |
| 1999/0629 | Cname *cname; int t, n, newname; | |
| 1993/0501 | int mntok, isdot; | |
| 1998/0224 | Chan *c, *cc; | |
| 1991/1105 | char createerr[ERRLEN]; | |
| 1999/0501/sys/src/9/port/chan.c:589,603 – 1999/0629/sys/src/9/port/chan.c:717,740 | ||
| 1990/0821 | } } | |
| 1999/0629 | newname = 1; cname = nil; if(waserror()){ cnameclose(cname); nexterror(); } | |
| 1993/0501 | elem = up->elem; | |
| 1990/0227 | mntok = 1; | |
| 1990/0820 | isdot = 0; | |
| 1993/0501 | switch(name[0]) { case '/': | |
| 1997/0327 |
| |
| 1999/0629 | cname = newcname(name); /* save this before advancing */ | |
| 1990/0227 | name = skipslash(name); | |
| 1999/0629 | c = cclone(up->slash, 0); | |
| 1993/0501 | break; case '#': | |
| 1999/0629 | cname = newcname(name); /* save this before advancing */ | |
| 1990/0227 | mntok = 0; | |
| 1993/0501 | elem[0] = 0; n = 0; | |
| 1999/0501/sys/src/9/port/chan.c:611,616 – 1999/0629/sys/src/9/port/chan.c:748,755 | ||
| 1995/0208 | name = skipslash(name); if(*name) error(Efilename); | |
| 1999/0629 | poperror(); cnameclose(cname); | |
| 1995/0208 | return c; } else { | |
| 1999/0501/sys/src/9/port/chan.c:627,632 – 1999/0629/sys/src/9/port/chan.c:766,773 | ||
| 1993/0501 | name = skipslash(name); break; default: | |
| 1999/0629 | cname = newcname(up->dot->name->s); cname = addelem(cname, name); | |
| 1997/0327 | c = cclone(up->dot, 0); | |
| 1993/0501 | name = skipslash(name); | |
| 1990/0820 | if(*name == 0) | |
| 1999/0501/sys/src/9/port/chan.c:688,694 – 1999/0629/sys/src/9/port/chan.c:829,838 | ||
| 1993/1017 | if(omode == OEXEC) | |
| 1993/1018 | c->flag &= ~CCACHE; | |
| 1998/0512 | ||
| 1999/0629 | cc = c; | |
| 1999/0122 | c = devtab[c->type]->open(c, omode&~OCEXEC); | |
| 1999/0629 | if(cc != c) newname = 0; | |
| 1993/1018 | ||
| 1990/08141 | if(omode & OCEXEC) | |
| 1991/0427 | c->flag |= CCEXEC; | |
| 1999/0501/sys/src/9/port/chan.c:760,765 – 1999/0629/sys/src/9/port/chan.c:904,923 | ||
| 1990/0227 | default: panic("unknown namec access %d\n", amode); } | |
| 1999/0629 | poperror(); /* peculiar workaround for #/ */ if(newname){ if(cname->s[0]=='#' && cname->s[1]=='/') cleanname(cname, 2); else cleanname(cname, 0); cnameclose(c->name); c->name = cname; }else cnameclose(cname); | |
| 1990/0227 | poperror(); | |
| 1991/0427 | return c; | |
| 1990/0227 | } | |