stew

a monorepo of some sort
git clone git://git.nsmpr.xyz/stew.git
Log | Files | Refs

fs.c (2888B)


      1 #include <u.h>
      2 #include <libc.h>
      3 #include <fcall.h>
      4 #include <thread.h>
      5 #include <9p.h>
      6 
      7 #include <btr.h>
      8 
      9 typedef struct Snek Snek;
     10 struct Snek {
     11 	void *aux;
     12 	Snek* next;
     13 };
     14 
     15 Snek *head, *tail;
     16 
     17 
     18 typedef struct Cell Cell;
     19 struct Cell {
     20 	int type;
     21 	long n;
     22 	char *p;
     23 };
     24 
     25 char *mkmsg(int op, vlong id, long nbytes, vlong offset, char *data);
     26 void pushmsg(char *msg);
     27 char *pullmsg(void);
     28 void msgerror(vlong id, char *str);
     29 
     30 /*
     31    Cell's type can be:
     32    - Atom
     33      arbitrary length bytestring
     34    - NULL
     35      technically equivalent to Atom of length 0
     36    - Pair
     37    required opeartions:
     38    - fetch (id -> Cell *)
     39    - store (id, Cell * -> _ )
     40 */
     41 
     42 Cell *
     43 fetch(long id)
     44 {
     45 	return nil;
     46 }
     47 
     48 void
     49 store(long id, Cell *c)
     50 {
     51 }
     52 
     53 void
     54 usage(void)
     55 {
     56 	fprint(2, "usage: %s\n", argv0);
     57 	exits("usage");
     58 }
     59 
     60 void
     61 fs_write(Req *r)
     62 {
     63 	Btrmsgheader *m;
     64 	if (r->ifcall.count < sizeof(Btrmsgheader)) {
     65 		// msg too short, provide BTerror
     66 		msgerror(0, smprint("msg too short"));
     67 		r->ofcall.count = r->ifcall.count;
     68 		respond(r, nil);
     69 		return;
     70 	}
     71 	m = (Btrmsgheader *)r->ifcall.data;
     72 	switch (m->op) {
     73 	case BTstat:
     74 		// provide BRstat
     75 		msgerror(m->id, smprint("BTstat not implemented yet"));
     76 		r->ofcall.count = r->ifcall.count;
     77 		break;
     78 	default:
     79 		// unexpected op, provide BTerror
     80 		msgerror(m->id, smprint("unknown op %X", m->op));
     81 		r->ofcall.count = r->ifcall.count;
     82 	}
     83 	respond(r, nil);
     84 }
     85 
     86 void
     87 fs_read(Req *r)
     88 {
     89 	char *msg = pullmsg();
     90 	if (msg == nil) {
     91 		// TODO: should block instead of returning read of 0 length, probably?
     92 		respond(r, nil);
     93 		return;
     94 	}
     95 	Btrmsgheader *mh = (Btrmsgheader *)msg;
     96 	long count = mh->nbytes + sizeof(Btrmsgheader);
     97 	if (count > r->ifcall.count) {
     98 		// TODO: this should be an error, probably?
     99 		count = r->ifcall.count;
    100 	}
    101 	memcpy(r->ofcall.data, msg, count);
    102 	r->ofcall.count = count;
    103 	respond(r, nil);
    104 }
    105 
    106 void
    107 main(int argc, char **argv)
    108 {
    109 	ARGBEGIN{
    110 	default:
    111 		usage();
    112 	} ARGEND
    113 	if (argc > 0) usage();
    114 	Srv btrsrv = {
    115 		.read = fs_read,
    116 		.write = fs_write,
    117 	};
    118 	btrsrv.tree = alloctree("btr", "btr", DMDIR|0555, nil);
    119 	File *data = createfile(btrsrv.tree->root, "data", "btr", DMAPPEND|0666, nil);
    120 	postmountsrv(&btrsrv, "btr", "/mnt/btr", MREPL);
    121 }
    122 
    123 char *
    124 mkmsg(int op, vlong id, long nbytes, vlong offset, char *data)
    125 {
    126 	Btrmsgheader mh = {
    127 		.op = op, .id = id, .nbytes = nbytes, .offset = offset,
    128 	};
    129 	char *msg = malloc(sizeof(Btrmsgheader) + nbytes);
    130 	memcpy(msg, &mh, sizeof(Btrmsgheader));
    131 	memcpy(msg + sizeof(Btrmsgheader), data, nbytes);
    132 	return msg;
    133 }
    134 
    135 void
    136 pushmsg(char *msg)
    137 {
    138 	Snek *next = mallocz(sizeof(Snek), 1);
    139 	next->aux = msg;
    140 	if (head != nil) head->next = next;
    141 	else tail = next;
    142 	head = next;
    143 }
    144 
    145 char *
    146 pullmsg(void)
    147 {
    148 	if (tail == nil) return nil;
    149 	char *msg = tail->aux;
    150 	tail = tail->next;
    151 	if (tail == nil) head = nil;
    152 	return msg;
    153 }
    154 
    155 void
    156 msgerror(vlong id, char *str)
    157 {
    158 	pushmsg(mkmsg(BRerror, id, strlen(str), 0, str));
    159 }