| plan 9 kernel history: overview | file list | diff list |
1993/1115/port/chan.c (diff list | history)
| 1990/0227/sys/src/9/port/chan.c:78,83 – 1990/0303/sys/src/9/port/chan.c:78,85 (short | long) | ||
| 1990/0227 | c->offset = 0; c->mnt = 0; c->stream = 0; | |
| 1990/0303 | c->mchan = 0; c->mqid = 0; | |
| 1990/0227 | return c; } unlock(&chanalloc); | |
| 1990/0303/sys/src/9/port/chan.c:149,155 – 1990/0321/sys/src/9/port/chan.c:149,155 (short | long) | ||
| 1990/0227 | Mtab *mt, *mz; Mount *mnt, *omnt, *nmnt, *pmnt; Pgrp *pg; | |
| 1990/0321 | int islast; | |
| 1990/0227 | if(CHDIR & (old->qid^new->qid)) error(0, Emount); | |
| 1990/0303/sys/src/9/port/chan.c:157,166 – 1990/0321/sys/src/9/port/chan.c:157,171 | ||
| 1990/0227 | error(0, Emount); mz = 0; | |
| 1990/0321 | islast = 0; mnt = 0; | |
| 1990/0227 | pg = u->p->pgrp; lock(pg); if(waserror()){ | |
| 1990/0321 | if(mnt){ mnt->c = 0; /* caller will close new */ closemount(mnt); } | |
| 1990/0227 | unlock(pg); nexterror(); } | |
| 1990/0303/sys/src/9/port/chan.c:171,188 – 1990/0321/sys/src/9/port/chan.c:176,193 | ||
| 1990/0227 | for(i=0; i<pg->nmtab; i++,mt++){ if(mt->c==0 && mz==0) mz = mt; | |
| 1990/0321 | else if(eqchan(mt->c, old, CHDIR|QPATH)){ mz = 0; | |
| 1990/0227 | goto Found; | |
| 1990/0321 | } | |
| 1990/0227 | } | |
| 1990/0321 | islast++; | |
| 1990/0227 | } mz->mnt = 0; | |
| 1990/0303/sys/src/9/port/chan.c:244,251 – 1990/0321/sys/src/9/port/chan.c:249,260 | ||
| 1990/0227 | } incref(new); | |
| 1990/0321 | if(mz){ mz->c = old; | |
| 1990/0227 | incref(old); | |
| 1990/0321 | } if(islast) pg->nmtab++; | |
| 1990/0227 | unlock(pg); poperror(); return mnt->mountid; | |
| 1990/0303/sys/src/9/port/chan.c:286,292 – 1990/0321/sys/src/9/port/chan.c:295,301 | ||
| 1990/0227 | Found: lock(pg); if(!eqchan(mt->c, c, CHDIR|QPATH)){ /* table changed underfoot */ | |
| 1990/0321 | pprint("domount: changed underfoot?\n"); | |
| 1990/0227 | unlock(pg); return c; } | |
| 1990/0303/sys/src/9/port/chan.c:333,339 – 1990/0321/sys/src/9/port/chan.c:342,348 | ||
| 1990/0227 | goto Notfound; } if(c->mountid != mnt->mountid){ | |
| 1990/0321 | pprint("walk: changed underfoot?\n"); | |
| 1990/0227 | unlock(pg); goto Notfound; } | |
| 1990/0303/sys/src/9/port/chan.c:353,358 – 1990/0321/sys/src/9/port/chan.c:362,368 | ||
| 1990/0227 | if(!first) close(c); nc->mnt = mnt; | |
| 1990/0321 | nc->mountid = mnt->mountid; | |
| 1990/0227 | c = nc; first = 0; goto Again; | |
| 1990/0303/sys/src/9/port/chan.c:391,397 – 1990/0321/sys/src/9/port/chan.c:401,407 | ||
| 1990/0227 | } mnt = c->mnt; if(c->mountid != mnt->mountid){ | |
| 1990/0321 | pprint("createdir: changed underfoot?\n"); | |
| 1990/0227 | error(0, Enocreate); } do{ | |
| 1990/0321/sys/src/9/port/chan.c:490,497 – 1990/0513/sys/src/9/port/chan.c:490,499 (short | long) | ||
| 1990/0227 | switch(amode){ case Aaccess: | |
| 1990/0513 | if((nc=walk(c, elem, mntok)) == 0){ print("%d pc %lux\n", u->nerrlab, u->errlab[u->nerrlab-1].pc); | |
| 1990/0227 | error(0, Enonexist); | |
| 1990/0513 | } | |
| 1990/0227 | c = nc; break; | |
| 1990/0513/sys/src/9/port/chan.c:490,499 – 1990/0515/sys/src/9/port/chan.c:490,497 (short | long) | ||
| 1990/0227 | switch(amode){ case Aaccess: | |
| 1990/0513 |
| |
| 1990/0515 | if((nc=walk(c, elem, mntok)) == 0) | |
| 1990/0227 | error(0, Enonexist); | |
| 1990/0513 |
| |
| 1990/0227 | c = nc; break; | |
| 1990/0515/sys/src/9/port/chan.c:134,140 – 1990/0603/sys/src/9/port/chan.c:134,140 (short | long) | ||
| 1990/0227 | nmnt->mountid = omnt->mountid; nmnt->next = omnt->next; if(nmnt->next) | |
| 1990/0603 | incref(nmnt->next); | |
| 1990/0227 | nmnt->c = omnt->c; incref(nmnt->c); omnt->ref--; | |
| 1990/0515/sys/src/9/port/chan.c:207,220 – 1990/0603/sys/src/9/port/chan.c:207,218 | ||
| 1990/0227 | /* fall through */ case MREPL: | |
| 1990/0603 | mnt->next = mt->mnt; | |
| 1990/0227 | mt->mnt = mnt; | |
| 1990/0603 | else mnt->term = 1; | |
| 1990/0227 | break; /* | |
| 1990/0603/sys/src/9/port/chan.c:127,133 – 1990/0617/sys/src/9/port/chan.c:127,132 (short | long) | ||
| 1990/0227 | { Mount *nmnt; | |
| 1990/0617/sys/src/9/port/chan.c:72,77 – 1990/0707/sys/src/9/port/chan.c:72,78 (short | long) | ||
| 1990/0227 | lock(&chanalloc); if(c = chanalloc.free){ /* assign = */ chanalloc.free = c->next; | |
| 1990/0707 | c->type = 0; /* if closed before changed, this calls rooterror, a nop */ | |
| 1990/0227 | c->flag = 0; c->ref = 1; unlock(&chanalloc); | |
| 1990/0707/sys/src/9/port/chan.c:447,453 – 1990/08141/sys/src/9/port/chan.c:447,453 (short | long) | ||
| 1990/0227 | mntok = 0; if(!((ulong)name & KZERO)) validaddr((ulong)(name+1), 2, 0); | |
| 1990/08141 | if(name[1]=='|' || name[1]=='M') | |
| 1990/0227 | error(0, Enonexist); t = devno(name[1], 1); if(t == -1) | |
| 1990/0707/sys/src/9/port/chan.c:511,516 – 1990/08141/sys/src/9/port/chan.c:511,518 | ||
| 1990/0227 | c = nc; Open: c = (*devtab[c->type].open)(c, omode); | |
| 1990/08141 | if(omode & OCEXEC) c->flag |= CCEXEC; | |
| 1990/0227 | break; case Amount: | |
| 1990/0707/sys/src/9/port/chan.c:533,538 – 1990/08141/sys/src/9/port/chan.c:535,542 | ||
| 1990/0227 | if((c->flag&(CMOUNT|CCREATE)) == CMOUNT) c = createdir(c); (*devtab[c->type].create)(c, elem, omode, perm); | |
| 1990/08141 | if(omode & OCEXEC) c->flag |= CCEXEC; | |
| 1990/0227 | break; default: | |
| 1990/08141/sys/src/9/port/chan.c:340,346 – 1990/0820/sys/src/9/port/chan.c:340,346 (short | long) | ||
| 1990/0227 | goto Notfound; } if(c->mountid != mnt->mountid){ | |
| 1990/0321 |
| |
| 1990/0820 | pprint("walk: changed underfoot? '%s'\n", name); | |
| 1990/0227 | unlock(pg); goto Notfound; } | |
| 1990/08141/sys/src/9/port/chan.c:431,442 – 1990/0820/sys/src/9/port/chan.c:431,443 | ||
| 1990/0227 | { Chan *c, *nc; int t; | |
| 1990/0820 | int mntok, isdot; | |
| 1990/0227 | char *elem = u->elem; if(name[0] == 0) error(0, Enonexist); mntok = 1; | |
| 1990/0820 | isdot = 0; | |
| 1990/0227 | if(name[0] == '/'){ c = clone(u->slash, 0); /* | |
| 1990/08141/sys/src/9/port/chan.c:459,466 – 1990/0820/sys/src/9/port/chan.c:460,471 | ||
| 1990/0227 | }else name = nextelem(name, elem); c = (*devtab[t].attach)(elem); | |
| 1990/0820 | }else{ | |
| 1990/0227 | c = clone(u->dot, 0); | |
| 1990/0820 | name = skipslash(name); /* eat leading ./ */ if(*name == 0) isdot = 1; } | |
| 1990/0227 | if(waserror()){ close(c); | |
| 1990/08141/sys/src/9/port/chan.c:468,475 – 1990/0820/sys/src/9/port/chan.c:473,481 | ||
| 1990/0227 | } name = nextelem(name, elem); | |
| 1990/0820 | if(mntok && !isdot) if(!(amode==Amount && elem[0]==0)) /* don't domount on slash */ | |
| 1990/0227 | c = domount(c); /* see case Atodir below */ /* | |
| 1990/08141/sys/src/9/port/chan.c:482,487 – 1990/0820/sys/src/9/port/chan.c:488,494 | ||
| 1990/0227 | c = nc; name = nextelem(name, elem); } | |
| 1990/0820 | ||
| 1990/0227 | /* * Last element; act according to type of access. */ | |
| 1990/08141/sys/src/9/port/chan.c:488,496 – 1990/0820/sys/src/9/port/chan.c:495,507 | ||
| 1990/0227 | switch(amode){ case Aaccess: | |
| 1990/0515 |
| |
| 1990/0227 |
| |
| 1990/0820 | if(isdot) c = domount(c); else{ if((nc=walk(c, elem, mntok)) == 0) error(0, Enonexist); c = nc; } | |
| 1990/0227 | break; case Atodir: | |
| 1990/08141/sys/src/9/port/chan.c:506,514 – 1990/0820/sys/src/9/port/chan.c:517,529 | ||
| 1990/0227 | break; case Aopen: | |
| 1990/0820 | if(isdot) c = domount(c); else{ if((nc=walk(c, elem, mntok)) == 0) error(0, Enonexist); c = nc; } | |
| 1990/0227 | Open: c = (*devtab[c->type].open)(c, omode); | |
| 1990/08141 | if(omode & OCEXEC) | |
| 1990/08141/sys/src/9/port/chan.c:527,532 – 1990/0820/sys/src/9/port/chan.c:542,549 | ||
| 1990/0227 | break; case Acreate: | |
| 1990/0820 | if(isdot) error(0, Eisdir); | |
| 1990/0227 | if((nc=walk(c, elem, 1)) != 0){ c = nc; omode |= OTRUNC; | |
| 1990/08141/sys/src/9/port/chan.c:552,561 – 1990/0820/sys/src/9/port/chan.c:569,587 | ||
| 1990/0227 | char* skipslash(char *name) { | |
| 1990/0820 | Again: | |
| 1990/0227 | while(*name == '/'){ if(((ulong)name&KZERO)==0 && (((ulong)name+1)&(BY2PG-1))==0) validaddr((ulong)name+1, 1, 0); name++; | |
| 1990/0820 | } if(*name == '.'){ if(((ulong)name&KZERO)==0 && (((ulong)name+1)&(BY2PG-1))==0) validaddr((ulong)name+1, 1, 0); if(name[1]==0 || name[1]=='/'){ name++; goto Again; } | |
| 1990/0227 | } return name; } | |
| 1990/0820/sys/src/9/port/chan.c:432,441 – 1990/0821/sys/src/9/port/chan.c:432,457 (short | long) | ||
| 1990/0227 | Chan *c, *nc; int t; | |
| 1990/0820 | int mntok, isdot; | |
| 1990/0227 |
| |
| 1990/0821 | char *p; char *elem; | |
| 1990/0227 | if(name[0] == 0) error(0, Enonexist); | |
| 1990/0821 | /* * Make sure all of name is o.k. first byte is validated * externally so if it's a kernel address we know it's o.k. */ if(!((ulong)name & KZERO)){ p = name; t = BY2PG-((ulong)p&(BY2PG-1)); while(vmemchr(p, 0, t) == 0){ p += t; t = BY2PG; } } elem = u->elem; | |
| 1990/0227 | mntok = 1; | |
| 1990/0820 | isdot = 0; | |
| 1990/0227 | if(name[0] == '/'){ | |
| 1990/0820/sys/src/9/port/chan.c:446,453 – 1990/0821/sys/src/9/port/chan.c:462,467 | ||
| 1990/0227 | name = skipslash(name); }else if(name[0] == '#'){ mntok = 0; | |
| 1990/08141 | if(name[1]=='|' || name[1]=='M') | |
| 1990/0227 | error(0, Enonexist); t = devno(name[1], 1); | |
| 1990/0820/sys/src/9/port/chan.c:570,588 – 1990/0821/sys/src/9/port/chan.c:584,595 | ||
| 1990/0227 | skipslash(char *name) { | |
| 1990/0820 | Again: | |
| 1990/0227 |
| |
| 1990/0821 | while(*name == '/') | |
| 1990/0227 | name++; | |
| 1990/0821 | if(*name=='.' && (name[1]==0 || name[1]=='/')){ name++; goto Again; | |
| 1990/0820 | } | |
| 1990/0227 |
| |
| 1990/0820/sys/src/9/port/chan.c:600,606 – 1990/0821/sys/src/9/port/chan.c:607,612 | ||
| 1990/0227 | * name[0] should not be a slash. * Advance name to next element in path, copying current element into elem. * Return pointer to next element, skipping slashes. | |
| 1990/0820/sys/src/9/port/chan.c:610,618 – 1990/0821/sys/src/9/port/chan.c:616,624 | ||
| 1990/0227 | if(*name == '/') error(0, Efilename); | |
| 1990/0821 | end = memchr(name, 0, NAMELEN); | |
| 1990/0227 | if(end == 0){ | |
| 1990/0821 | end = memchr(name, '/', NAMELEN); | |
| 1990/0227 | if(end == 0) error(0, Efilename); }else{ | |
| 1990/0821/sys/src/9/port/chan.c:96,106 – 1990/0907/sys/src/9/port/chan.c:96,109 (short | long) | ||
| 1990/0227 | void close(Chan *c) { | |
| 1990/0907 | if(c->flag & CFREE) panic("close"); | |
| 1990/0227 | if(decref(c) == 0){ if(!waserror()){ (*devtab[c->type].close)(c); poperror(); } | |
| 1990/0907 | c->flag = CFREE; | |
| 1990/0227 | lock(&chanalloc); c->next = chanalloc.free; chanalloc.free = c; | |
| 1990/0907/sys/src/9/port/chan.c:372,382 – 1990/0914/sys/src/9/port/chan.c:372,392 (short | long) | ||
| 1990/0227 | if(name[0]) /* walk succeeded */ c->flag &= ~CMOUNT; | |
| 1990/0914 | if(domnt){ if(waserror()){ print("domount error\n"); if(!first) close(c); return 0; } c = domount(c); poperror(); } | |
| 1990/0227 | if(!first) close(ac); | |
| 1990/0914 | ||
| 1990/0227 | return c; Notfound: | |
| 1990/0907/sys/src/9/port/chan.c:425,430 – 1990/0914/sys/src/9/port/chan.c:435,445 | ||
| 1990/0227 | return nc; } | |
| 1990/0914 | void saveregisters(void) { } | |
| 1990/0227 | /* * Turn a name into a channel. * &name[0] is known to be a valid address. It may be a kernel address. | |
| 1990/0907/sys/src/9/port/chan.c:542,547 – 1990/0914/sys/src/9/port/chan.c:557,563 | ||
| 1990/0820 | c = nc; } | |
| 1990/0227 | Open: | |
| 1990/0914 | saveregisters(); /* else error() in open has wrong value of c saved */ | |
| 1990/0227 | c = (*devtab[c->type].open)(c, omode); | |
| 1990/08141 | if(omode & OCEXEC) c->flag |= CCEXEC; | |
| 1990/0914/sys/src/9/port/chan.c:374,380 – 1990/09141/sys/src/9/port/chan.c:374,379 (short | long) | ||
| 1990/0227 | ||
| 1990/0914 | if(domnt){ if(waserror()){ | |
| 1990/09141/sys/src/9/port/chan.c:479,485 – 1990/1009/sys/src/9/port/chan.c:479,485 (short | long) | ||
| 1990/0227 | name = skipslash(name); }else if(name[0] == '#'){ mntok = 0; | |
| 1990/08141 |
| |
| 1990/1009 | if(name[1]=='M') | |
| 1990/0227 | error(0, Enonexist); t = devno(name[1], 1); if(t == -1) | |
| 1990/1009/sys/src/9/port/chan.c:14,32 – 1990/1104/sys/src/9/port/chan.c:14,36 (short | long) | ||
| 1990/0227 | int incref(Ref *r) { | |
| 1990/1104 | int x; | |
| 1990/0227 | lock(r); | |
| 1990/1104 | x = ++r->ref; | |
| 1990/0227 | unlock(r); | |
| 1990/1104 | return x; | |
| 1990/0227 | } int decref(Ref *r) { | |
| 1990/1104 | int x; | |
| 1990/0227 | lock(r); | |
| 1990/1104 | x = --r->ref; | |
| 1990/0227 | unlock(r); | |
| 1990/1104 | return x; | |
| 1990/0227 | } void | |
| 1990/1104/sys/src/9/port/chan.c:80,90 – 1990/11211/sys/src/9/port/chan.c:80,91 (short | long) | ||
| 1990/0227 | c->flag = 0; c->ref = 1; unlock(&chanalloc); | |
| 1990/11211 | c->dev = 0; | |
| 1990/0227 | c->offset = 0; c->mnt = 0; c->stream = 0; | |
| 1990/0303 | c->mchan = 0; | |
| 1990/11211 | c->mqid = (Qid){0, 0}; | |
| 1990/0227 | return c; } unlock(&chanalloc); | |
| 1990/1104/sys/src/9/port/chan.c:116,125 – 1990/11211/sys/src/9/port/chan.c:117,134 | ||
| 1990/0227 | } int | |
| 1990/11211 | eqqid(Qid a, Qid b) | |
| 1990/0227 | { | |
| 1990/11211 | return a.path==b.path && a.vers==b.vers; } int eqchan(Chan *a, Chan *b, int pathonly) { if(a->qid.path != b->qid.path) | |
| 1990/0227 | return 0; | |
| 1990/11211 | if(!pathonly && a->qid.vers!=b->qid.vers) return 0; | |
| 1990/0227 | if(a->type != b->type) return 0; if(a->dev != b->dev) | |
| 1990/1104/sys/src/9/port/chan.c:158,167 – 1990/11211/sys/src/9/port/chan.c:167,176 | ||
| 1990/0227 | Pgrp *pg; | |
| 1990/0321 | int islast; | |
| 1990/0227 |
| |
| 1990/11211 | if(CHDIR & (old->qid.path^new->qid.path)) error(Emount); if((old->qid.path&CHDIR)==0 && (flag&MORDER)!=MREPL) error(Emount); | |
| 1990/0227 | mz = 0; | |
| 1990/0321 | islast = 0; | |
| 1990/1104/sys/src/9/port/chan.c:190,196 – 1990/11211/sys/src/9/port/chan.c:199,205 | ||
| 1990/0227 | } if(mz == 0){ if(i == conf.nmtab) | |
| 1990/11211 | error(Enomount); | |
| 1990/0227 | mz = &pg->mtab[i]; | |
| 1990/0321 | islast++; | |
| 1990/0227 | } | |
| 1990/1104/sys/src/9/port/chan.c:210,216 – 1990/11211/sys/src/9/port/chan.c:219,225 | ||
| 1990/0227 | */ case MBEFORE: if(mt->mnt == 0) | |
| 1990/11211 | error(Enotunion); | |
| 1990/0227 | /* fall through */ case MREPL: | |
| 1990/1104/sys/src/9/port/chan.c:227,233 – 1990/11211/sys/src/9/port/chan.c:236,242 | ||
| 1990/0227 | */ case MAFTER: if(mt->mnt == 0) | |
| 1990/11211 | error(Enotunion); | |
| 1990/0227 | omnt = mt->mnt; pmnt = 0; while(!omnt->term){ | |
| 1990/1104/sys/src/9/port/chan.c:416,426 – 1990/11211/sys/src/9/port/chan.c:425,435 | ||
| 1990/0227 | mnt = c->mnt; if(c->mountid != mnt->mountid){ | |
| 1990/0321 | pprint("createdir: changed underfoot?\n"); | |
| 1990/0227 |
| |
| 1990/11211 | error(Enocreate); | |
| 1990/0227 | } do{ if(mnt->term) | |
| 1990/11211 | error(Enocreate); | |
| 1990/0227 | mnt = mnt->next; }while(!(mnt->c->flag&CCREATE)); mc = mnt->c; | |
| 1990/1104/sys/src/9/port/chan.c:457,463 – 1990/11211/sys/src/9/port/chan.c:466,472 | ||
| 1990/0821 | char *elem; | |
| 1990/0227 | if(name[0] == 0) | |
| 1990/11211 | error(Enonexist); | |
| 1990/0821 | /* * Make sure all of name is o.k. first byte is validated | |
| 1990/1104/sys/src/9/port/chan.c:484,493 – 1990/11211/sys/src/9/port/chan.c:493,502 | ||
| 1990/0227 | }else if(name[0] == '#'){ mntok = 0; | |
| 1990/1009 | if(name[1]=='M') | |
| 1990/0227 |
| |
| 1990/11211 | error(Enonexist); | |
| 1990/0227 | t = devno(name[1], 1); if(t == -1) | |
| 1990/11211 | error(Ebadsharp); | |
| 1990/0227 | name += 2; if(*name == '/'){ name = skipslash(name); | |
| 1990/1104/sys/src/9/port/chan.c:519,525 – 1990/11211/sys/src/9/port/chan.c:528,534 | ||
| 1990/0227 | */ while(*name){ if((nc=walk(c, elem, mntok)) == 0) | |
| 1990/11211 | error(Enonexist); | |
| 1990/0227 | c = nc; name = nextelem(name, elem); } | |
| 1990/1104/sys/src/9/port/chan.c:534,540 – 1990/11211/sys/src/9/port/chan.c:543,549 | ||
| 1990/0820 | c = domount(c); else{ if((nc=walk(c, elem, mntok)) == 0) | |
| 1990/11211 | error(Enonexist); | |
| 1990/0820 | c = nc; } | |
| 1990/0227 | break; | |
| 1990/1104/sys/src/9/port/chan.c:545,554 – 1990/11211/sys/src/9/port/chan.c:554,563 | ||
| 1990/0227 | * so one may mount on / or . and see the effect. */ if((nc=walk(c, elem, 0)) == 0) | |
| 1990/11211 | error(Enonexist); | |
| 1990/0227 | c = nc; | |
| 1990/11211 | if(!(c->qid.path & CHDIR)) error(Enotdir); | |
| 1990/0227 | break; case Aopen: | |
| 1990/1104/sys/src/9/port/chan.c:556,562 – 1990/11211/sys/src/9/port/chan.c:565,571 | ||
| 1990/0820 | c = domount(c); else{ if((nc=walk(c, elem, mntok)) == 0) | |
| 1990/11211 | error(Enonexist); | |
| 1990/0820 | c = nc; } | |
| 1990/0227 | Open: | |
| 1990/1104/sys/src/9/port/chan.c:573,585 – 1990/11211/sys/src/9/port/chan.c:582,594 | ||
| 1990/0227 | * the replacement. */ if((nc=walk(c, elem, 0)) == 0) | |
| 1990/11211 | error(Enonexist); | |
| 1990/0227 | c = nc; break; case Acreate: | |
| 1990/0820 | if(isdot) | |
| 1990/11211 | error(Eisdir); | |
| 1990/0227 | if((nc=walk(c, elem, 1)) != 0){ c = nc; omode |= OTRUNC; | |
| 1990/1104/sys/src/9/port/chan.c:637,648 – 1990/11211/sys/src/9/port/chan.c:646,657 | ||
| 1990/0227 | char *end, *e; if(*name == '/') | |
| 1990/11211 | error(Efilename); | |
| 1990/0821 | end = memchr(name, 0, NAMELEN); | |
| 1990/0227 | if(end == 0){ | |
| 1990/0821 | end = memchr(name, '/', NAMELEN); | |
| 1990/0227 | if(end == 0) | |
| 1990/11211 | error(Efilename); | |
| 1990/0227 | }else{ e = memchr(name, '/', end-name); if(e) | |
| 1990/1104/sys/src/9/port/chan.c:651,657 – 1990/11211/sys/src/9/port/chan.c:660,666 | ||
| 1990/0227 | while(name < end){ c = *name++; if((c&0x80) || isfrog[c]) | |
| 1990/11211 | error(Ebadchar); | |
| 1990/0227 | *elem++ = c; } *elem = 0; | |
| 1990/1104/sys/src/9/port/chan.c:661,667 – 1990/11211/sys/src/9/port/chan.c:670,676 | ||
| 1990/0227 | void isdir(Chan *c) { | |
| 1990/11211 | if(c->qid.path & CHDIR) | |
| 1990/0227 | return; | |
| 1990/11211 | error(Enotdir); | |
| 1990/0227 | } | |
| 1990/11211/sys/src/9/port/chan.c:192,198 – 1990/1122/sys/src/9/port/chan.c:192,198 (short | long) | ||
| 1990/0227 | for(i=0; i<pg->nmtab; i++,mt++){ if(mt->c==0 && mz==0) mz = mt; | |
| 1990/0321 |
| |
| 1990/1122 | else if(eqchan(mt->c, old, 1)){ | |
| 1990/0321 | mz = 0; | |
| 1990/0227 | goto Found; | |
| 1990/0321 | } | |
| 1990/11211/sys/src/9/port/chan.c:296,302 – 1990/1122/sys/src/9/port/chan.c:296,302 | ||
| 1990/0227 | */ mt = pg->mtab; for(i=0; i<pg->nmtab; i++,mt++) | |
| 1990/1122 | if(mt->c && eqchan(mt->c, c, 1)) | |
| 1990/0227 | goto Found; /* * No; c is unaffected | |
| 1990/11211/sys/src/9/port/chan.c:308,314 – 1990/1122/sys/src/9/port/chan.c:308,314 | ||
| 1990/0227 | */ Found: lock(pg); | |
| 1990/1122 | if(!eqchan(mt->c, c, 1)){ /* table changed underfoot */ | |
| 1990/0321 | pprint("domount: changed underfoot?\n"); | |
| 1990/0227 | unlock(pg); return c; | |
| 1990/1122/sys/src/9/port/chan.c:99,118 – 1991/0413/sys/src/9/port/chan.c:99,126 (short | long) | ||
| 1990/0227 | } void | |
| 1991/0413 | freechan(Chan *c) { c->flag = CFREE; lock(&chanalloc); c->next = chanalloc.free; chanalloc.free = c; unlock(&chanalloc); } void | |
| 1990/0227 | close(Chan *c) { | |
| 1990/0907 | if(c->flag & CFREE) panic("close"); | |
| 1990/0227 | if(decref(c) == 0){ | |
| 1991/0413 | if(waserror()) { freechan(c); nexterror(); | |
| 1990/0227 | } | |
| 1990/0907 |
| |
| 1990/0227 |
| |
| 1991/0413 | (*devtab[c->type].close)(c); freechan(c); poperror(); | |
| 1990/0227 | } } | |
| 1991/0413/sys/src/9/port/chan.c:101,111 – 1991/0414/sys/src/9/port/chan.c:101,113 (short | long) | ||
| 1990/0227 | void | |
| 1991/0413 | freechan(Chan *c) { | |
| 1991/0414 | if(decref(c) == 0){ c->flag = CFREE; lock(&chanalloc); c->next = chanalloc.free; chanalloc.free = c; unlock(&chanalloc); } | |
| 1991/0413 | } void | |
| 1991/0413/sys/src/9/port/chan.c:114,126 – 1991/0414/sys/src/9/port/chan.c:116,130 | ||
| 1990/0907 | if(c->flag & CFREE) panic("close"); | |
| 1990/0227 | if(decref(c) == 0){ | |
| 1991/0413 |
| |
| 1991/0414 | if(!waserror()) { (*devtab[c->type].close)(c); poperror(); | |
| 1990/0227 | } | |
| 1991/0413 |
| |
| 1991/0414 | c->flag = CFREE; lock(&chanalloc); c->next = chanalloc.free; chanalloc.free = c; unlock(&chanalloc); | |
| 1990/0227 | } } | |
| 1991/0414/sys/src/9/port/chan.c:530,537 – 1991/0416/sys/src/9/port/chan.c:530,540 (short | long) | ||
| 1990/0227 | name = nextelem(name, elem); | |
| 1990/0820 |
| |
| 1991/0416 | /* * If mounting, don't follow the mount entry for root or the * current directory. */ if(mntok && !isdot && !(amode==Amount && elem[0]==0)) | |
| 1990/0227 | c = domount(c); /* see case Atodir below */ /* | |
| 1991/0414/sys/src/9/port/chan.c:548,554 – 1991/0416/sys/src/9/port/chan.c:551,556 | ||
| 1990/0227 | /* * Last element; act according to type of access. */ | |
| 1990/0820 | if(isdot) | |
| 1991/0416/sys/src/9/port/chan.c:84,89 – 1991/0421/sys/src/9/port/chan.c:84,91 (short | long) | ||
| 1990/0227 | c->offset = 0; c->mnt = 0; c->stream = 0; | |
| 1991/0421 | c->aux = 0; c->mntindex = 0; | |
| 1990/0303 | c->mchan = 0; | |
| 1990/11211 | c->mqid = (Qid){0, 0}; | |
| 1990/0227 | return c; | |
| 1991/0421/sys/src/9/port/chan.c:11,16 – 1991/0423/sys/src/9/port/chan.c:11,28 (short | long) | ||
| 1990/0227 | Chan *free; }chanalloc; | |
| 1991/0423 | /* * used by namec, domount, and walk to point * to the current mount entry during name resolution */ typedef struct Finger Finger; struct Finger { Chan *c; /* channel we're walking */ int needcl; /* true if we need to clone c before using it */ Mount *mnt; /* last mount point we ran traversed */ ulong mountid; /* id of that mount point */ }; | |
| 1990/0227 | int incref(Ref *r) { | |
| 1991/0421/sys/src/9/port/chan.c:83,91 – 1991/0423/sys/src/9/port/chan.c:95,101 | ||
| 1990/11211 | c->dev = 0; | |
| 1990/0227 | c->offset = 0; c->mnt = 0; | |
| 1991/0421 | c->aux = 0; | |
| 1990/0303 | c->mchan = 0; | |
| 1990/11211 | c->mqid = (Qid){0, 0}; | |
| 1990/0227 | return c; | |
| 1991/0421/sys/src/9/port/chan.c:294,308 – 1991/0423/sys/src/9/port/chan.c:304,316 | ||
| 1990/0227 | return (*devtab[c->type].clone)(c, nc); } | |
| 1991/0423 | void domount(Finger *f) | |
| 1990/0227 | { int i; | |
| 1991/0423 | Chan *mc; | |
| 1990/0227 | pg = u->p->pgrp; /* | |
| 1991/0421/sys/src/9/port/chan.c:310,321 – 1991/0423/sys/src/9/port/chan.c:318,329 | ||
| 1990/0227 | */ mt = pg->mtab; for(i=0; i<pg->nmtab; i++,mt++) | |
| 1990/1122 |
| |
| 1991/0423 | if(mt->c && eqchan(mt->c, f->c, 1)) | |
| 1990/0227 | goto Found; /* * No; c is unaffected */ | |
| 1991/0423 | return; | |
| 1990/0227 | /* * Yes; move c through table | |
| 1991/0421/sys/src/9/port/chan.c:322,420 – 1991/0423/sys/src/9/port/chan.c:330,419 | ||
| 1990/0227 | */ Found: lock(pg); | |
| 1990/1122 |
| |
| 1991/0423 | if(!eqchan(mt->c, f->c, 1)){ /* table changed underfoot */ | |
| 1990/0321 | pprint("domount: changed underfoot?\n"); | |
| 1990/0227 | unlock(pg); | |
| 1991/0423 | return; | |
| 1990/0227 | } | |
| 1991/0423 | f->mnt = mt->mnt; f->mountid = f->mnt->mountid; mc = mt->mnt->c; | |
| 1990/0227 | incref(mc); unlock(pg); | |
| 1991/0423 | close(f->c); f->c = mc; f->needcl = 1; | |
| 1990/0227 | } | |
| 1991/0423 | int walk(Finger *f, char *name, int domnt) | |
| 1990/0227 | { | |
| 1991/0423 | Mount *mnt = f->mnt; ulong mountid = f->mountid; Chan *c = f->c; Chan *mc; | |
| 1990/0227 | Pgrp *pg = u->p->pgrp; /* * name may be empty if the file name is "/", "#c" etc. */ | |
| 1991/0423 | if(name[0]){ for(;;){ if(!first || f->needcl){ mc = (*devtab[c->type].clwalk)(c, name); if(mc){ close(c); c = mc; break; } } else { if((*devtab[c->type].walk)(c, name) != 0){ break; } } if(!(c->flag&CMOUNT)) goto Notfound; if(mnt == 0) panic("walk"); /* ??? is this safe ??? */ lock(pg); if(mnt->term){ unlock(pg); goto Notfound; } if(mountid != mnt->mountid){ pprint("walk: changed underfoot? '%s'\n", name); unlock(pg); goto Notfound; } mnt = mnt->next; mountid = mnt->mountid; mc = mnt->c; incref(mc); | |
| 1990/0227 | unlock(pg); | |
| 1990/0820 |
| |
| 1990/0227 |
| |
| 1990/0321 |
| |
| 1990/0227 |
| |
| 1990/0914 |
| |
| 1991/0423 | c = mc; first = 0; | |
| 1990/0914 | } | |
| 1991/0423 | /* * we get here only if we have a cloned and walked * channel */ if(!first) close(f->c); f->c = c; f->needcl = 0; f->mnt = 0; c->flag &= ~CMOUNT; | |
| 1990/0914 | } | |
| 1990/0227 |
| |
| 1991/0423 | if(domnt) domount(f); | |
| 1990/0227 | ||
| 1991/0423 | return 1; | |
| 1990/0914 | ||
| 1990/0227 |
| |
| 1991/0421/sys/src/9/port/chan.c:422,435 – 1991/0423/sys/src/9/port/chan.c:421,434 | ||
| 1990/0227 | } /* | |
| 1991/0423 | * f->c is a mounted non-creatable directory. find a creatable one. | |
| 1990/0227 | */ | |
| 1991/0423 | void createdir(Finger *f) | |
| 1990/0227 | { Mount *mnt; Pgrp *pg = u->p->pgrp; | |
| 1991/0423 | Chan *mc; | |
| 1990/0227 | lock(pg); if(waserror()){ | |
| 1991/0421/sys/src/9/port/chan.c:436,443 – 1991/0423/sys/src/9/port/chan.c:435,442 | ||
| 1990/0227 | unlock(pg); nexterror(); } | |
| 1991/0423 | mnt = f->mnt; if(f->mountid != mnt->mountid){ | |
| 1990/0321 | pprint("createdir: changed underfoot?\n"); | |
| 1990/11211 | error(Enocreate); | |
| 1990/0227 | } | |
| 1991/0421/sys/src/9/port/chan.c:449,464 – 1991/0423/sys/src/9/port/chan.c:448,457 | ||
| 1990/0227 | mc = mnt->c; incref(mc); unlock(pg); | |
| 1991/0423 | close(f->c); f->needcl = 1; f->c = mc; | |
| 1990/0227 | } | |
| 1990/0914 | void | |
| 1991/0421/sys/src/9/port/chan.c:466,471 – 1991/0423/sys/src/9/port/chan.c:459,477 | ||
| 1990/0914 | { } | |
| 1991/0423 | void doclone(Finger *f) { Chan *nc; if(f->needcl == 0) return; nc = clone(f->c, 0); close(f->c); f->c = nc; f->needcl = 0; } | |
| 1990/0227 | /* * Turn a name into a channel. * &name[0] is known to be a valid address. It may be a kernel address. | |
| 1991/0421/sys/src/9/port/chan.c:473,483 – 1991/0423/sys/src/9/port/chan.c:479,489 | ||
| 1990/0227 | Chan* namec(char *name, int amode, int omode, ulong perm) { | |
| 1990/0820 | int mntok, isdot; | |
| 1990/0821 | char *p; char *elem; | |
| 1991/0423 | Finger f; | |
| 1990/0227 | if(name[0] == 0) | |
| 1990/11211 | error(Enonexist); | |
| 1991/0421/sys/src/9/port/chan.c:498,505 – 1991/0423/sys/src/9/port/chan.c:504,514 | ||
| 1990/0821 | elem = u->elem; | |
| 1990/0227 | mntok = 1; | |
| 1990/0820 | isdot = 0; | |
| 1991/0423 | f.mnt = 0; | |
| 1990/0227 | if(name[0] == '/'){ | |
| 1991/0423 | f.c = u->slash; incref(f.c); f.needcl = 1; | |
| 1990/0227 | /* * Skip leading slashes. */ | |
| 1991/0421/sys/src/9/port/chan.c:517,525 – 1991/0423/sys/src/9/port/chan.c:526,537 | ||
| 1990/0227 | elem[0]=0; }else name = nextelem(name, elem); | |
| 1991/0423 | f.c = (*devtab[t].attach)(elem); f.needcl = 0; | |
| 1990/0820 | }else{ | |
| 1990/0227 |
| |
| 1991/0423 | f.c = u->dot; incref(f.c); f.needcl = 1; | |
| 1990/0820 | name = skipslash(name); /* eat leading ./ */ if(*name == 0) isdot = 1; | |
| 1991/0421/sys/src/9/port/chan.c:526,532 – 1991/0423/sys/src/9/port/chan.c:538,544 | ||
| 1990/0820 | } | |
| 1990/0227 | if(waserror()){ | |
| 1991/0423 | close(f.c); | |
| 1990/0227 | nexterror(); } | |
| 1991/0421/sys/src/9/port/chan.c:537,543 – 1991/0423/sys/src/9/port/chan.c:549,555 | ||
| 1991/0416 | * current directory. */ if(mntok && !isdot && !(amode==Amount && elem[0]==0)) | |
| 1990/0227 |
| |
| 1991/0423 | domount(&f); /* see case Atodir below */ | |
| 1990/0227 | /* * How to treat the last element of the name depends on the operation. | |
| 1991/0421/sys/src/9/port/chan.c:544,552 – 1991/0423/sys/src/9/port/chan.c:556,563 | ||
| 1990/0227 | * Therefore do all but the last element by the easy algorithm. */ while(*name){ | |
| 1991/0423 | if(walk(&f, elem, mntok) == 0) | |
| 1990/11211 | error(Enonexist); | |
| 1990/0227 |
| |
| 1990/0820 | ||
| 1991/0421/sys/src/9/port/chan.c:556,566 – 1991/0423/sys/src/9/port/chan.c:567,576 | ||
| 1990/0227 | switch(amode){ case Aaccess: | |
| 1990/0820 | if(isdot) | |
| 1991/0423 | domount(&f); | |
| 1990/0820 | else{ | |
| 1991/0423 | if(walk(&f, elem, mntok) == 0) | |
| 1990/11211 | error(Enonexist); | |
| 1990/0820 |
| |
| 1990/0227 | break; | |
| 1991/0421/sys/src/9/port/chan.c:569,594 – 1991/0423/sys/src/9/port/chan.c:579,604 | ||
| 1990/0227 | * Directories (e.g. for cd) are left before the mount point, * so one may mount on / or . and see the effect. */ | |
| 1991/0423 | if(walk(&f, elem, 0) == 0) | |
| 1990/11211 | error(Enonexist); | |
| 1990/0227 |
| |
| 1990/11211 |
| |
| 1991/0423 | if(!(f.c->qid.path & CHDIR)) | |
| 1990/11211 | error(Enotdir); | |
| 1990/0227 | break; case Aopen: | |
| 1990/0820 | if(isdot) | |
| 1991/0423 | domount(&f); | |
| 1990/0820 | else{ | |
| 1991/0423 | if(walk(&f, elem, mntok) == 0) | |
| 1990/11211 | error(Enonexist); | |
| 1990/0820 |
| |
| 1990/0227 | Open: | |
| 1990/0914 |
| |
| 1990/0227 |
| |
| 1991/0423 | saveregisters(); /* else error() in open has wrong value of c saved */ if(f.needcl) doclone(&f); f.c = (*devtab[f.c->type].open)(f.c, omode); | |
| 1990/08141 | if(omode & OCEXEC) | |
| 1991/0423 | f.c->flag |= CCEXEC; | |
| 1990/0227 | break; case Amount: | |
| 1991/0421/sys/src/9/port/chan.c:597,627 – 1991/0423/sys/src/9/port/chan.c:607,643 | ||
| 1990/0227 | * the second mount to be attached to the original directory, not * the replacement. */ | |
| 1991/0423 | if(walk(&f, elem, 0) == 0) | |
| 1990/11211 | error(Enonexist); | |
| 1990/0227 |
| |
| 1990/0820 | if(isdot) | |
| 1990/11211 | error(Eisdir); | |
| 1990/0227 |
| |
| 1991/0423 | if(walk(&f, elem, 1) != 0){ | |
| 1990/0227 | omode |= OTRUNC; goto Open; } | |
| 1991/0423 | if((f.c->flag&(CMOUNT|CCREATE)) == CMOUNT) createdir(&f); if(f.needcl) doclone(&f); (*devtab[f.c->type].create)(f.c, elem, omode, perm); | |
| 1990/08141 | if(omode & OCEXEC) | |
| 1991/0423 | f.c->flag |= CCEXEC; | |
| 1990/0227 | break; default: panic("unknown namec access %d\n", amode); } | |
| 1991/0423 | if(f.needcl) doclone(&f); | |
| 1990/0227 | poperror(); | |
| 1991/0423 | if(f.c->flag & CMOUNT){ f.c->mnt = f.mnt; f.c->mountid = f.mountid; } return f.c; | |
| 1990/0227 | } /* | |
| 1991/0423/sys/src/9/port/chan.c:111,128 – 1991/0426/sys/src/9/port/chan.c:111,116 (short | long) | ||
| 1990/0227 | } void | |
| 1991/0413 |
| |
| 1991/0414 |
| |
| 1991/0413 |
| |
| 1990/0227 | close(Chan *c) { | |
| 1990/0907 | if(c->flag & CFREE) | |
| 1991/0426/sys/src/9/port/chan.c:11,28 – 1991/0427/sys/src/9/port/chan.c:11,16 (short | long) | ||
| 1990/0227 | Chan *free; }chanalloc; | |
| 1991/0423 |
| |
| 1990/0227 | int incref(Ref *r) { | |
| 1991/0426/sys/src/9/port/chan.c:95,101 – 1991/0427/sys/src/9/port/chan.c:83,91 | ||
| 1990/11211 | c->dev = 0; | |
| 1990/0227 | c->offset = 0; c->mnt = 0; | |
| 1991/0427 | c->stream = 0; | |
| 1991/0421 | c->aux = 0; | |
| 1991/0427 | c->mntindex = 0; | |
| 1990/0303 | c->mchan = 0; | |
| 1990/11211 | c->mqid = (Qid){0, 0}; | |
| 1990/0227 | return c; | |
| 1991/0426/sys/src/9/port/chan.c:292,304 – 1991/0427/sys/src/9/port/chan.c:282,296 | ||
| 1990/0227 | return (*devtab[c->type].clone)(c, nc); } | |
| 1991/0423 |
| |
| 1991/0427 | Chan* domount(Chan *c) | |
| 1990/0227 | { int i; | |
| 1991/0427 | ulong mntid; | |
| 1990/0227 | Mtab *mt; | |
| 1991/0427 | Mount *mnt; | |
| 1990/0227 | Pgrp *pg; | |
| 1991/0423 |
| |
| 1991/0427 | Chan *nc, *mc; | |
| 1990/0227 | pg = u->p->pgrp; /* | |
| 1991/0426/sys/src/9/port/chan.c:306,317 – 1991/0427/sys/src/9/port/chan.c:298,309 | ||
| 1990/0227 | */ mt = pg->mtab; for(i=0; i<pg->nmtab; i++,mt++) | |
| 1991/0423 |
| |
| 1991/0427 | if(mt->c && eqchan(mt->c, c, 1)) | |
| 1990/0227 | goto Found; /* * No; c is unaffected */ | |
| 1991/0423 |
| |
| 1991/0427 | return c; | |
| 1990/0227 | /* * Yes; move c through table | |
| 1991/0426/sys/src/9/port/chan.c:318,407 – 1991/0427/sys/src/9/port/chan.c:310,408 | ||
| 1990/0227 | */ Found: lock(pg); | |
| 1991/0423 |
| |
| 1991/0427 | if(!eqchan(mt->c, c, 1)){ /* table changed underfoot */ | |
| 1990/0321 | pprint("domount: changed underfoot?\n"); | |
| 1990/0227 | unlock(pg); | |
| 1991/0423 |
| |
| 1991/0427 | return c; | |
| 1990/0227 | } | |
| 1991/0423 |
| |
| 1991/0427 | mnt = mt->mnt; mntid = mnt->mountid; mc = mnt->c; | |
| 1990/0227 | incref(mc); unlock(pg); | |
| 1991/0423 |
| |
| 1991/0427 | if(waserror()){ close(mc); nexterror(); } nc = clone(mc, 0); close(mc); poperror(); close(c); nc->mnt = mnt; nc->mountid = mntid; return nc; | |
| 1990/0227 | } | |
| 1991/0423 |
| |
| 1991/0427 | Chan* walk(Chan *ac, char *name, int domnt) | |
| 1990/0227 | { | |
| 1991/0427 | Mount *mnt; | |
| 1990/0227 | int first = 1; | |
| 1991/0423 |
| |
| 1991/0427 | Chan *c = ac; Chan *nc, *mc; | |
| 1990/0227 | Pgrp *pg = u->p->pgrp; /* * name may be empty if the file name is "/", "#c" etc. */ | |
| 1991/0423 |
| |
| 1991/0427 | Again: if(name[0] && (*devtab[c->type].walk)(c, name)==0){ if(!(c->flag&CMOUNT)) goto Notfound; mnt = c->mnt; if(mnt == 0) panic("walk"); lock(pg); if(mnt->term){ | |
| 1990/0227 | unlock(pg); | |
| 1990/0914 |
| |
| 1991/0423 |
| |
| 1991/0427 | goto Notfound; | |
| 1990/0914 | } | |
| 1991/0423 |
| |
| 1991/0427 | if(c->mountid != mnt->mountid){ pprint("walk: changed underfoot? '%s'\n", name); unlock(pg); goto Notfound; } mnt = mnt->next; mc = mnt->c; incref(mc); unlock(pg); if(waserror()){ close(mc); nexterror(); } if(mnt == 0) panic("walk 1"); nc = clone(mc, 0); close(mc); poperror(); | |
| 1991/0423 | if(!first) | |
| 1991/0427 | close(c); nc->mnt = mnt; nc->mountid = mnt->mountid; c = nc; first = 0; goto Again; } if(name[0]) /* walk succeeded */ | |
| 1991/0423 | c->flag &= ~CMOUNT; | |
| 1991/0427 | if(domnt){ if(waserror()){ if(!first) close(c); return 0; } c = domount(c); poperror(); | |
| 1990/0914 | } | |
| 1991/0423 |
| |
| 1991/0427 | if(!first) close(ac); | |
| 1990/0227 | ||
| 1991/0423 |
| |
| 1990/0914 | ||
| 1991/0427 | return c; | |
| 1990/0227 | Notfound: if(!first) close(c); | |
| 1991/0426/sys/src/9/port/chan.c:409,422 – 1991/0427/sys/src/9/port/chan.c:410,423 | ||
| 1990/0227 | } /* | |
| 1991/0423 |
| |
| 1991/0427 | * c is a mounted non-creatable directory. find a creatable one. | |
| 1990/0227 | */ | |
| 1991/0423 |
| |
| 1991/0427 | Chan* createdir(Chan *c) | |
| 1990/0227 | { Mount *mnt; Pgrp *pg = u->p->pgrp; | |
| 1991/0423 |
| |
| 1991/0427 | Chan *mc, *nc; | |
| 1990/0227 | lock(pg); if(waserror()){ | |
| 1991/0426/sys/src/9/port/chan.c:423,430 – 1991/0427/sys/src/9/port/chan.c:424,431 | ||
| 1990/0227 | unlock(pg); nexterror(); } | |
| 1991/0423 |
| |
| 1991/0427 | mnt = c->mnt; if(c->mountid != mnt->mountid){ | |
| 1990/0321 | pprint("createdir: changed underfoot?\n"); | |
| 1990/11211 | error(Enocreate); | |
| 1990/0227 | } | |
| 1991/0426/sys/src/9/port/chan.c:436,445 – 1991/0427/sys/src/9/port/chan.c:437,452 | ||
| 1990/0227 | mc = mnt->c; incref(mc); unlock(pg); | |
| 1991/0427 | if(waserror()){ close(mc); nexterror(); } nc = clone(mc, 0); | |
| 1990/0227 | poperror(); | |
| 1991/0423 |
| |
| 1991/0427 | close(c); close(mc); nc->mnt = mnt; return nc; | |
| 1990/0227 | } | |
| 1990/0914 | void | |
| 1991/0426/sys/src/9/port/chan.c:447,465 – 1991/0427/sys/src/9/port/chan.c:454,459 | ||
| 1990/0914 | { } | |
| 1991/0423 |
| |
| 1990/0227 | /* * Turn a name into a channel. * &name[0] is known to be a valid address. It may be a kernel address. | |
| 1991/0426/sys/src/9/port/chan.c:467,477 – 1991/0427/sys/src/9/port/chan.c:461,471 | ||
| 1990/0227 | Chan* namec(char *name, int amode, int omode, ulong perm) { | |
| 1991/0427 | Chan *c, *nc, *cc; | |
| 1990/0227 | int t; | |
| 1990/0820 | int mntok, isdot; | |
| 1990/0821 | char *p; char *elem; | |
| 1991/0423 |
| |
| 1990/0227 | if(name[0] == 0) | |
| 1990/11211 | error(Enonexist); | |
| 1991/0426/sys/src/9/port/chan.c:492,502 – 1991/0427/sys/src/9/port/chan.c:486,493 | ||
| 1990/0821 | elem = u->elem; | |
| 1990/0227 | mntok = 1; | |
| 1990/0820 | isdot = 0; | |
| 1991/0423 |
| |
| 1990/0227 | if(name[0] == '/'){ | |
| 1991/0423 |
| |
| 1991/0427 | c = clone(u->slash, 0); | |
| 1990/0227 | /* * Skip leading slashes. */ | |
| 1991/0426/sys/src/9/port/chan.c:514,525 – 1991/0427/sys/src/9/port/chan.c:505,513 | ||
| 1990/0227 | elem[0]=0; }else name = nextelem(name, elem); | |
| 1991/0423 |
| |
| 1991/0427 | c = (*devtab[t].attach)(elem); | |
| 1990/0820 | }else{ | |
| 1991/0423 |
| |
| 1991/0427 | c = clone(u->dot, 0); | |
| 1990/0820 | name = skipslash(name); /* eat leading ./ */ if(*name == 0) isdot = 1; | |
| 1991/0426/sys/src/9/port/chan.c:526,532 – 1991/0427/sys/src/9/port/chan.c:514,520 | ||
| 1990/0820 | } | |
| 1990/0227 | if(waserror()){ | |
| 1991/0423 |
| |
| 1991/0427 | close(c); | |
| 1990/0227 | nexterror(); } | |
| 1991/0426/sys/src/9/port/chan.c:537,543 – 1991/0427/sys/src/9/port/chan.c:525,531 | ||
| 1991/0416 | * current directory. */ if(mntok && !isdot && !(amode==Amount && elem[0]==0)) | |
| 1991/0423 |
| |
| 1991/0427 | c = domount(c); /* see case Atodir below */ | |
| 1990/0227 | /* * How to treat the last element of the name depends on the operation. | |
| 1991/0426/sys/src/9/port/chan.c:544,551 – 1991/0427/sys/src/9/port/chan.c:532,540 | ||
| 1990/0227 | * Therefore do all but the last element by the easy algorithm. */ while(*name){ | |
| 1991/0423 |
| |
| 1991/0427 | if((nc=walk(c, elem, mntok)) == 0) | |
| 1990/11211 | error(Enonexist); | |
| 1991/0427 | c = nc; | |
| 1990/0227 | name = nextelem(name, elem); } | |
| 1990/0820 | ||
| 1991/0426/sys/src/9/port/chan.c:555,564 – 1991/0427/sys/src/9/port/chan.c:544,554 | ||
| 1990/0227 | switch(amode){ case Aaccess: | |
| 1990/0820 | if(isdot) | |
| 1991/0423 |
| |
| 1991/0427 | c = domount(c); | |
| 1990/0820 | else{ | |
| 1991/0423 |
| |
| 1991/0427 | if((nc=walk(c, elem, mntok)) == 0) | |
| 1990/11211 | error(Enonexist); | |
| 1991/0427 | c = nc; | |
| 1990/0820 | } | |
| 1990/0227 | break; | |
| 1991/0426/sys/src/9/port/chan.c:567,592 – 1991/0427/sys/src/9/port/chan.c:557,582 | ||
| 1990/0227 | * Directories (e.g. for cd) are left before the mount point, * so one may mount on / or . and see the effect. */ | |
| 1991/0423 |
| |
| 1991/0427 | if((nc=walk(c, elem, 0)) == 0) | |
| 1990/11211 | error(Enonexist); | |
| 1991/0423 |
| |
| 1991/0427 | c = nc; if(!(c->qid.path & CHDIR)) | |
| 1990/11211 | error(Enotdir); | |
| 1990/0227 | break; case Aopen: | |
| 1990/0820 | if(isdot) | |
| 1991/0423 |
| |
| 1991/0427 | c = domount(c); | |
| 1990/0820 | else{ | |
| 1991/0423 |
| |
| 1991/0427 | if((nc=walk(c, elem, mntok)) == 0) | |
| 1990/11211 | error(Enonexist); | |
| 1991/0427 | c = nc; | |
| 1990/0820 | } | |
| 1990/0227 | Open: | |
| 1991/0423 |
| |
| 1991/0427 | saveregisters(); /* else error() in open has wrong value of c saved */ c = (*devtab[c->type].open)(c, omode); | |
| 1990/08141 | if(omode & OCEXEC) | |
| 1991/0423 |
| |
| 1991/0427 | c->flag |= CCEXEC; | |
| 1990/0227 | break; case Amount: | |
| 1991/0426/sys/src/9/port/chan.c:595,631 – 1991/0427/sys/src/9/port/chan.c:585,635 | ||
| 1990/0227 | * the second mount to be attached to the original directory, not * the replacement. */ | |
| 1991/0423 |
| |
| 1991/0427 | if((nc=walk(c, elem, 0)) == 0) | |
| 1990/11211 | error(Enonexist); | |
| 1991/0427 | c = nc; | |
| 1990/0227 | break; case Acreate: | |
| 1990/0820 | if(isdot) | |
| 1990/11211 | error(Eisdir); | |
| 1991/0423 |
| |
| 1991/0427 | /* * Walk the element before trying to create it * to see if it exists. We clone the channel * first, just in case someone is trying to * use clwalk outside the kernel. */ cc = clone(c, 0); if(waserror()){ close(cc); nexterror(); } if((nc=walk(cc, elem, 1)) != 0){ poperror(); close(c); c = nc; | |
| 1990/0227 | omode |= OTRUNC; goto Open; } | |
| 1991/0423 |
| |
| 1991/0427 | close(cc); poperror(); /* * the file didn't exist, try the create */ if((c->flag&(CMOUNT|CCREATE)) == CMOUNT) c = createdir(c); (*devtab[c->type].create)(c, elem, omode, perm); | |
| 1990/08141 | if(omode & OCEXEC) | |
| 1991/0423 |
| |
| 1991/0427 | c->flag |= CCEXEC; | |
| 1990/0227 | break; default: panic("unknown namec access %d\n", amode); } | |
| 1991/0423 |
| |
| 1990/0227 | poperror(); | |
| 1991/0423 |
| |
| 1991/0427 | return c; | |
| 1990/0227 | } /* | |
| 1991/0427/sys/src/9/port/chan.c:30,35 – 1991/0705/sys/src/9/port/chan.c:30,37 (short | long) | ||
| 1990/0227 | lock(r); | |
| 1990/1104 | x = --r->ref; | |
| 1990/0227 | unlock(r); | |
| 1991/0705 | if(x < 0) panic("decref"); | |
| 1990/1104 | return x; | |
| 1990/0227 | } | |
| Too many diffs (26 > 25). Stopping. | ||