#include "dat.h" #include "fns.h" #include "error.h" typedef struct Buffile Buffile; struct Buffile { uchar *p; int s; int e; }; enum { Qdir, Qbuffile, }; Dirtab bufdir[] = { ".", {Qdir,0,QTDIR}, 0, DMDIR|0500, "new", {Qbuffile}, 0, 0660, }; static Buffile* buffilealloc(uchar *p, int n) { Buffile *b; b = malloc(sizeof b[0]+n); b->p = (uchar*)b+sizeof b[0]; memmove(b->p, p, n); b->s = 0; b->e = n; return b; } static Chan* bufattach(char *spec) { return devattach('β', spec); } static Walkqid* bufwalk(Chan *c, Chan *nc, char **name, int nname) { return devwalk(c, nc, name, nname, bufdir, nelem(bufdir), devgen); } static int bufstat(Chan *c, uchar *db, int n) { return devstat(c, db, n, bufdir, nelem(bufdir), devgen); } static Chan* bufopen(Chan *c, int omode) { return devopen(c, omode, bufdir, nelem(bufdir), devgen); } static void bufclose(Chan *c) { free(c->aux); c->aux = nil; } static long bufread(Chan *c, void *va, long n, vlong off) { Buffile *b; int have; if(c->qid.type == QTDIR) return devdirread(c, va, n, bufdir, nelem(bufdir), devgen); b = c->aux; if(b == nil) return 0; USED(off); have = b->e - b->s; if(have < n || n < 0) n = have; memmove(va, b->p, n); b->s += n; return n; } static long bufwrite(Chan *c, void *va, long n, vlong off) { if(c->qid.type == QTDIR) error(Eisdir); free(c->aux); c->aux = buffilealloc(va, n); return n; } Dev bufdevtab = { 'β', "buf", devinit, bufattach, bufwalk, bufstat, bufopen, devcreate, bufclose, bufread, devbread, bufwrite, devbwrite, devremove, devwstat, };