ref: 4fd46455350c3e29718f8fdd6d709f3c72b4abb4
parent: b35328f248cab12ae0760c237d1544842200510c
author: halfwit <michaelmisch1985@gmail.com>
date: Sun Sep 21 10:32:35 EDT 2025
rfork is working, commit
--- a/TODO
+++ b/TODO
@@ -1,37 +1,25 @@
TODO:
- - [x] /env/fn# to init functions?
- - [-] set up initial connection before handing over to an rc session, to set up binds and mounts?
- - [ ] Set up $path with \#9/$objtype/bin and \#9/rc/bin
- - [x] remove rc builtins aside from mount/bind
- - [x] start.s in libmachdep for each posix-target, just do like tas.c
- - investigate if we want to run this another way instead!
- - [x] have it export a var service=unix
+
- [ ] Some people probably want aan?
- [ ] gui-cocoa try to capture the windows we create so we can send mouse/keyboard to it, plist for launchd
- [ ] gui-wl cannibalize the wayland shims
- [ ] Use ScreenCaptureKit to get at the video/audio. Handle resizes the other direction
- [ ] define the gui interface
- - [x] Makefile librc --> librc.a
- - [ ] RFREND + RFNOMEM could probably be handled in rfork
+ - [ ] Fully fledged note handling
+ - [ ] up->parent integration into /proc
-Remove our rc, just add in all of our syscall intercepts properly.
Kernel space needs:
- - devdraw - #i: !needed, We use the client exported /dev/draw instead
- - devkbd - #b: !needed, We use the client exported /dev/kbd instead
- - devmouse - #m: !needed, We use the client exported /dev/mouse instead
- - devaudio - #A: !needed, We use the client exported /dev/audio instead
- - devcmd - #C: needed OS(1) commands, we already run on host
- - devcons - #c: needed, /dev/cons
- - devenv - #e: needed, /env
- - devfs - #U: needed, local files
- - devip - #I: needed, networking
- - devlfd - #L: needed, local fd
- - devmnt - #M: needed, client shares
- - devpipe - #|: needed, for pipes
- - devroot - #/: needed, base of stack
- - devssl - #D: needed, ssl
- - devtls - #a: needed, tls
- - devproc - #p: needed, /proc, overlay any existing
- - devsrv - #s: !needed, eventually add
- - devbin - #9: needed, just a path that can use PLAN9
- - devtab - meta, needed - add/remove any devices that we add/remove, from here as well
+ - [x] devcmd - #C: OS(1) commands, we already run on host
+ - [x] devcons - #c: /dev/cons
+ - [x] devenv - #e:/env
+ - [x] devfs - #U: needed, local files
+ - [x] devip - #I: needed, networking
+ - [x] devlfd - #L: needed, local fd
+ - [x] devmnt - #M: needed, client shares
+ - [x] devpipe - #|: needed, for pipes
+ - [x] devroot - #/: needed, base of stack
+ - [x] devssl - #D: needed, ssl
+ - [x] devtls - #a: needed, tls
+ - [ ] devproc - #p: needed, /proc, overlay any existing
+ - [ ] devbin - #9: needed, just a path that can use PLAN9 environment variable
+ - [x] devtab - # meta: needed add/remove any devices that we add/remove, from here as well
--- a/include/u.h
+++ b/include/u.h
@@ -27,4 +27,5 @@
#undef unmount
#undef pipe
#undef iounit
-extern int debug;
\ No newline at end of file
+extern int debug;
+extern char *ninepath;
\ No newline at end of file
--- a/kern/arm.c
+++ b/kern/arm.c
@@ -488,6 +488,15 @@
instr = *(u32int*) vaddr(up->R[15], 4, &seg);
segunlock(seg);
+ if(debug > 2) {+ print("%.8ux %.8ux %c%c%c%c\n", up->R[15], instr,+ (up->CPSR & flZ) ? 'Z' : ' ',
+ (up->CPSR & flC) ? 'C' : ' ',
+ (up->CPSR & flN) ? 'N' : ' ',
+ (up->CPSR & flV) ? 'V' : ' '
+ );
+ }
+
up->R[15] += 4;
// CPSR testing for conditional execution
--- a/kern/dat.h
+++ b/kern/dat.h
@@ -305,6 +305,7 @@
QLock debug; /* single access via devproc.c */
RWlock ns; /* Namespace n read/one write lock */
Mhead *mnthash[MNTHASH];
+ u64int notallowed[4];
};
typedef struct Ureg {@@ -434,6 +435,7 @@
QLock debug;
Lock rlock; /* sync sleep/wakeup with postnote */
+ Lock exl; /* rfork, etc */
Rendez *r; /* rendezvous point slept on */
Rendez rsleep; /* place for syssleep/debug */
int notepending; /* note issued but not acted on */
@@ -472,6 +474,8 @@
Chan *dot;
Proc *qnext;
+ Proc *parent;
+ int nchild;
void (*fn)(void*);
void *arg;
--- a/kern/devlfd-posix.c
+++ b/kern/devlfd-posix.c
@@ -142,23 +142,6 @@
error(Enonexist);
}
- /* Enforce permissions based on fd */
- switch(fd) {- case 0: /* stdin */
- if(omode != OREAD)
- error(Eperm);
- break;
- case 1: /* stdout */
- case 2: /* stderr */
- if(omode != OWRITE)
- error(Eperm);
- break;
- default:
- if((omode & (OREAD|OWRITE)) == 0)
- error(Eperm);
- break;
- }
-
c->mode = openmode(omode);
c->flag |= COPEN;
c->offset = 0;
--- a/kern/seg.c
+++ b/kern/seg.c
@@ -10,10 +10,10 @@
if(debug > 1)
print("newseg: size=%.8ux start=%.8ux idx=%d\n", size, start, idx);- s = malloc(sizeof *s);
+ s = malloc(sizeof(Segment));
if(s == nil)
panic("%r");- memset(s, 0, sizeof *s);
+
incref(&s->ref);
s->start = start;
s->size = size;
@@ -36,7 +36,6 @@
if(debug > 1)
print("newseg: created idx=%d type=%d start=%.8ux size=%.8ux\n",idx, s->type, s->start, s->size);
- up->seg[idx] = s;
return s;
}
@@ -108,11 +107,6 @@
if(segno < 0 || segno >= NSEG)
panic("dupseg: invalid segment index %d", segno);s = seg[segno];
- if(s == nil) {- if(debug > 1)
- print("dupseg: null segment for segno=%d, skipping\n", segno);- return nil;
- }
if(debug > 1)
print("dupseg: segno=%d, type=%d, start=%.8ux, size=%.8ux, share=%d\n", segno, s->type, s->start, s->size, share);qlock(&s->rw);
@@ -121,7 +115,7 @@
nexterror();
}
switch(s->type&SG_TYPE) {- case SG_TEXT: /* New segment shares pte set */
+ case SG_TEXT:
case SG_SHARED:
case SG_PHYSICAL:
case SG_FIXED:
@@ -129,13 +123,12 @@
default:
goto sameseg;
case SG_STACK:
- n = newseg(s->start, s->size, s->type);
- memcpy(n->data, s->data, s->size);
+ n = newseg(s->start, s->size, ESEG);
break;
case SG_BSS: /* Just copy on write */
if(share)
goto sameseg;
- n = newseg(s->start, s->size, s->type);
+ n = newseg(s->start, s->size, BSEG);
break;
case SG_DATA: /* Copy on write plus demand load info */
if(segno == TSEG){@@ -146,10 +139,12 @@
}
if(share)
goto sameseg;
- n = newseg(s->start, s->size, s->type);
- memcpy(n->dref, s->dref, s->size);
+ n = newseg(s->start, s->size, DSEG);
break;
}
+
+ if(n != nil && n != s)
+ memcpy(n->data, s->data, s->size);
qunlock(s);
poperror();
return n;
--- a/kern/syscall.c
+++ b/kern/syscall.c
@@ -71,6 +71,7 @@
u32int name, flags;
char *namet;
int fd, copied;
+
name = arg(0);
flags = arg(1);
namet = copyifnec(name, -1, &copied);
@@ -194,9 +195,9 @@
fd = arg(0);
buf = arg(1);
nbuf = arg(2);
+ buft = bufifnec(buf, nbuf, &buffered);
if(debug)
print("fd2path\n");- buft = bufifnec(buf, nbuf, &buffered);
up->R[0] = noteerr(fd2path(fd, buft, nbuf), 0);
if(buffered)
copyback(buf, nbuf, buft);
@@ -214,7 +215,7 @@
namet = copyifnec(name, -1, &copied);
edir = arg(1);
nedir = arg(2);
- edirt = bufifnec(edir, nedir, &buffered);
+ edirt = bufifnec(edir, nedir, &buffered);
if(debug)
print("sysstat: edir=%s, nedir=%d\n", edirt, nedir);up->R[0] = noteerr(stat(namet, edirt, nedir), nedir);
@@ -230,6 +231,7 @@
u32int fd, edir, nedir;
void *edirt;
int buffered;
+
fd = arg(0);
edir = arg(1);
nedir = arg(2);
@@ -236,7 +238,7 @@
edirt = bufifnec(edir, nedir, &buffered);
if(debug)
print("sysfstat: edir=%s, nedir=%d\n", edirt, nedir);- up->R[0] = noteerr(sysfstat(fd, edirt, nedir), nedir);
+ up->R[0] = noteerr(fstat(fd, edirt, nedir), nedir);
if(buffered)
copyback(edir, up->R[0], edirt);
}
@@ -256,7 +258,7 @@
edirt = copyifnec(edir, nedir, &copied2);
if(debug)
print("syswstate dir=%s, name=%s\n", edirt, namet);- up->R[0] = noteerr(syswstat(namet, edirt, nedir), nedir);
+ up->R[0] = noteerr(wstat(namet, edirt, nedir), nedir);
if(copied)
free(namet);
if(copied2)
@@ -276,7 +278,7 @@
edirt = copyifnec(edir, nedir, &copied);
if(debug)
print("sysfwstat: %d, %#ux, %d\n",fd, edir, nedir);- up->R[0] = noteerr(sysfwstat(fd, edirt, nedir), nedir);
+ up->R[0] = noteerr(fwstat(fd, edirt, nedir), nedir);
if(copied)
free(edirt);
}
@@ -343,10 +345,10 @@
int copied;
dir = arg(0);
+ dirt = copyifnec(dir, -1, &copied);
if(debug)
print("syschdir\n");- dirt = copyifnec(dir, -1, &copied);
- up->R[0] = noteerr(syschdir(dirt), 0);
+ up->R[0] = noteerr(chdir(dirt), 0);
if(copied)
free(dirt);
}
@@ -380,39 +382,11 @@
_sysrfork(void)
{u32int flags;
- int rc, i;
- Segment *s, *t;
- Fd *old;
+
flags = arg(0);
if(debug)
print("rfork(%#o) for proc pid=%lud\n", flags, up->pid);- if((flags & (RFFDG | RFCFDG)) == (RFFDG | RFCFDG) ||
- (flags & (RFNAMEG | RFCNAMEG)) == (RFNAMEG | RFCNAMEG) ||
- (flags & (RFENVG | RFCENVG)) == (RFENVG | RFCENVG)) {- up->R[0] = -1;
- cherrstr("bad arg in syscall");- return;
- }
-
- if((flags & RFPROC) == 0) {- if(flags & RFFDG) {- Fgrp *old = up->fgrp;
- up->fgrp = dupfgrp(up->fgrp);
- closefgrp(old);
- }
- if(flags & RFCFDG) {- Fgrp *old = up->fgrp;
- up->fgrp = dupfgrp(nil);
- closefgrp(old);
- }
- up->R[0] = noteerr(sysrfork(flags), 0);
- return;
- }
-
- /* Seg could be being shared here, not useful */
- rc = sysrfork(flags);
- if(rc < 0) /* this should NEVER happen */
- panic("rfork failed: %r");+ up->R[0] = noteerr(rfork(flags), 0);
}
static void
@@ -474,7 +448,7 @@
fdt = bufifnec(fd, 8, &buffered);
if(debug)
print("syspipe\n");- up->R[0] = noteerr(syspipe((int *) fdt), 0);
+ up->R[0] = noteerr(pipe((int *) fdt), 0);
if(buffered)
copyback(fd, 8, fdt);
}
@@ -512,7 +486,7 @@
value = arg(1);
if(debug)
print("sysrendezvous: tag=%.8ux, value=%.8ux\n", tag, value);- up->R[0] = (u32int) (uintptr)sysrendezvous((void *)tag, (void *)value);
+ up->R[0] = (u32int) (uintptr)rendezvous((void *)tag, (void *)value);
if(up->R[0] == ~0)
noteerr(0, 1);
}
@@ -540,7 +514,7 @@
if(debug)
print("sysmount\n");}
- up->R[0] = noteerr(sysmount(fd, afd, oldt, flag, anamet), 0);
+ up->R[0] = noteerr(mount(fd, afd, oldt, flag, anamet), 0);
if(copiedold)
free(oldt);
if(copiedaname)
@@ -561,7 +535,7 @@
oldt = copyifnec(old, -1, &copiedold);
if(debug)
print("sysbind: name=%s, old=%s\n", namet, oldt);- up->R[0] = noteerr(sysbind(namet, oldt, flags), 0);
+ up->R[0] = noteerr(bind(namet, oldt, flags), 0);
if(copiedname)
free(namet);
if(copiedold)
@@ -583,10 +557,10 @@
if(name == 0) {namet = nil;
copiedname = 0;
- up->R[0] = noteerr(sysunmount(nil, oldt), 0);
+ up->R[0] = noteerr(unmount(nil, oldt), 0);
} else {namet = copyifnec(name, -1, &copiedname);
- up->R[0] = noteerr(sysunmount(namet, oldt), 0);
+ up->R[0] = noteerr(unmount(namet, oldt), 0);
}
if(copiedold)
free(oldt);
@@ -605,7 +579,7 @@
filet = copyifnec(file, -1, &copied);
if(debug)
print("sysremove: file=%s\n", filet);- up->R[0] = noteerr(sysremove(filet), 0);
+ up->R[0] = noteerr(remove(filet), 0);
if(copied)
free(filet);
}
--- a/kern/sysproc.c
+++ b/kern/sysproc.c
@@ -12,7 +12,6 @@
#include <sys/mman.h>
#include <setjmp.h>
-#undef read
jmp_buf exec_jmp;
#define pgsize 0x1000
@@ -37,7 +36,33 @@
return *(u32int*) vaddrnol(up->R[13] + 4 + 4 * n, 4);
}
+void
+devmask(Pgrp *pgrp, int invert, char *devs)
+{+ int i, t, w;
+ char *p;
+ Rune r;
+ u64int mask[nelem(pgrp->notallowed)];
+ if(invert)
+ memset(mask, 0xFF, sizeof mask);
+ else
+ memset(mask, 0, sizeof mask);
+
+ w = sizeof mask[0] * 8;
+ for(p = devs; *p != '\0';){+ p += chartorune(&r, p);
+ t = devno(r, 1);
+ if(t == -1)
+ continue;
+ if(invert)
+ mask[t/w] &= ~(1<<t%w);
+ else
+ mask[t/w] |= 1<<t%w;
+ }
+
+}
+
static void
copyname(char *file)
{@@ -298,7 +323,6 @@
}
*(ulong *) vaddrnol(sp, 4) = 0;
inittos();
-
}
void
@@ -365,8 +389,8 @@
int
loadtext(char *file, int argc, char **argv)
{- Segment *text, *data, *bss;
- uvlong txtaddr, txtsz, txtoff, dataddr, datsz, datoff, bsssz, hdrsz;
+ Segment *text, *data, *bss, *stack;
+ uvlong txtaddr, txtsz, dataddr, datsz, datoff, bsssz, hdrsz;
Exec hdr;
char buf[2];
int fd;
@@ -385,7 +409,6 @@
hdrsz = sizeof(Exec);
txtaddr = pgsize + hdrsz;
txtsz = beswal(hdr.text);
- txtoff = sizeof(Exec);
dataddr = _round(pgsize+txtsz+hdrsz, pgsize);
datsz = beswal(hdr.data);
datoff = txtsz + hdrsz;
@@ -399,8 +422,8 @@
text = newseg(txtaddr - hdrsz, txtsz + hdrsz, TSEG);
data = newseg(dataddr, datsz, DSEG);
bss = newseg(dataddr + datsz, bsssz, BSEG);
- newseg((USTKTOP & ~7) - USTKSIZE, USTKSIZE, ESEG);
- seek(fd, txtoff - hdrsz, 0);
+ stack = newseg((USTKTOP & ~7) - USTKSIZE, USTKSIZE, ESEG);
+ seek(fd, 0, 0);
if(readn(fd, text->data, txtsz + hdrsz) < txtsz + hdrsz)
panic("%r");seek(fd, datoff, 0);
@@ -407,6 +430,11 @@
if(readn(fd, data->data, datsz) < datsz)
panic("%r");+ up->seg[TSEG] = text;
+ up->seg[DSEG] = data;
+ up->seg[BSEG] = bss;
+ up->seg[ESEG] = stack;
+
memset(bss->data, 0, bss->size);
up->R[15] = beswal(hdr.entry);
close(fd);
@@ -443,7 +471,6 @@
Pgrp *opg;
Rgrp *org;
Egrp *oeg;
- ulong pid;
char *devs;
int i, n;
@@ -472,8 +499,8 @@
pgrpcpy(up->pgrp, opg);
closepgrp(opg);
}
- //if(flag & RFNOMNT)
- // devmask(up->pgrp, 1, devs);
+ if(flag & RFNOMNT)
+ devmask(up->pgrp, 1, devs);
if(flag & RFREND) {org = up->rgrp;
up->rgrp = newrgrp();
@@ -495,9 +522,7 @@
}
return 0;
}
-
p = newproc();
-
qlock(&up->debug);
qlock(&p->debug);
p->slash = cclone(up->slash);
@@ -516,18 +541,15 @@
// p->noteid = up->noteid;
/* Copy regs over */
- for(i = 0; i <= 15; i++)
+ for(i = 1; i <= 15; i++)
p->R[i] = up->R[i];
p->R[0] = 0;
+
p->CPSR = up->CPSR;
p->FPSR = up->FPSR;
-
- strcpy(&p->text, up->text);
- strcpy(&p->user, up->user);
//strcpy(&p->args, "");
//p->nargs = 0;
//p->setargs = 0;
- pid = getpid();
qunlock(&p->debug);
qunlock(&up->debug);
@@ -566,16 +588,15 @@
if(flag & RFNAMEG)
pgrpcpy(p->pgrp, up->pgrp);
/* inherit notallowed */
- //memmove(p->pgrp->notallowed, up->pgrp->notallowed, sizeof p->pgrp->notallowed);
+ memmove(p->pgrp->notallowed, up->pgrp->notallowed, sizeof p->pgrp->notallowed);
}
else {p->pgrp = up->pgrp;
incref(p->pgrp);
}
- /* TODO: devmask
if(flag & RFNOMNT)
devmask(p->pgrp, 1, devs);
- */
+
if(flag & RFREND)
p->rgrp = newrgrp();
else {@@ -599,12 +620,13 @@
poperror();
if((flag&RFNOWAIT) == 0){- //p->parent = up;
- //lock(&up->exl);
- //up->nchild++;
- //unlock(&up->exl);
+ // TODO: Actually use parent + ppid
+ p->parent = up;
+ lock(&up->exl);
+ up->nchild++;
+ unlock(&up->exl);
}
osproc(p);
- return 0;
+ return p->pid;
}
--- a/main.c
+++ b/main.c
@@ -9,6 +9,7 @@
char *argv0;
int debug;
+char *ninepath;
void
sizebug(void)
@@ -44,7 +45,7 @@
static void
usage(void)
{- fprintf(stderr, "usage: drawcpu [-p 9bin]\n");
+ fprintf(stderr, "usage: drawcpu [-p <path> -d]\n");
exit(1);
}
@@ -77,10 +78,9 @@
main(int argc, char **argv)
{extern ulong kerndate;
- char *path, *file, *rc;
+ char *file;
debug = 0;
- path = nil;
kerndate = seconds();
eve = getuser();
if(eve == nil)
@@ -87,11 +87,8 @@
eve = "drawcpu";
ARGBEGIN {- case 'r':
- rc = EARGF(usage());
- break;
case 'p':
- path = EARGF(usage());
+ ninepath = EARGF(usage());
break;
case 'd':
debug++;
@@ -100,6 +97,10 @@
usage();
} ARGEND;
+
+ if(!ninepath)
+ ninepath = getwd(ninepath, 256);
+
sizebug();
osinit();
procinit0();
@@ -113,6 +114,8 @@
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)@@ -119,8 +122,10 @@
panic("bind #U: %r"); //if(bind("#P", "/proc", MBEFORE) < 0) // panic("bind #P: %r");- if(bind("#L", "/fd", MAFTER) < 0)- panic("bind #L");+ 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"); bind("#A", "/dev", MAFTER); bind("#N", "/dev", MAFTER);@@ -129,14 +134,9 @@
if(bind("/root", "/", MAFTER) < 0) panic("bind /root: %r");- /* TODO: /path/to/root, root has /rc and /arm
- * Bind in /arm/bin, /rc/bin/ and /rc/lib
- */
- if(rc != nil)
- bind(rc, "/rc", MAFTER);
-
- if(path != nil)
- bind(path, "/bin", MAFTER);
+ /* This should work, but it doesn't */
+ if(bind("/arm/bin", "/bin", MCREATE|MREPL) < 0 || bind("/rc/bin", "/bin", MAFTER) < 0)+ panic("bind bin: %r"); if(**argv == '/' || **argv == '.' || **argv == '#') {if(loadtext(*argv, argc, argv) < 0)
--- a/rc/lib/rcmain
+++ b/rc/lib/rcmain
@@ -1,10 +1,11 @@
# rcmain: Plan 9 version
+
if(~ $#home 0) home=/
if(~ $#ifs 0) ifs='
'
switch($#prompt){case 0
- prompt=('% ' ' ')+ prompt=('unix% ' ' ')case 1
prompt=($prompt ' ')
}
--
⑨