| plan 9 kernel history: overview | file list | diff list |
1991/1117/port/devmux.c (diff list | history)
| 1991/1115/sys/src/9/port/devmux.c:22,28 – 1991/1117/sys/src/9/port/devmux.c:22,28 (short | long | prev | next) | ||
| 1991/1114 | enum { | |
| 1991/1117 | Nmux = 32, | |
| 1991/1115 | Maxmsg = (32*1024), Flowctl = Maxmsg/2, | |
| 1991/1114 | }; | |
| 1991/1115/sys/src/9/port/devmux.c:50,56 – 1991/1117/sys/src/9/port/devmux.c:50,56 | ||
| 1991/1114 | struct Mux { Ref; | |
| 1991/1115 |
| |
| 1991/1117 | int srv; | |
| 1991/1114 | char name[NAMELEN]; char user[NAMELEN]; ulong perm; | |
| 1991/1115/sys/src/9/port/devmux.c:57,66 – 1991/1117/sys/src/9/port/devmux.c:57,66 | ||
| 1991/1114 | int headopen; Dtq headq; Con connects[Nmux]; | |
| 1991/1117 | Chan *c; | |
| 1991/1114 | }; Mux *muxes; | |
| 1991/1115 | void muxflow(Dtq*); | |
| 1991/1115/sys/src/9/port/devmux.c:87,93 – 1991/1117/sys/src/9/port/devmux.c:87,96 | ||
| 1991/1114 | m = &muxes[s]; if(m->name[0] == '\0') return 0; | |
| 1991/1115 |
| |
| 1991/1117 | if(m->srv) devdir(c, NQID(s, 0), m->name, 0, m->user, m->perm, dp); else devdir(c, DQID(s), m->name, 0, m->user, m->perm, dp); | |
| 1991/1114 | return 1; } | |
| 1991/1115/sys/src/9/port/devmux.c:191,250 – 1991/1117/sys/src/9/port/devmux.c:194,254 | ||
| 1991/1114 | Mux *m; Con *cm, *e; | |
| 1991/1115 | int mux, ok; | |
| 1991/1117 | Chan *new; | |
| 1991/1114 | ||
| 1991/1117 | c = devopen(c, omode, 0, 0, muxgen); | |
| 1991/1114 | if(c->qid.path & CHDIR) | |
| 1991/1117 | return c; | |
| 1991/1114 | ||
| 1991/1115 | mux = NMUX(c); m = &muxes[mux]; | |
| 1991/1117 | lock(m); if(waserror()) { c->flag &= ~COPEN; unlock(m); nexterror(); } if(m->srv) { if(m->c == 0) error(Eshutdown); new = m->c; incref(new); unlock(m); poperror(); close(c); return new; } | |
| 1991/1114 | switch(NCON(c)) { case Qhead: | |
| 1991/1115 |
| |
| 1991/1114 | if(m->headopen) | |
| 1991/1115 |
| |
| 1991/1114 | errors("server channel busy"); | |
| 1991/1115 |
| |
| 1991/1117 | m->headopen = 1; m->ref++; | |
| 1991/1114 | break; case Qclone: if(m->headopen == 0) errors("server shutdown"); | |
| 1991/1117 | if(cm == e) | |
| 1991/1114 | errors("all cannels busy"); | |
| 1991/1115 | cm->ref = 1; | |
| 1991/1114 | m->ref++; | |
| 1991/1115 | c->qid = NQID(mux, (cm-m->connects)+Qoffset); | |
| 1991/1114 | break; default: | |
| 1991/1115 |
| |
| 1991/1114 | cm->ref++; | |
| 1991/1115 | m->ref++; | |
| 1991/1114 | break; } | |
| 1991/1117 | unlock(m); poperror(); | |
| 1991/1114 | return c; } | |
| 1991/1115/sys/src/9/port/devmux.c:266,272 – 1991/1117/sys/src/9/port/devmux.c:270,275 | ||
| 1991/1114 | unlock(m); continue; } | |
| 1991/1115/sys/src/9/port/devmux.c:277,286 – 1991/1117/sys/src/9/port/devmux.c:280,292 | ||
| 1991/1114 | strncpy(m->name, name, NAMELEN); strncpy(m->user, u->p->user, NAMELEN); m->perm = perm&~CHDIR; | |
| 1991/1117 | m->srv = 1; if(perm&CHDIR) m->srv = 0; | |
| 1991/1114 | unlock(m); n = m - muxes; | |
| 1991/1117 | c->qid = (Qid){(CHDIR&perm)|(n+1)<<8, 0}; | |
| 1991/1114 | c->flag |= COPEN; c->mode = omode; } | |
| 1991/1115/sys/src/9/port/devmux.c:289,303 – 1991/1117/sys/src/9/port/devmux.c:295,324 | ||
| 1991/1114 | muxremove(Chan *c) { Mux *m; | |
| 1991/1117 | Chan *srv; | |
| 1991/1114 |
| |
| 1991/1117 | if(c->qid.path == CHDIR) | |
| 1991/1114 | error(Eperm); m = &muxes[NMUX(c)]; | |
| 1991/1117 | if((c->qid.path&CHDIR) == 0 && m->srv == 0) error(Eperm); | |
| 1991/1114 | if(strcmp(u->p->user, m->user) != 0) errors("not owner"); | |
| 1991/1117 | srv = 0; lock(m); if(m->srv) { srv = m->c; m->c = 0; } | |
| 1991/1114 | m->name[0] = '\0'; | |
| 1991/1117 | unlock(m); if(srv) close(srv); muxclose(c); | |
| 1991/1114 | } void | |
| 1991/1115/sys/src/9/port/devmux.c:316,322 – 1991/1117/sys/src/9/port/devmux.c:337,343 | ||
| 1991/1114 | convM2D(db, &d); d.mode &= 0777; | |
| 1991/1117 | if(c->qid.path&CHDIR || m->srv) { | |
| 1991/1114 | strcpy(m->name, d.name); m->perm = d.mode; return; | |
| 1991/1115/sys/src/9/port/devmux.c:345,354 – 1991/1117/sys/src/9/port/devmux.c:366,375 | ||
| 1991/1115 | if(c->qid.path&CHDIR) | |
| 1991/1114 | return; | |
| 1991/1115 |
| |
| 1991/1117 | m = &muxes[NMUX(c)]; if(!(c->flag&COPEN) || m->srv) | |
| 1991/1115 | return; | |
| 1991/1114 |
| |
| 1991/1115/sys/src/9/port/devmux.c:430,446 – 1991/1117/sys/src/9/port/devmux.c:451,476 | ||
| 1991/1114 | { Mux *m; Con *cm; | |
| 1991/1117 | int muxid, fd; | |
| 1991/1114 | Block *f, *bp; | |
| 1991/1115 |
| |
| 1991/1117 | char *a, hdr[3], buf[10]; | |
| 1991/1114 | ||
| 1991/1115 | if(c->qid.path&CHDIR) | |
| 1991/1114 | error(Eisdir); | |
| 1991/1115 |
| |
| 1991/1117 | m = &muxes[NMUX(c)]; if(n > Maxmsg || (m->srv && n >= sizeof(buf))) | |
| 1991/1115 | error(Etoobig); | |
| 1991/1114 |
| |
| 1991/1117 | if(m->srv) { memmove(buf, va, n); /* so we can NUL-terminate */ buf[n] = 0; fd = strtoul(buf, 0, 0); fdtochan(fd, -1, 0); /* error check */ m->c = u->p->fgrp->fd[fd]; incref(m->c); return n; } | |
| 1991/1114 | switch(NCON(c)) { case Qclone: error(Eperm); | |
| 1991/1115/sys/src/9/port/devmux.c:475,481 – 1991/1117/sys/src/9/port/devmux.c:505,511 | ||
| 1991/1115 | ulong l, bwrite; | |
| 1991/1114 | head = 0; | |
| 1991/1117 | tail = 0; | |
| 1991/1114 | if(waserror()) { if(head) freeb(head); | |
| 1991/1115/sys/src/9/port/devmux.c:568,574 – 1991/1117/sys/src/9/port/devmux.c:598,603 | ||
| 1991/1114 | qlock(&q->rd); bp = 0; if(waserror()) { | |
| 1991/1115/sys/src/9/port/devmux.c:575,580 – 1991/1117/sys/src/9/port/devmux.c:604,610 | ||
| 1991/1114 | q->list = bp; } unlock(&q->listlk); | |
| 1991/1117 | qunlock(&q->rd); | |
| 1991/1114 | nexterror(); } | |
| 1991/1115 | while(!havedata(q)) { | |