#include "dat.h" #include "fns.h" static NodeTable nodes; static QLock id_lock; static uvlong get_next_id(void) { static uvlong id = 0; uvlong next; qlock(&id_lock); next = ++id; qunlock(&id_lock); return next; } Aux* create_aux(FileType t) { Aux* self = (Aux*)malloc(sizeof(Aux)); self->type = t; self->data = nil; self->count = 0; return self; } void fs_destroy_file(File* f) { Aux* a = (Aux*)f->aux; if(a && a->data) { free(a->data); } if (a) { free (a); } } void kuro_read(Req* r) { Aux* a = (Aux*)r->fid->file->aux; switch (a->type) { case CTL: default: respond(r, nil); break; } } void new_window(char* filename, int new) { int rw_fd[2]; char client_fd[32] = {0}; char client_id[32] = {0}; uvlong id; NodeRef* noderef; pipe(rw_fd); id = get_next_id(); noderef = (NodeRef*)malloc(sizeof(NodeRef)); noderef->id = id; noderef->fd[0] = rw_fd[0]; noderef->fd[1] = rw_fd[1]; nodetbl_add(&nodes, noderef); sprintf(client_fd, "%d", rw_fd[1]); sprintf(client_id, "%d", id); rfork(RFNAMEG); char* a[] = { "kuro", "-p", client_fd, "-i", client_id, new ? "-n" : filename, new ? filename : 0, 0 }; exec("./kuro", a); } void newwindowthread(void* arg) { char* filename = (char*)arg; new_window(filename, 1); } void write_ctl(Req* r) { char cmd[16] = {0}; char* c = r->ifcall.data; int i; for (i = 0; i < r->ifcall.count && *c != ' ' && *c != '\n'; i++) { strncat(cmd, c, 1); c++; } if (*c == ' ') { c++; } /* maybe don't do this... */ strcsw(c, '\n', 0); /* diagnostics for now */ print("cmd: %s\n", cmd); print("arg: %s\n", c); if (strequ(cmd, "new")) { threadcreate(newwindowthread, c, 256); respond(r, nil); } else { print("unknown command...\n"); respond(r, nil); } } void kuro_write(Req* r) { Aux* a = (Aux*)r->fid->file->aux; switch (a->type) { case CTL: write_ctl(r); break; default: respond(r, nil); break; } } char* mk_mtpt(char* parent, char* buf) { int pid = getpid(); sprintf(buf, "%s/%d", parent, pid); return buf; } void start_9p() { char* mtpt_base = getenv("KURO_MTPT"); if (mtpt_base) { char mtpt[256] = "TESTING LIKE THIS SHOULD NOT BE NECESSARY; AYEYEYEYEYE"; mk_mtpt(mtpt_base, mtpt); int i = ensure(mtpt); print("%d result of ensure\n", i); print("%s\n", mtpt); Srv srv = { .read = kuro_read, .write = kuro_write }; Tree* tree = alloctree(nil, nil, DMDIR | 0777, fs_destroy_file); srv.tree = tree; closefile(createfile(tree->root, "ctl", nil, DMAPPEND | 0600, create_aux(CTL))); closefile(tree->root); /* TODO: figure out how to kill the server cleanly so we don't need MREPL */ threadpostmountsrv(&srv, nil, mtpt, MREPL | MCREATE); threadexits(0); } }