shithub: drawcpu

Download patch

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 '	')
 }
--