static int32_t kbinread(Chan *c, void *a, int32_t n, int64_t _) { if(c->qid.type == QTDIR) return devdirread(c, a, n, kbintab, nelem(kbintab), devgen); return 0; }
static long pointerread(Chan* c, void* a, long n, vlong) { Pointer mt; char tmp[128]; int l; switch((ulong)c->qid.path){ case Qdir: return devdirread(c, a, n, pointertab, nelem(pointertab), devgen); case Qpointer: qlock(&mouse.q); if(waserror()) { qunlock(&mouse.q); nexterror(); } mt = mouseconsume(); poperror(); qunlock(&mouse.q); l = sprint(tmp, "m%11d %11d %11d %11lud ", mt.x, mt.y, mt.b, mt.msec); if(l < n) n = l; memmove(a, tmp, n); break; case Qcursor: /* TO DO: interpret data written as Image; give to drawcursor() */ break; default: n=0; break; } return n; }
static int32_t envread(Chan *c, void *a, int32_t n, int64_t off) { Egrp *eg; Evalue *e; int32_t offset; if(c->qid.type & QTDIR) return devdirread(c, a, n, 0, 0, envgen); eg = envgrp(c); rlock(&eg->rwl); e = envlookup(eg, nil, c->qid.path); if(e == 0) { runlock(&eg->rwl); error(Enonexist); } offset = off; if(offset > e->len) /* protects against overflow converting int64_t to long */ n = 0; else if(offset + n > e->len) n = e->len - offset; if(n <= 0) n = 0; else memmove(a, e->value+offset, n); runlock(&eg->rwl); return n; }
static long eiaread(Chan *c, void *buf, long n, vlong offset) { ssize_t cnt; int port = NETID(c->qid.path); if(c->qid.type & QTDIR) return devdirread(c, buf, n, eiadir, ndir, devgen); switch(NETTYPE(c->qid.path)) { case Ndataqid: osenter(); cnt = read(eia[port].fd, buf, n); osleave(); if(cnt == -1) oserror(); return cnt; case Nctlqid: return readnum(offset, buf, n, port, NUMSIZE); case Nstatqid: return rdstat(port, buf, n, offset); } return 0; }
static long regressread(struct chan *c, void *va, long n, int64_t off) { uint64_t w, *bp; char *a, *ea; uintptr_t offset = off; uint64_t pc; int snp_ret, ret = 0; switch((int)c->qid.path){ case Monitordirqid: n = devdirread(c, va, n, regresstab, ARRAY_SIZE(regresstab), devgen); break; case Monitorctlqid: n = readstr(off, va, n, ctlcommands); break; case Monitordataqid: if (regress.monitor) { printd("monitordataqid: regress.monitor %p len %p\n", regress.monitor, qlen(kprof.monitor)); if (qlen(regress.monitor) > 0) n = qread(regress.monitor, va, n); else n = 0; } else error(EFAIL, "no monitor queue"); break; default: n = 0; break; } return n; }
static long wdread(Chan* c, void* a, long n, vlong off) { ulong offset = off; char *p; switch((ulong)c->qid.path){ case Qdir: return devdirread(c, a, n, wddir, nelem(wddir), devgen); case Qwdctl: if(wd == nil || wd->stat == nil) return 0; p = malloc(READSTR); if(p == nil) error(Enomem); if(waserror()){ free(p); nexterror(); } wd->stat(p, p + READSTR); n = readstr(offset, a, n, p); free(p); poperror(); return n; default: error(Egreg); break; } return 0; }
static long eiaread(Chan *c, void *buf, long n, vlong offset) { DWORD cnt; int port = NETID(c->qid.path); BOOL good; if(c->qid.type & QTDIR) return devdirread(c, buf, n, eiadir, ndir, devgen); switch(NETTYPE(c->qid.path)) { case Ndataqid: cnt = 0; // if ReadFile timeouts and cnt==0 then just re-read // this will give osleave() a chance to detect an // interruption (i.e. killprog) while(cnt==0) { osenter(); good = ReadFile(eia[port].comfh, buf, n, &cnt, NULL); SleepEx(0,FALSE); //allow another thread access to port osleave(); if(!good) oserror(); } return cnt; case Nctlqid: return readnum(offset, buf, n, eia[port].id, NUMSIZE); case Nstatqid: return rdstat(port, buf, n, offset); } return 0; }
static size_t ver_read(struct chan *c, void *va, size_t n, off64_t off) { switch ((int) c->qid.path) { case Kverdirqid: return devdirread(c, va, n, vertab, ARRAY_SIZE(vertab), devgen); case Kverbuildid: return read_buildid(va, n, off); case Kverdate: if (build_info_date) return ver_emit_nlstr(va, build_info_date, n, (long) off); break; case Kvercommitid: if (build_info_commitid) return ver_emit_nlstr(va, build_info_commitid, n, (long) off); break; case Kverversion: if (build_info_version) return ver_emit_nlstr(va, build_info_version, n, (long) off); break; case Kverversionname: if (build_info_version_name) return ver_emit_nlstr(va, build_info_version_name, n, (long) off); break; case Kverkconfig: return readstr(off, va, n, __kconfig_str); default: error(EINVAL, ERROR_FIXME); } return 0; }
static long envread(Chan *c, void *a, long n, vlong offset) { Egrp *eg; Evalue *e; if(c->qid.type & QTDIR) return devdirread(c, a, n, 0, 0, envgen); eg = up->env->egrp; qlock(&eg->l); for(e = eg->entries; e != nil; e = e->next) if(e->qid.path == c->qid.path) break; if(e == nil) { qunlock(&eg->l); error(Enonexist); } if(offset > e->len) /* protects against overflow converting vlong to ulong */ n = 0; else if(offset + n > e->len) n = e->len - offset; if(n <= 0) n = 0; else memmove(a, e->val+offset, n); qunlock(&eg->l); return n; }
static long rtcread(Chan *c, void *buf, long n, vlong offset) { ulong t, ot; if(c->qid.type & QTDIR) return devdirread(c, buf, n, rtcdir, NRTC, devgen); switch((ulong)c->qid.path){ case Qrtc: qlock(&rtclock); t = rtctime(); do{ ot = t; t = rtctime(); /* make sure there's no skew */ }while(t != ot); qunlock(&rtclock); n = readnum(offset, buf, n, t, 12); return n; case Qnvram: if(offset > NVREAD) return 0; if(n > NVREAD - offset) n = NVREAD - offset; qlock(&rtclock); memmove(buf, nvr.ram+offset, n); qunlock(&rtclock); return n; } error(Egreg); return 0; /* not reached */ }
static long piperead(struct chan *c, void *va, long n, int64_t ignored) { Pipe *p; p = c->aux; switch (NETTYPE(c->qid.path)) { case Qdir: return devdirread(c, va, n, p->pipedir, ARRAY_SIZE(pipedir), pipegen); case Qdata0: if (c->flag & O_NONBLOCK) return qread_nonblock(p->q[0], va, n); else return qread(p->q[0], va, n); case Qdata1: if (c->flag & O_NONBLOCK) return qread_nonblock(p->q[1], va, n); else return qread(p->q[1], va, n); default: panic("piperead"); } return -1; /* not reached */ }
long netifread(struct netif *nif, struct chan *c, void *a, long n, uint32_t offset) { int i, j; struct netfile *f; char *p; if (c->qid.type & QTDIR) return devdirread(c, a, n, (struct dirtab *)nif, 0, netifgen); switch (NETTYPE(c->qid.path)) { case Ndataqid: f = nif->f[NETID(c->qid.path)]; return qread(f->in, a, n); case Nctlqid: return readnum(offset, a, n, NETID(c->qid.path), NUMSIZE); case Nstatqid: p = kzmalloc(READSTR, 0); if (p == NULL) return 0; j = snprintf(p, READSTR, "in: %d\n", nif->inpackets); j += snprintf(p + j, READSTR - j, "link: %d\n", nif->link); j += snprintf(p + j, READSTR - j, "out: %d\n", nif->outpackets); j += snprintf(p + j, READSTR - j, "crc errs: %d\n", nif->crcs); j += snprintf(p + j, READSTR - j, "overflows: %d\n", nif->overflows); j += snprintf(p + j, READSTR - j, "soft overflows: %d\n", nif->soverflows); j += snprintf(p + j, READSTR - j, "framing errs: %d\n", nif->frames); j += snprintf(p + j, READSTR - j, "buffer errs: %d\n", nif->buffs); j += snprintf(p + j, READSTR - j, "output errs: %d\n", nif->oerrs); j += snprintf(p + j, READSTR - j, "prom: %d\n", nif->prom); j += snprintf(p + j, READSTR - j, "mbps: %d\n", nif->mbps); j += snprintf(p + j, READSTR - j, "addr: "); for (i = 0; i < nif->alen; i++) j += snprintf(p + j, READSTR - j, "%02.2x", nif->addr[i]); snprintf(p + j, READSTR - j, "\n"); n = readstr(offset, a, n, p); kfree(p); return n; case Naddrqid: p = kzmalloc(READSTR, 0); if (p == NULL) return 0; j = 0; for (i = 0; i < nif->alen; i++) j += snprintf(p + j, READSTR - j, "%02.2x", nif->addr[i]); n = readstr(offset, a, n, p); kfree(p); return n; case Ntypeqid: f = nif->f[NETID(c->qid.path)]; return readnum(offset, a, n, f->type, NUMSIZE); case Nifstatqid: return 0; } error(Ebadarg); return -1; /* not reached */ }
static long envread(Chan *c, void *a, long n, vlong off) { Egrp *eg; Evalue *e; ulong offset = off; if(c->qid.type & QTDIR) return devdirread(c, a, n, 0, 0, envgen); eg = envgrp(c); rlock(eg); if(waserror()){ runlock(eg); nexterror(); } e = envlookup(eg, nil, c->qid.path); if(e == nil) error(Enonexist); if(offset >= e->len || e->value == nil) n = 0; else if(offset + n > e->len) n = e->len - offset; if(n <= 0) n = 0; else memmove(a, e->value+offset, n); runlock(eg); poperror(); return n; }
static long dupread(Chan *c, void *va, long n, vlong offset) { char *a = va; char buf[256]; int fd, twicefd; if(c->qid.type == QTDIR) return devdirread(c, a, n, nil, 0, dupgen); twicefd = c->qid.path - 1; fd = twicefd/2; if(twicefd & 1){ c = fdtochan(up->env->fgrp, fd, -1, 0, 1); if(waserror()){ cclose(c); nexterror(); } progfdprint(c, fd, 0, buf, sizeof buf); poperror(); cclose(c); return readstr((ulong)offset, va, n, buf); } panic("dupread"); return 0; }
static long flashread(Chan *c, void *buf, long n, vlong offset) { Flash *f; char *s, *o; Flashpart *fp; Flashregion *r; int i; ulong start, end; if(c->qid.type & QTDIR) return devdirread(c, buf, n, nil, 0, flashgen); f = flash.card[c->dev]; fp = &f->part[PART(c->qid.path)]; if(fp->name == nil) error(Egreg); switch(TYPE(c->qid.path)){ case Qdata: offset += fp->start; if(offset >= fp->end) return 0; if(offset+n > fp->end) n = fp->end - offset; n = readflash(f, buf, offset, n); if(n < 0) error(Eio); return n; case Qctl: s = malloc(READSTR); if(waserror()){ free(s); nexterror(); } o = seprint(s, s+READSTR, "%#2.2ux %#4.4ux %d %q\n", f->id, f->devid, f->width, f->sort!=nil? f->sort: "nor"); for(i=0; i<f->nr; i++){ r = &f->regions[i]; if(r->start < fp->end && fp->start < r->end){ start = r->start; if(fp->start > start) start = fp->start; end = r->end; if(fp->end < end) end = fp->end; o = seprint(o, s+READSTR, "%#8.8lux %#8.8lux %#8.8lux", start, end, r->erasesize); if(r->pagesize) o = seprint(o, s+READSTR, " %#8.8lux", r->pagesize); o = seprint(o, s+READSTR, "\n"); } } n = readstr(offset, buf, n, s); poperror(); free(s); return n; } error(Egreg); return 0; /* not reached */ }
static long audioread(Chan *c, void *a, long n, vlong off) { Audiochan *ac; Audio *adev; long (*fn)(Audio *, void *, long, vlong); ac = c->aux; adev = ac->adev; fn = nil; switch((ulong)c->qid.path){ case Qdir: audiodir[Qaudio].length = adev->buffered ? adev->buffered(adev) : 0; return devdirread(c, a, n, audiodir, nelem(audiodir), devgen); case Qaudio: fn = adev->read; break; case Qaudiostat: fn = adev->status; break; case Qvolume: fn = adev->volread; break; } if(fn == nil) error(Egreg); eqlock(ac); if(waserror()){ qunlock(ac); nexterror(); } switch((ulong)c->qid.path){ case Qaudiostat: case Qvolume: /* generate the text on first read */ if(ac->data == nil || off == 0){ long l; ac->data = nil; l = fn(adev, ac->buf, sizeof(ac->buf)-1, 0); if(l < 0) l = 0; ac->buf[l] = 0; ac->data = ac->buf; } /* then serve all requests from buffer */ n = readstr(off, a, n, ac->data); break; default: n = fn(adev, a, n, off); } qunlock(ac); poperror(); return n; }
static long dsoread(Chan *c, void *a, long n, vlong offset) { MyFiles *f; char* s; if(c->qid.type == QTDIR) return devdirread(c, a, n, dsotab, nfichtab+2, devgen); if(c->qid.path == Qdata){ //s = usage(); // Antes en lugar de los comando, mostraba la ayuda s = getComandos(); return readstr(offset, a, n, s); } f = getMyFile(c); if(!f->valido || checkFiles(f) && (f->type != Qmir)){ f->valido = 0; print("Fichero corrupto: %s\n",f->name); } // Se mantienen los cierres comentados // para indicar donde deben ir si fuesen necesarios if(!checkCorruptos(f)){ //qlock(&f->lock); switch(f->type){ case Qcat: n = dsoconcatread(f, a, n, offset); break; case Qpar: n = dsopartread(f, a, n, offset); break; case Qmir: n = dsomirrorread(f, a, n,offset); break; case Qilv: n = dsointerlread(f, a, n, offset); break; default: print("BUG: f->type desconocido\n"); n = 0; } //qunlock(&f->lock); }else{ f->valido = 0; print("Imposible leer de %s\n",f->name); return 0; } return n; }
static int32_t srvread(Chan *c, void *va, int32_t n, int64_t m) { int32_t r; isdir(c); qlock(&srvlk); r = devdirread(c, va, n, 0, 0, srvgen); qunlock(&srvlk); return r; }
static long capread(struct chan *c, void *va, long n, int64_t m) { switch ((uint32_t)c->qid.path) { case Qdir: return devdirread(c, va, n, capdir, ncapdir, devgen); default: error(EPERM, "Permission denied: can't read capability files"); break; } return n; }
static long floppyread(Chan *c, void *a, long n, vlong off) { FDrive *dp; long rv; int sec, head, cyl; long len; uchar *aa; ulong offset = off; if(c->qid.type & QTDIR) return devdirread(c, a, n, floppydir, 1+fl.ndrive*NFDIR, devgen); rv = 0; dp = &fl.d[c->qid.path & ~Qmask]; switch ((int)(c->qid.path & Qmask)) { case Qdata: islegal(offset, n, dp); aa = a; qlock(&fl); if(waserror()){ qunlock(&fl); nexterror(); } floppyon(dp); changed(c, dp); for(rv = 0; rv < n; rv += len){ /* * all xfers come out of the track cache */ dp->len = n - rv; floppypos(dp, offset+rv); cyl = dp->tcyl; head = dp->thead; len = dp->len; sec = dp->tsec; if(readtrack(dp, cyl, head) < 0) break; memmove(aa+rv, dp->cache + (sec-1)*dp->t->bytes, len); } qunlock(&fl); poperror(); break; case Qctl: return readstr(offset, a, n, dp->t->name); default: panic("floppyread: bad qid"); } return rv; }
static int32_t corebootread(Chan *c, void *va, int32_t n, int64_t off) { switch((uint32_t)c->qid.path){ case Qdir: return devdirread(c, va, n, corebootdir, nelem(corebootdir), corebootdevgen); case Qtable: /* todo: do something */ break; } return 0; }
static long devlogfsread(Chan *c, void *buf, long n, vlong off) { int instance, qid, qt; SPLITPATH(c->qid.path, c->qid.type, instance, qid, qt); USED(instance); #ifdef CALLTRACE print("devlogfsread(c = 0x%.8lux, buf = 0x%.8lux, n = %ld, instance = %d, qid = %d, qt = %d) - start\n", (ulong)c, (ulong)buf, n, instance, qid, qt); #endif if(qt & QTDIR) { #ifdef CALLTRACE print("devlogfsread(c = 0x%.8lux, buf = 0x%.8lux, n = %ld, instance = %d, qid = %d, qt = %d) - calling devdirread\n", (ulong)c, (ulong)buf, n, instance, qid, qt); #endif return devdirread(c, buf, n, 0, 0, devlogfsgen); } if(DATAQID(qid, qt)) { if (qid == Qfsboot) { Devlogfs *l = c->aux; qlock(&l->bootqlock); if (waserror()) { qunlock(&l->bootqlock); nexterror(); } smartio((SMARTIOFN *)logfsbootio, l->lb, buf, n, off, logfsbootgetiosize(l->lb), 0); poperror(); qunlock(&l->bootqlock); return n; } else if (qid == Qfs) { Devlogfs *d = c->aux; return lfsrvread(d, buf, n); } error(Eio); } if (qid == Qusers) { long nr; errorany(logfsisusersread(is, buf, n, (ulong)off, &nr)); return nr; } else if (qid == Qdump) return devlogfsdumpread(buf, n); if (qid != Qctl) error(Egreg); return 0; }
static int32_t capread(Chan *c, void *va, int32_t n, int64_t m) { switch((uint32_t)c->qid.path) { case Qdir: return devdirread(c, va, n, capdir, ncapdir, devgen); default: error(Eperm); break; } return n; }
static long capread(Chan *c, void *va, long n, vlong vl) { switch((ulong)c->qid.path){ case Qdir: return devdirread(c, va, n, capdir, ncapdir, devgen); default: error(Eperm); break; } return n; }
static long rtcread(Chan *c, void *a, long n, vlong offset) { if(c->qid.type & QTDIR) return devdirread(c, a, n, rtcdir, nelem(rtcdir), devgen); switch((ulong)c->qid.path){ case Qrtc: return readnum((ulong)offset, a, n, rtcsecs, 12); } error(Ebadarg); return 0; }
static long cmdread(Chan *ch, void *a, long n, vlong offset) { Conv *c; char *p, *cmds; int fd; USED(offset); p = a; switch(TYPE(ch->qid)) { default: error(Eperm); case Qcmd: case Qtopdir: case Qconvdir: return devdirread(ch, a, n, 0, 0, cmdgen); case Qctl: sprint(up->genbuf, "%ld", CONV(ch->qid)); return readstr(offset, p, n, up->genbuf); case Qstatus: c = cmd.conv[CONV(ch->qid)]; cmds = ""; if(c->cmd != nil) cmds = c->cmd->f[1]; snprint(up->genbuf, sizeof(up->genbuf), "cmd/%d %d %s %q %q\n", c->x, c->inuse, c->state, c->dir, cmds); return readstr(offset, p, n, up->genbuf); case Qdata: case Qstderr: fd = 1; if(TYPE(ch->qid) == Qstderr) fd = 2; c = cmd.conv[CONV(ch->qid)]; qlock(&c->l); if(c->fd[fd] == -1){ qunlock(&c->l); return 0; } qunlock(&c->l); osenter(); n = read(c->fd[fd], a, n); osleave(); if(n < 0) oserror(); return n; case Qwait: c = cmd.conv[CONV(ch->qid)]; return qread(c->waitq, a, n); } }
static int32_t pmcread(Chan *c, void *a, int32_t n, int64_t offset) { Proc *up = externup(); uint32_t type, id; PmcCtl p; char *s; uint64_t v; uint64_t coreno; type = PMCTYPE(c->qid.path); id = PMCID(c->qid.path); switch(type){ case Qcore: case Qdir: case Qctr: return devdirread(c, a, n, nil, 0, pmcgen); } s = malloc(PmcCtlRdStr); if(waserror()){ free(s); nexterror(); } coreno = (uint64_t)c->aux; p._coreno = coreno; switch(type){ case Qdata: v = pmcgetctr(coreno, id); snprint(s, PmcCtlRdStr, "%#ullx", v); break; case Qctl: if (pmcgetctl(coreno, &p, id) < 0) error("bad ctr"); if (pmcctlstr(s, PmcCtlRdStr, &p) < 0) error("bad pmc"); break; case Qgctl: if (pmcdescstr(s, PmcCtlRdStr) < 0) error("bad pmc"); break; default: error(Eperm); } n = readstr(offset, a, n, s); free(s); poperror(); return n; }
long ipread(Chan *ch, void *a, long n, vlong offset) { int r; Conv *c; Proto *x; uchar ip[4]; char buf[128], *p; /*print("ipread %s %lux\n", c2name(ch), (long)ch->qid.path);*/ p = a; switch(TYPE(ch->qid)) { default: error(Eperm); case Qcs: return csread(ch, a, n, offset); case Qprotodir: case Qtopdir: case Qconvdir: return devdirread(ch, a, n, 0, 0, ipgen); case Qctl: sprint(buf, "%d", CONV(ch->qid)); return readstr(offset, p, n, buf); case Qremote: c = proto[PROTO(ch->qid)].conv[CONV(ch->qid)]; hnputl(ip, c->raddr); sprint(buf, "%I!%d\n", ip, c->rport); return readstr(offset, p, n, buf); case Qlocal: c = proto[PROTO(ch->qid)].conv[CONV(ch->qid)]; hnputl(ip, c->laddr); sprint(buf, "%I!%d\n", ip, c->lport); return readstr(offset, p, n, buf); case Qstatus: x = &proto[PROTO(ch->qid)]; c = x->conv[CONV(ch->qid)]; sprint(buf, "%s/%d %d %s \n", c->p->name, c->x, c->r.ref, c->state); return readstr(offset, p, n, buf); case Qdata: c = proto[PROTO(ch->qid)].conv[CONV(ch->qid)]; r = so_recv(c->sfd, a, n, 0); if(r < 0){ oserrstr(); nexterror(); } return r; } }
static int32_t vconread(Chan *c, void *va, int32_t n, int64_t offset) { int vdidx = DEV(c->qid); if(vdidx >= nvcon) error(Ebadarg); switch(TYPE(c->qid)) { case Qtopdir: case Qvirtcon: return devdirread(c, va, n, (Dirtab *)0, 0L, vcongen); case Qvcpipe: return rwcommon(vcons[vdidx], va, n, 0); } return -1; }
static long dlread(Chan *c, void *a, long n, vlong voffset) { switch((ulong)c->qid.path){ case Qdir: return devdirread(c, a, n, dltab, nelem(dltab), devgen); case Qdynld: return readdl(a, n, (ulong)voffset); case Qdynsyms: return readsyms(a, n, (ulong)voffset); default: error(Egreg); } return n; }