ref: 94cb585132563082a7db68d7a61bb59e885c5b20
parent: 8b24f795e2bb2a5d169641ed0fda0e99b69e4466
author: halfwit <michaelmisch1985@gmail.com>
date: Sun Dec 28 19:40:37 EST 2025
Update to get much more of a robust runtime
--- a/TODO
+++ b/TODO
@@ -5,6 +5,8 @@
- [ ] Use ScreenCaptureKit to get at the video/audio. Handle resizes the other direction
- [ ] gui-wl cannibalize the wayland shims
- [ ] define the gui interface
+ - [ ] drawinit - initialization
+ - [ ] drawrun(p) - capture for a specific process, ran in `os`/`devcmd`
- [ ] Fully fledged note handling
- [x] up->parent integration into /proc
- [ ] Un-stub stub.c things
--- a/kern/Makefile
+++ b/kern/Makefile
@@ -13,6 +13,7 @@
devcap.$O\
devcmd.$O\
devcons.$O\
+ devdup.$O\
devenv.$O\
devfs-$(OS).$O\
devlfd-$(OS).$O\
@@ -22,6 +23,7 @@
devpipe.$O\
devproc.$O\
devroot.$O\
+ devsrv.$O\
devssl.$O\
devtab.$O\
devtls.$O\
--- a/kern/dat.h
+++ b/kern/dat.h
@@ -186,6 +186,7 @@
Chan* mchan; /* channel to mounted server */
Qid mqid; /* qid of root of mount point */
Path* path;
+ char *srvname;
};
struct Path
--- a/kern/devcmd.c
+++ b/kern/devcmd.c
@@ -655,6 +655,13 @@
iprint("XXX %s\n", up->errstr);oscmdkill(t);
}
+
+ // TODO: t holds pid
+ // TODO: Spin up kbd/mouse/screen
+ //attachscreen(t);
+ //attachkbd(t)
+ //attachmouse(t);
+
n = oscmdwait(t, status, sizeof(status));
if(n < 0){oserrstr();
@@ -673,6 +680,7 @@
qproduce(c->waitq, status, n);
}else
closeconv(c);
+ // TODO: Spin down kbd/mouse/screen
qunlock(&c->l);
pexit("", 0);}
--- /dev/null
+++ b/kern/devdup.c
@@ -1,0 +1,143 @@
+#include "u.h"
+#include "lib.h"
+#include "dat.h"
+#include "fns.h"
+#include "error.h"
+
+/* Qid is (2*fd + (file is ctl))+1 */
+
+static int
+dupgen(Chan *c, char *, Dirtab*, int, int s, Dir *dp)
+{+ Fgrp *fgrp = up->fgrp;
+ Chan *f;
+ static int perm[] = { 0400, 0200, 0600, 0 };+ int p;
+ Qid q;
+
+ if(s == DEVDOTDOT){+ devdir(c, c->qid, ".", 0, eve, 0555, dp);
+ return 1;
+ }
+ if(s == 0)
+ return 0;
+ s--;
+ if(s/2 > fgrp->maxfd)
+ return -1;
+ if((f=fgrp->fd[s/2]) == nil)
+ return 0;
+ if(s & 1){+ p = 0400;
+ sprint(up->genbuf, "%dctl", s/2);
+ }else{+ p = perm[f->mode&3];
+ sprint(up->genbuf, "%d", s/2);
+ }
+ mkqid(&q, s+1, 0, QTFILE);
+ devdir(c, q, up->genbuf, 0, eve, p, dp);
+ return 1;
+}
+
+static Chan*
+dupattach(char *spec)
+{+ return devattach('d', spec);+}
+
+static Walkqid*
+dupwalk(Chan *c, Chan *nc, char **name, int nname)
+{+ return devwalk(c, nc, name, nname, (Dirtab *)0, 0, dupgen);
+}
+
+static int
+dupstat(Chan *c, uchar *db, int n)
+{+ return devstat(c, db, n, (Dirtab *)0, 0L, dupgen);
+}
+
+static Chan*
+dupopen(Chan *c, int omode)
+{+ Chan *f;
+ int fd, twicefd;
+
+ if(omode & ORCLOSE)
+ error(Eperm);
+ if(c->qid.type & QTDIR){+ if(omode != 0)
+ error(Eisdir);
+ c->mode = 0;
+ c->flag |= COPEN;
+ c->offset = 0;
+ return c;
+ }
+ if(c->qid.type & QTAUTH)
+ error(Eperm);
+ twicefd = c->qid.path - 1;
+ fd = twicefd/2;
+ if((twicefd & 1)){+ /* ctl file */
+ f = c;
+ f->mode = openmode(omode);
+ f->flag |= COPEN;
+ f->offset = 0;
+ }else{+ /* fd file */
+ f = fdtochan(fd, openmode(omode), 0, 1);
+ cclose(c);
+ }
+ return f;
+}
+
+static void
+dupclose(Chan*)
+{+}
+
+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, (Dirtab *)0, 0L, dupgen);
+ twicefd = c->qid.path - 1;
+ fd = twicefd/2;
+ if(twicefd & 1){+ c = fdtochan(fd, -1, 0, 1);
+ procfdprint(c, fd, buf, sizeof buf);
+ cclose(c);
+ return readstr((ulong)offset, va, n, buf);
+ }
+ panic("dupread");+}
+
+static long
+dupwrite(Chan*, void*, long, vlong)
+{+ error(Eperm);
+}
+
+Dev dupdevtab = {+ 'd',
+ "dup",
+
+ devreset,
+ devinit,
+ devshutdown,
+ dupattach,
+ dupwalk,
+ dupstat,
+ dupopen,
+ devcreate,
+ dupclose,
+ dupread,
+ devbread,
+ dupwrite,
+ devbwrite,
+ devremove,
+ devwstat,
+};
\ No newline at end of file
--- a/kern/devenv.c
+++ b/kern/devenv.c
@@ -366,6 +366,21 @@
wunlock(&eg->lk);
}
+/*
+ * to let the kernel set environment variables
+ */
+void
+ksetenv(char *ename, char *eval, int conf)
+{+ Chan *c;
+ char buf[2*KNAMELEN];
+
+ snprint(buf, sizeof(buf), "#e%s/%s", conf?"c":"", ename);
+ c = namec(buf, Acreate, OWRITE, 0666);
+ devtab[c->type]->write(c, eval, strlen(eval), 0);
+ cclose(c);
+}
+
void
envcpy(Egrp *to, Egrp *from)
{--- a/kern/devroot.c
+++ b/kern/devroot.c
@@ -10,10 +10,13 @@
Qboot = 0x1000,
Qmnt = 0x2000,
Qfactotum,
+ Qroot,
+ Qcpu,
+ Qterm,
Nrootfiles = 32,
Nbootfiles = 32,
- Nmntfiles = 2,
+ Nmntfiles = 5,
};
typedef struct Dirlist Dirlist;
@@ -58,6 +61,9 @@
static Dirtab mntdir[Nmntfiles] = { "mnt", {Qmnt, 0, QTDIR}, 0, DMDIR|0555, "factotum", {Qfactotum, 0, QTDIR}, 0, DMDIR|0555,+ "root", {Qroot, 0, QTDIR}, 0, DMDIR|0555,+ "cpu", {Qcpu, 0, QTDIR}, 0, DMDIR|0555,+ "term", {Qterm, 0, QTDIR}, 0, DMDIR|0555,};
static Dirlist mntlist =
{@@ -64,7 +70,7 @@
Qmnt,
mntdir,
mntdata,
- 2,
+ 5,
Nmntfiles
};
@@ -111,17 +117,19 @@
static void
rootreset(void)
{- addrootdir("arm"); addrootdir("bin"); addrootdir("dev"); addrootdir("env"); addrootdir("fd");- addrootdir("rc");+ addrootdir("mnt");+ addrootdir("n"); addrootdir("net"); addrootdir("net.alt"); addrootdir("proc"); addrootdir("root"); addrootdir("srv");+ addrootdir("shr");+ addrootdir("tmp");}
static Chan*
--- /dev/null
+++ b/kern/devsrv.c
@@ -1,0 +1,685 @@
+#include "u.h"
+#include "lib.h"
+#include "dat.h"
+#include "fns.h"
+#include "error.h"
+
+#define SRVTYPE(x) (((uint)x)&0x3)
+#define SRVPATH(x) (((uvlong)x)>>2)
+#define SRVQID(x, t) ((((uvlong)x)<<2)|((t)&0x3))
+
+typedef struct Link Link;
+struct Link
+{+ void *link;
+ char *name;
+ char *owner;
+ ulong perm;
+ ulong path;
+};
+
+typedef struct Srv Srv;
+struct Srv
+{+ Link ln;
+ Chan *chan;
+};
+
+typedef struct Board Board;
+struct Board
+{+ Link ln;
+ Ref rf;
+
+ int closed;
+ Srv *srv;
+
+ /* tree linkage */
+ Board *parent;
+ Board *child;
+
+ /* all boards list */
+ Board *prev;
+ Board *next;
+};
+
+enum{+ Qsrv,
+ Qclone,
+ Qlease,
+};
+
+static char clone[] = "clone";
+
+static RWLock srvlk;
+static ulong srvpath;
+static Board srvroot;
+
+static void*
+lookup(Link *l, char *name, ulong qidpath)
+{+ Link *lp;
+
+ if(qidpath != ~0UL){+ qidpath = SRVPATH(qidpath);
+ }
+ for(lp = l; lp != nil; lp = lp->link){+ if(qidpath != ~0UL && lp->path == qidpath)
+ return lp;
+ if(name != nil && strcmp(lp->name, name) == 0)
+ return lp;
+ }
+ return nil;
+}
+
+static void*
+bremove(Link **l, char *name, ulong qidpath)
+{+ Link *lp;
+ Link **last;
+
+ if(qidpath != ~0UL){+ assert(SRVTYPE(qidpath) == Qsrv);
+ qidpath = SRVPATH(qidpath);
+ }
+ last = l;
+ for(lp = *l; lp != nil; lp = lp->link){+ if(qidpath != ~0UL && lp->path == qidpath)
+ break;
+ if(name != nil && strcmp(lp->name, name) == 0)
+ break;
+ last = &lp->link;
+ }
+ if(lp == nil)
+ return nil;
+
+ *last = lp->link;
+ lp->link = nil;
+ return lp;
+}
+
+static void
+freelink(Link *l)
+{+ free(l->name);
+ free(l->owner);
+ free(l);
+}
+
+/* always called with srvlock wlock'ed */
+static void
+boardclunk(Board *b)
+{+ Board *ch;
+
+ /* srvroot is not ref-counted nor clunkable */
+ if(b == &srvroot)
+ return;
+
+ if(decref(b))
+ return;
+
+ /*
+ * All boards must be walkable from root. So a board
+ * is allowed to sit at zero references as long as it
+ * still has active children. For leaf nodes we then
+ * have to walk up the tree to clear now empty parents.
+ */
+ while(b->closed && b->child == nil){+ assert(b->srv == nil);
+ assert(b->parent != nil);
+
+ /* unlink from parent board */
+ ch = bremove((Link**)&b->parent->child, b->ln.name, ~0UL);
+ assert(ch == b);
+
+ /* unlink from all boards list */
+ ch->prev->next = ch->next;
+ ch->next->prev = ch->prev;
+
+ b = ch->parent;
+ freelink(ch);
+ }
+}
+
+static int
+srvgen(Chan *c, char *name, Dirtab*, int, int s, Dir *dp)
+{+ Srv *sp;
+ Board *b, *ch;
+ Qid q;
+
+ if(name != nil && strlen(name) >= sizeof(up->genbuf))
+ return -1;
+
+ b = c->aux;
+ ch = nil;
+ mkqid(&q, ~0L, 0, QTFILE);
+ rlock(&srvlk);
+ if(waserror()){+ runlock(&srvlk);
+ nexterror();
+ }
+ switch(s){+ case -2: /* dot */
+ ch = b;
+ goto Child;
+ case DEVDOTDOT:
+ ch = b->parent;
+ if(ch == nil)
+ ch = &srvroot;
+ goto Child;
+ }
+ if(name != nil){+ if(strcmp(name, clone) == 0)
+ goto Clone;
+
+ sp = lookup(b->srv, name, ~0UL);
+ if(sp == nil)
+ ch = lookup(b->child, name, ~0UL);
+ } else {+ if(s == 0)
+ goto Clone;
+ s--;
+ for(sp = b->srv; sp != nil && s > 0; sp = sp->ln.link)
+ s--;
+ for(ch = b->child; ch != nil && s > 0; ch = ch->ln.link)
+ s--;
+ }
+ if(sp != nil){+ kstrcpy(up->genbuf, sp->ln.name, sizeof up->genbuf);
+ q.path = SRVQID(sp->ln.path, Qsrv);
+ devdir(c, q, up->genbuf, 0, sp->ln.owner, sp->ln.perm, dp);
+ } else if(ch != nil){+Child:
+ if(name != nil || s == DEVDOTDOT){+ devpermcheck(ch->ln.owner, ch->ln.perm, OEXEC);
+ c->aux = ch;
+ }
+ kstrcpy(up->genbuf, ch->ln.name, sizeof up->genbuf);
+ q.path = SRVQID(ch->ln.path, Qsrv);
+ q.type = QTDIR;
+ devdir(c, q, up->genbuf, 0, ch->ln.owner, ch->ln.perm|DMDIR, dp);
+ } else if(0){+Clone:
+ q.path = SRVQID(SRVPATH(c->qid.path), Qclone);
+ devdir(c, q, clone, 0, eve, 0444, dp);
+ } else {+ runlock(&srvlk);
+ poperror();
+ return -1;
+ }
+
+ runlock(&srvlk);
+ poperror();
+ return 1;
+}
+
+static void
+srvinit(void)
+{+ srvroot.next = &srvroot;
+ srvroot.prev = &srvroot;
+ srvroot.ln.path = srvpath++;
+ srvroot.ln.name = "#s";
+ srvroot.ln.perm = 0777;
+ kstrdup(&srvroot.ln.owner, eve);
+}
+
+static Chan*
+srvattach(char *spec)
+{+ Chan *c;
+
+ c = devattach('s', spec);+ c->aux = &srvroot;
+ return c;
+}
+
+static Walkqid*
+srvwalk(Chan *c, Chan *nc, char **name, int nname)
+{+ Board *b;
+ Walkqid *wq;
+
+ wq = devwalk(c, nc, name, nname, 0, 0, srvgen);
+ if(wq == nil || wq->clone == nil)
+ return wq;
+
+ b = wq->clone->aux;
+ if(b == &srvroot)
+ return wq;
+
+ incref(b);
+ return wq;
+}
+
+static int
+srvstat(Chan *c, uchar *db, int n)
+{+ Dir d;
+
+ /* devstat cheats for dir stats, we care about our dir perms */
+ if(c->qid.type == QTDIR){+ srvgen(c, nil, nil, 0, -2, &d);
+ n = convD2M(&d, db, n);
+ if(n == 0)
+ error(Ebadarg);
+ return n;
+ }
+
+ return devstat(c, db, n, 0, 0, srvgen);
+}
+
+static Chan*
+srvopen(Chan *c, int omode)
+{+ Board *b, *ch;
+ Srv *sp;
+ Chan *nc;
+ char buf[64];
+ int mode;
+
+ if(omode&OTRUNC)
+ error(Eexist);
+ if(omode&ORCLOSE)
+ error(Eperm);
+ mode = openmode(omode);
+
+ b = c->aux;
+ if(SRVTYPE(c->qid.path) == Qclone){+ wlock(&srvlk);
+ if(waserror()){+ wunlock(&srvlk);
+ nexterror();
+ }
+ if(b->closed)
+ error(Eshutdown);
+ ch = smalloc(sizeof *ch);
+ ch->rf.ref = 1;
+ ch->ln.perm = 0770;
+ do {+ ch->ln.path = srvpath++;
+ snprint(buf, sizeof buf, "%ld", ch->ln.path);
+ } while(lookup(b->srv, buf, ~0UL) != nil);
+ kstrdup(&ch->ln.name, buf);
+ kstrdup(&ch->ln.owner, up->user);
+
+ /* link to all boards list */
+ ch->next = &srvroot;
+ ch->prev = srvroot.prev;
+ ch->next->prev = ch;
+ ch->prev->next = ch;
+
+ /* link to parent board */
+ ch->parent = b;
+ ch->ln.link = b->child;
+ b->child = ch;
+
+ c->aux = ch;
+ c->qid.path = SRVQID(ch->ln.path, Qlease);
+ c->mode = mode;
+ boardclunk(b);
+ wunlock(&srvlk);
+ poperror();
+ return c;
+ }
+
+ rlock(&srvlk);
+ if(waserror()){+ runlock(&srvlk);
+ nexterror();
+ }
+ if(c->qid.type == QTDIR){+ if(omode != OREAD)
+ error(Eisdir);
+ devpermcheck(b->ln.owner, b->ln.perm, omode);
+ c->mode = mode;
+ c->flag |= COPEN;
+ c->offset = 0;
+ runlock(&srvlk);
+ poperror();
+ return c;
+ }
+ if(b->closed)
+ error(Eshutdown);
+
+ sp = lookup(b->srv, nil, c->qid.path);
+ if(sp == nil)
+ error(Eshutdown);
+ nc = sp->chan;
+ if(nc == nil)
+ error(Eshutdown);
+ if(mode != nc->mode && nc->mode != ORDWR)
+ error(Eperm);
+ devpermcheck(sp->ln.owner, sp->ln.perm, omode);
+
+ incref(nc);
+
+ runlock(&srvlk);
+ poperror();
+
+ cclose(c);
+ return nc;
+}
+
+static Chan*
+srvcreate(Chan *c, char *name, int omode, ulong perm)
+{+ Board *b;
+ Srv *sp;
+
+ if(openmode(omode) != OWRITE)
+ error(Eperm);
+
+ if(strlen(name) >= sizeof(up->genbuf))
+ error(Etoolong);
+
+ if(strcmp(name, clone) == 0)
+ error(Eexist);
+
+ sp = smalloc(sizeof *sp);
+ kstrdup(&sp->ln.name, name);
+ kstrdup(&sp->ln.owner, up->user);
+
+ b = c->aux;
+ wlock(&srvlk);
+ if(waserror()){+ wunlock(&srvlk);
+ freelink(sp);
+ nexterror();
+ }
+ if(b->closed)
+ error(Eshutdown);
+ devpermcheck(b->ln.owner, b->ln.perm, OWRITE);
+ if(lookup(b->srv, name, ~0UL) != nil)
+ error(Eexist);
+ if(lookup(b->child, name, ~0UL) != nil)
+ error(Eexist);
+
+ sp->ln.perm = perm&0777;
+ sp->ln.path = srvpath++;
+
+ c->qid.path = SRVQID(sp->ln.path, Qsrv);
+ c->qid.type = QTFILE;
+
+ sp->ln.link = b->srv;
+ b->srv = sp;
+
+ wunlock(&srvlk);
+ poperror();
+
+ c->flag |= COPEN;
+ c->mode = OWRITE;
+
+ return c;
+}
+
+static void
+srvremove(Chan *c)
+{+ Board *b;
+ Srv *sp;
+
+ b = c->aux;
+ wlock(&srvlk);
+ if(waserror()){+ boardclunk(b);
+ wunlock(&srvlk);
+ nexterror();
+ }
+ if(c->qid.type == QTDIR)
+ error(Eperm);
+ switch(SRVTYPE(c->qid.path)){+ case Qlease:
+ case Qclone:
+ error(Eperm);
+ }
+
+ sp = lookup(b->srv, nil, c->qid.path);
+ if(sp == nil)
+ error(Enonexist);
+
+ if(strcmp(sp->ln.owner, up->user) != 0 && !iseve())
+ error(Eperm);
+
+ bremove((Link**)&b->srv, nil, c->qid.path);
+
+ boardclunk(b);
+ wunlock(&srvlk);
+ poperror();
+
+ if(sp->chan != nil)
+ cclose(sp->chan);
+ freelink(sp);
+}
+
+static int
+srvwstat(Chan *c, uchar *dp, int n)
+{+ Board *b, *s;
+ char *strs;
+ Dir d;
+ Link *lp;
+
+ switch(SRVTYPE(c->qid.path)){+ case Qlease:
+ case Qclone:
+ error(Eperm);
+ }
+ if(c->qid.type == QTDIR && c->aux == &srvroot)
+ error(Eperm);
+
+ strs = smalloc(n);
+ if(waserror()){+ free(strs);
+ nexterror();
+ }
+ n = convM2D(dp, n, &d, strs);
+ if(n == 0)
+ error(Eshortstat);
+
+ b = c->aux;
+ wlock(&srvlk);
+ if(waserror()){+ wunlock(&srvlk);
+ nexterror();
+ }
+ if(b->closed)
+ error(Eshutdown);
+
+ if(c->qid.type == QTDIR)
+ lp = b;
+ else
+ lp = lookup(b->srv, nil, c->qid.path);
+ if(lp == nil)
+ error(Enonexist);
+
+ if(strcmp(lp->owner, up->user) != 0 && !iseve())
+ error(Eperm);
+
+ if(d.name != nil && *d.name && strcmp(lp->name, d.name) != 0) {+ if(strchr(d.name, '/') != nil)
+ error(Ebadchar);
+ if(strlen(d.name) >= sizeof(up->genbuf))
+ error(Etoolong);
+
+ /* Ensure new name doesn't conflict with old names */
+ if(strcmp(d.name, clone) == 0)
+ error(Eexist);
+ if(c->qid.type == QTDIR)
+ s = b->parent;
+ else
+ s = b;
+ if(lookup(s->srv, d.name, ~0UL) != nil)
+ error(Eexist);
+ if(lookup(s->child, d.name, ~0UL) != nil)
+ error(Eexist);
+ kstrdup(&lp->name, d.name);
+ }
+ if(d.uid != nil && *d.uid)
+ kstrdup(&lp->owner, d.uid);
+ if(d.mode != ~0UL)
+ lp->perm = d.mode & 0777;
+
+ wunlock(&srvlk);
+ poperror();
+
+ free(strs);
+ poperror();
+
+ return n;
+}
+
+static void
+srvclose(Chan *c)
+{+ Srv *sp, *link;
+ Board *b;
+
+ if((c->flag & CRCLOSE) != 0 && SRVTYPE(c->qid.path) != Qlease){+ /*
+ * in theory we need to override any changes in removability
+ * since open, but since all that's checked is the owner,
+ * which is immutable, all is well.
+ */
+ if(waserror())
+ return;
+ srvremove(c);
+ poperror();
+ return;
+ }
+
+ b = c->aux;
+ if(b == &srvroot)
+ return;
+
+ wlock(&srvlk);
+ if(SRVTYPE(c->qid.path) != Qlease){+ boardclunk(b);
+ wunlock(&srvlk);
+ return;
+ }
+
+ /* free later after releasing srvlk */
+ sp = b->srv;
+ b->srv = nil;
+ b->closed++;
+ boardclunk(b);
+ wunlock(&srvlk);
+
+ for(; sp != nil; sp = link){+ link = sp->ln.link;
+ if(sp->chan != nil)
+ cclose(sp->chan);
+ freelink(sp);
+ }
+}
+
+static long
+srvread(Chan *c, void *va, long n, vlong off)
+{+ Board *b;
+
+ if(SRVTYPE(c->qid.path) == Qlease){+ b = c->aux;
+ rlock(&srvlk);
+ if(waserror()){+ runlock(&srvlk);
+ nexterror();
+ }
+ n = readstr((ulong)off, va, n, b->ln.name);
+ runlock(&srvlk);
+ poperror();
+ return n;
+ }
+ isdir(c);
+ return devdirread(c, va, n, 0, 0, srvgen);
+}
+
+static long
+srvwrite(Chan *c, void *va, long n, vlong)
+{+ Board *b;
+ Srv *sp;
+ Chan *c1;
+ int fd;
+ char buf[32];
+
+ if(SRVTYPE(c->qid.path) == Qlease)
+ error(Eperm);
+
+ if(n >= sizeof buf)
+ error(Etoobig);
+ memmove(buf, va, n); /* so we can NUL-terminate */
+ buf[n] = 0;
+ fd = strtoul(buf, 0, 0);
+
+ c1 = fdtochan(fd, -1, 0, 1); /* error check and inc ref */
+
+ b = c->aux;
+ wlock(&srvlk);
+ if(waserror()) {+ wunlock(&srvlk);
+ cclose(c1);
+ nexterror();
+ }
+ if(b->closed)
+ error(Eshutdown);
+ if(c1->qid.type & QTAUTH)
+ error("cannot post auth file in srv");+ sp = lookup(b->srv, nil, c->qid.path);
+ if(sp == nil)
+ error(Enonexist);
+
+ if(sp->chan != nil)
+ error(Ebadusefd);
+
+ sp->chan = c1;
+ if(c1->srvname == nil)
+ kstrdup(&c1->srvname, c->path->s);
+
+ wunlock(&srvlk);
+ poperror();
+ return n;
+}
+
+Dev srvdevtab = {+ 's',
+ "srv",
+
+ devreset,
+ srvinit,
+ devshutdown,
+ srvattach,
+ srvwalk,
+ srvstat,
+ srvopen,
+ srvcreate,
+ srvclose,
+ srvread,
+ devbread,
+ srvwrite,
+ devbwrite,
+ srvremove,
+ srvwstat,
+};
+
+void
+srvrenameuser(char *old, char *new)
+{+ Board *b;
+ Srv *sp;
+
+ wlock(&srvlk);
+ b = &srvroot;
+ do {+ if(strcmp(b->ln.owner, old) == 0)
+ kstrdup(&b->ln.owner, new);
+ for(sp = b->srv; sp != nil; sp = sp->ln.link)
+ if(strcmp(sp->ln.owner, old) == 0)
+ kstrdup(&sp->ln.owner, new);
+ b = b->next;
+ } while(b != &srvroot);
+ wunlock(&srvlk);
+}
\ No newline at end of file
--- a/kern/devtab.c
+++ b/kern/devtab.c
@@ -6,6 +6,7 @@
extern Dev consdevtab;
extern Dev rootdevtab;
+extern Dev dupdevtab;
extern Dev pipedevtab;
extern Dev ssldevtab;
extern Dev tlsdevtab;
@@ -17,11 +18,13 @@
extern Dev cmddevtab;
extern Dev envdevtab;
extern Dev procdevtab;
+extern Dev srvdevtab;
extern Dev capdevtab;
Dev *devtab[] = {&rootdevtab,
&consdevtab,
+ &dupdevtab,
&pipedevtab,
&ssldevtab,
&tlsdevtab,
@@ -33,6 +36,7 @@
&cmddevtab,
&envdevtab,
&procdevtab,
+ &srvdevtab,
&capdevtab,
0
};
--- a/kern/fns.h
+++ b/kern/fns.h
@@ -56,7 +56,6 @@
Walkqid* devwalk(Chan*, Chan*, char**, int, Dirtab*, int, Devgen*);
int devwstat(Chan*, uchar*, int);
Dir* dirchanstat(Chan*);
-void drawcmap(void);
void donote(char *, ulong);
void dump(void);
Fgrp* dupfgrp(Fgrp*);
@@ -81,8 +80,8 @@
void freesegs(void);
uintptr getmalloctag(void*);
uintptr getrealloctag(void*);
-void gotolabel(Label*);
char* getconfenv(void);
+void gotolabel(Label*);
long hostdomainwrite(char*, int);
long hostownerwrite(char*, int);
Block* iallocb(int);
@@ -157,7 +156,7 @@
#define poperror() up->nerrlab--
int postnote(Proc*, int, char*, int);
int pprint(char*, ...);
-int procfdprint(Chan*, int, int, char*, int);
+int procfdprint(Chan*, int, char*, int);
void procinit0(void);
void procrun(void*);
Proc* proctab(int);
@@ -256,5 +255,5 @@
void procwakeup(Proc*);
void osinit(void);
void screeninit(void);
-extern void terminit(void);
+
extern void setterm(int);
--- a/kern/screen.h
+++ b/kern/screen.h
@@ -33,9 +33,6 @@
extern Cursorinfo cursor;
extern Cursorinfo arrow;
-void screeninit(void);
-void screenload(Rectangle, int, uchar *, Point, int);
-
void getcolor(ulong, ulong*, ulong*, ulong*);
void setcolor(ulong, ulong, ulong, ulong);
@@ -42,6 +39,7 @@
void setcursor(void);
void mouseset(Point);
void flushmemscreen(Rectangle);
+void screenload(Rectangle, int, uchar *, Point, int);
Memdata*attachscreen(Rectangle*, ulong*, int*, int*, int*);
void deletescreenimage(void);
void resetscreenimage(void);
@@ -49,7 +47,6 @@
extern QLock drawlock;
#define ishwimage(i) 0
-void terminit(void);
void screenresize(Rectangle);
void screensize(Rectangle, ulong);
@@ -56,5 +53,4 @@
void mouseresize(void);
void mousetrack(int, int, int, ulong);
void absmousetrack(int, int, int, ulong);
-void cpubody(void);
-void guimain(void);
+
--- a/kern/sysproc.c
+++ b/kern/sysproc.c
@@ -147,6 +147,17 @@
wunlock(&fd->rw);
}
+int
+procfdprint(Chan *c, int fd, char *s, int ns)
+{+ return snprint(s, ns, "%3d %.2s %C %4ld (%.16llux %lud %.2ux) %5ld %8lld %s\n",
+ fd,
+ &"r w rw"[(c->mode&3)<<1],
+ devtab[c->type]->dc, c->dev,
+ c->qid.path, c->qid.vers, c->qid.type,
+ 8102, c->offset, c->path->s);
+}
+
void
fdclear(Fd *fd)
{--- a/main.c
+++ b/main.c
@@ -4,12 +4,13 @@
#include "kern/fns.h"
#include "user.h"
#include "drawcpu.h"
+#include "auth.h"
#include "args.h"
#include "proc.h"
char *argv0;
-int debug;
-char *ninepath;
+char cons[] = "/dev/cons";
+int debug;
void
sizebug(void)
@@ -29,30 +30,28 @@
assert(sizeof(uvlong)==8);
}
-// TODO: remove libgui, or at least revamp as cpubody goes away
-void cpubody(void) {}-
-char*
-estrdup(char *s)
-{- s = strdup(s);
- if(s == nil)
- sysfatal("out of memory");- return s;
-}
-
-
static void
usage(void)
{- fprintf(stderr, "usage: drawcpu [-p <path> -d]\n");
+ fprintf(stderr, "usage: drawcpu [-d]\n");
exit(1);
}
void
+postsrv(int fd, char *name)
+{+ int sfd;
+
+ sfd = create(smprint("/srv/%s", name), OWRITE, 0666);+ fprint(sfd, "%d", fd);
+ close(sfd);
+}
+
+void
notehandler(void *d, char *note)
{USED(d);
+print("note: %s\n", note);if(strncmp(note, "sys:", 4) == 0)
return;
@@ -63,74 +62,40 @@
return;
}
-static void
-envinit(char *nvram)
-{- int fd, nvrlen;
-
- /* We want to set up our env based on some details here
- * nvram, nvroff, nvrlen, cputype
- */
- if((fd = create("/env/nvram", ORDWR, 0666)) < 0)- panic("open env/nvram: %r");- fprint(fd, "%s", nvram);
- close(fd);
-
- // We need to set our actual nvlen
- if((fd = open(nvram, OREAD)) < 0)
- panic("open %d: %r", nvram);-
- nvrlen = seek(fd, 0, SEEK_END);
- close(fd);
-
- if((fd = create("/env/nvroff", ORDWR, 0666)) < 0)- panic("open env/nvroff: %r");- fprint(fd, "0");
- close(fd);
-
- if((fd = create("/env/nvrlen", ORDWR, 0666)) < 0)- panic("open env/nvrlen: %r");- fprint(fd, "%d", nvrlen);
- close(fd);
-
- if((fd = create("/env/cputype", ORDWR, 0666)) < 0)- panic("open env/cputype: %r");- fprint(fd, "arm");
- close(fd);
-}
-
int
main(int argc, char **argv)
{extern ulong kerndate;
- char *file, *nvram;
+ char *fs, *sysname;
+ int sfd, fd, tls = 0;
- debug = 0;
- kerndate = seconds();
- eve = getuser();
- nvram = "/tmp/nvram";
+ debug = 0;
+ kerndate = seconds();
+ eve = getuser();
ARGBEGIN {- case 'p':
- ninepath = EARGF(usage());
- break;
case 'd':
debug++;
break;
- case 'n':
- nvram = EARGF(usage());
+ case 'f':
+ fs = EARGF(usage());
break;
case 'u':
eve = EARGF(usage());
break;
+ case 's':
+ sysname = EARGF(usage());
+ break;
+ case 't':
+ tls++;
+ break;
default:
usage();
} ARGEND;
+
+ /* We don't use argv for the root loadtext */
+ argv[0] = "";
-
- if(!ninepath)
- ninepath = getwd(ninepath, 256);
-
sizebug();
osinit();
procinit0();
@@ -139,56 +104,69 @@
chandevreset();
chandevinit();
quotefmtinstall();
+ notify(notehandler);
- if(bind("#c", "/dev", MBEFORE) < 0)- panic("bind #c: %r");- if(bind("#e", "/env", MREPL|MCREATE) < 0)- panic("bind #e: %r");- if(bind("#L", "/fd", MREPL|MCREATE) < 0)- panic("bind #L");- if(bind("#I", "/net", MBEFORE) < 0)- panic("bind #I: %r");- if(bind("#U", "/root", MREPL|MCREATE) < 0)- panic("bind #U: %r");- if(bind("#p", "/proc", MBEFORE) < 0)- panic("bind #p: %r");+ /* This ordering is based on /lib/namespace
+ * - Our host fs connection lives in /srv/boot
+ * - Everything else should eventually get a /srv
+ */
+ bind("#c", "/dev", MREPL);+ bind("#d", "/fd", MREPL);+ bind("#e", "/env", MREPL|MCREATE);+ bind("#p", "/proc", MREPL);+ bind("#s", "/srv", MREPL|MCREATE);+ //bind -q #σ /shr MREPL
+ bind("#¤", "/dev", MAFTER);- if(bind(smprint("/root/%s/arm", ninepath), "/arm", MREPL|MCREATE) < 0)- panic("bind arm: %r");- if(bind(smprint("/root/%s/rc", ninepath), "/rc", MREPL|MCREATE) < 0)- panic("bind rc: %r");+ open(cons, OREAD);
+ open(cons, OWRITE);
+ open(cons, OWRITE);
- bind("#A", "/dev", MAFTER);- bind("#N", "/dev", MAFTER);- bind("#¤", "/dev", MAFTER);- bind("#C", "/", MAFTER);+ //bind("#l", "/net", MAFTER);+ bind("#I", "/net", MAFTER);+ //bind("#a", "/net", MAFTER);- if(bind("/root", "/", MAFTER) < 0)- panic("bind /root: %r");+ // TODO: This might be incorrect port
+ fd = dial(netmkaddr(fs, tls ? "tls" : "tcp", "9fs"), nil, nil, nil);
+ if(fd < 0)
+ panic("dial fs: %r");+ postsrv(fd, "boot");
+ close(fd);
- /* This should work, but it doesn't */
+ /* Set up our root */
+ sfd = open("/srv/boot", ORDWR);+ mount(sfd, -1, "/root", MREPL|MCREATE, "");
+ close(sfd);
+
+ // TODO: mntgen -s slashmnt /mnt
+ //postsrv(fd, "slashmnt");
+ // TODO: mntget -s slashn /n
+ //postsrv(fd, "slashn");
+ // TODO: mntgen -s slashexport /mnt/exportfs
+ //postsrv(fd, "slashexport");
+
+ /* Used for `os` */
+ bind("#C", "/mnt/term/", MAFTER);+ bind("#U", "/mnt/cpu", MAFTER);+ bind("/mnt/cpu/tmp", "/tmp", MCREATE|MAFTER);+ bind("/root", "/", MCREATE|MAFTER);+
+ /* Build our /bin directory */
if(bind("/arm/bin", "/bin", MCREATE|MREPL) < 0 || bind("/rc/bin", "/bin", MAFTER) < 0) panic("bind bin: %r");+ chdir(smprint("/usr/%s", eve));- if(**argv == '/' || **argv == '.' || **argv == '#') {- if(loadtext(*argv, argc, argv) < 0)
- panic("loadtext: %r");- } else {- file = smprint("/bin/%s", *argv);- if(loadtext(file, argc, argv) < 0)
- panic("loadtext: %r");- free(file);
- }
+ loadtext("/bin/rc", 1, argv);+ ksetenv("cputype", "arm", 0); // cputype being anything but arm should fail for now+ ksetenv("objtype", "arm", 0);+ ksetenv("rootdir", "/root", 0);+ ksetenv("user", eve, 0);+ ksetenv("service", "cpu", 0);+ ksetenv("sysname", sysname, 0);+ ksetenv("prompt", "unix\% ", 0);+ ksetenv("nvram", "/tmp/nvram", 0); /* Set up in the host /tmp */- envinit(nvram);
- if(open("/dev/cons", OREAD) != 0)- panic("open0: %r");- if(open("/dev/cons", OWRITE) != 1)- panic("open1: %r");- if(open("/dev/cons", OWRITE) != 2)- panic("open2: %r");-
- notify(notehandler);
+ /* Run machine */
procrun(0);
exits(0);
--- a/rc/lib/rcmain
+++ /dev/null
@@ -1,40 +1,0 @@
-# rcmain: Plan 9 version
-
-if(~ $#home 0) home=/
-if(~ $#ifs 0) ifs='
-'
-switch($#prompt){-case 0
- prompt=('unix% ' ' ')-case 1
- prompt=($prompt ' ')
-}
-if(~ $rcname ?.out) prompt=('broken! ' ' ')-if(flag p) path=/bin
-if not{- finit
- if(~ $#path 0) path=(/bin .)
-}
-fn sigexit
-if(! ~ $#cflag 0){- if(flag l){- if(/bin/test -r /rc/lib/rcmain.local) . /rc/lib/rcmain.local
- if(/bin/test -r $home/lib/profile) . $home/lib/profile
- }
- status=''
- eval $cflag
-}
-if not if(flag i){- if(flag l){- if(/bin/test -r /rc/lib/rcmain.local) . /rc/lib/rcmain.local
- if(/bin/test -r $home/lib/profile) . $home/lib/profile
- }
- status=''
- if(! ~ $#* 0) . $*
- . -i /fd/0
-}
-if not if(~ $#* 0) . /fd/0
-if not{- status=''
- . $*
-}
\ No newline at end of file
--
⑨