/* fs example. Does it get any better ? */
#include <u.h>
#include <libc.h>
#include <mp.h>
#include <fcall.h>
#include <thread.h>
#include <9p.h>
typedef struct FibState {
mpint *current;
mpint *last;
}FibState;
Tree *fibtree;
static void freefibstate(FibState *state)
{
mpfree(state->last);
mpfree(state->current);
free(state);
}
static FibState*
allocfibstate(void)
{
FibState *new;
new = emalloc9p(sizeof *new);
new->current = itomp(1,nil);
new->last = itomp(0,nil);
if(new->current == nil || new->last == nil) {
freefibstate(new);
new = nil;
}
return new;
}
static u32int
nextfib(FibState *state,char *buf,u32int maxlen)
{
int len;
mpint* next = mpnew(96);
if(next == nil)
return 0;
mptoa(state->current,10,buf,maxlen -1);
mpadd(state->current,state->last,next);
mpfree(state->last);
state->last = state->current;
state->current = next;
len = strlen(buf);
buf[len] = '\n';
return len + 1;
}
static void
fibread(Req *r)
{
if(r->ifcall.count < 2) {
respond(r,"Insufficient space");
return;
}
if(r->fid->aux == nil)
r->fid->aux = allocfibstate();
if(r->fid->aux == nil) {
respond(r,"Out of memory");
return;
}
r->ofcall.count = nextfib(r->fid->aux,r->ofcall.data,r->ifcall.count);
respond(r,nil);
}
static void
fibdestroyfid(Fid *f)
{
FibState *state = f->aux;
if(state)
freefibstate(state);
}
Srv fs = {
.read = fibread,
.destroyfid = fibdestroyfid
};
static void usage(void)
{
fprint(2,"usage: fibfs [-D] [-m mntpt]\n");
exits("usage");
}
void
main(int argc,char *argv[])
{
char *mntpt = ".";
ARGBEGIN{
case 'D':
chatty9p++;
break;
case 'm':
mntpt = EARGF(usage());
break;
}ARGEND;
fs.tree = fibtree = alloctree("none","none",DMDIR|0555,nil);
closefile(createfile(fibtree->root,"fibs","none",0444,nil));
postmountsrv(&fs,nil,mntpt,MAFTER);
exits(nil);
}
/*yes.*/
|