hlfw.ca

drawcpu

Download patch

ref: 35f93cec31d91dc9c68911fc0ac658eb67363af4
parent: 46b0c36526f6004ba57adf9fe675313bae870836
author: halfwit <michaelmisch1985@gmail.com>
date: Wed Feb 28 13:24:01 PST 2024

1000 line file soon for simple.c, but add more of the builtins we need

--- a/TODO
+++ b/TODO
@@ -1,9 +1,10 @@
-NOTES:
-Some commands we will need to add as builtins to rc
- - 'mount'
- - 'bind', might need a device driver or header-exposed syscall See how bind (2) is coded
- - 'unmount'
- - 'ns'
+BUILTINS:
+ - [x]' read' ?
+ - [x] 'write' ?
+ - [x] 'mount'
+ - [x] 'bind', might need a device driver or header-exposed syscall See how bind (2) is coded
+ - [ ] 'unmount'
+ - [ ] 'ns'
 
 TODO:
  - [ ] Install rcmain properly on system, refer to it as needed
@@ -14,6 +15,7 @@
  - [ ] gui-wl cannibalize the wayland shims
  - [ ] create namespaces with our bind/mount and allow report via ns(1)
  - [ ] define the gui interface
+ - [ ] make sure we chroot programs so the stdio and opens are correctly sent to our kernel devices
  - [x] Makefile librc --> librc.a
  - [x] libc.h getwd plan9port/src/lib9/getwd.c 
  - [x] libc.h dirread /sys/src/libc/9sys/dirread.c
@@ -41,4 +43,5 @@
  - devroot  - #/: needed, base of stack
  - devssl   - #D: !needed, ssl
  - devtls   - #a: !needed, tls
+ - devfd    - #f: needed, host fds in our kernelspace
  - devtab   - meta, needed - add/remove any devices that we add/remove, from here as well
--- a/main.c
+++ b/main.c
@@ -67,8 +67,6 @@
 		panic("bind #U: %r");
     if(bind("/root", "/", MAFTER) < 0)
 		panic("bind /root: %r");
-
-	// We get service=cpu, change to =unix
 	char *cmd[] = {
 		"drawcpu",
 		"-c"
--- a/rc/drawcpu.c
+++ b/rc/drawcpu.c
@@ -24,11 +24,17 @@
 	"flag",		execflag,
 	"finit",	execfinit,
 	"rfork",	execrfork,
+	"read",     execread,
+	"ns",       execns,
+	"bind",		execbind,
+	"mount",	execmount,
+	"unmount",	execunmount,
 	0
 };
 
+/* TODO: Set rcmain in .make  */
 char Rcmain[]="/usr/local/lib/rcmain";
-char Fdprefix[]="/dev/fd/";
+char Fdprefix[]="/fd/";
 
 char *Signame[] = {
 	"sigexit",	"sighup",	"sigint",	"sigquit",
--- a/rc/exec.h
+++ b/rc/exec.h
@@ -74,11 +74,14 @@
 };
 extern void (*builtinfunc(char *name))(void);
 
+void execread(void), execns(void);
+void execbind(void), execmount(void), execunmount(void);
 void execcd(void), execwhatis(void), execeval(void), execexec(void);
 int execforkexec(void);
 void execexit(void), execshift(void);
 void execwait(void), execumask(void), execdot(void), execflag(void);
 void execfunc(var*), execcmds(io*, char*, var*, redir*);
+
 void startfunc(var*, word*, var*, redir*);
 
 char *srcfile(thread*);
--- a/rc/rcmain
+++ b/rc/rcmain
@@ -29,9 +29,9 @@
 	}
 	status=''
 	if(! ~ $#* 0) . $*
-	. -i /dev/fd/0
+	. -i /fd/0
 }
-if not if(~ $#* 0) . /dev/fd/0
+if not if(~ $#* 0) . /fd/0
 if not{
 	status=''
 	. $*
--- a/rc/simple.c
+++ b/rc/simple.c
@@ -170,8 +170,268 @@
 }
 
 void
+chars(int fd, int multi, vlong count, char *file)
+{
+	char buf[8*1024];
+	vlong m;
+	int n;
+
+	for(m = 0; m < count; m += n){
+		n = sizeof(buf);
+		if(n > (count - m))
+			n = count - m;
+		if((n = read(fd, buf, n)) < 0){
+			fprint(2, "read: error reading %s: %r\n", file);
+			exits("read error");
+		}
+		if(n == 0){
+			if(m == 0)
+				setstatus("eof");
+			break;
+		}
+		write(1, buf, n);
+	}
+}
+
+int
+line(int fd, char *file)
+{
+	char c;
+	int m, n, nalloc;
+	char *buf;
+
+	nalloc = 0;
+	buf = nil;
+	for(m=0; ; ){
+		n = read(fd, &c, 1);
+		if(n < 0){
+			fprint(2, "read: error reading %s: %r\n", file);
+			exits("read error");
+		}
+		if(n == 0){
+			if(m == 0)
+				setstatus("eof");
+			break;
+		}
+		if(m == nalloc){
+			nalloc += 1024;
+			buf = realloc(buf, nalloc);
+			if(buf == nil){
+				fprint(2, "read: malloc error: %r\n");
+				exits("malloc");
+			}
+		}
+		buf[m++] = c;
+		if(c == '\n')
+			break;
+	}
+	if(m > 0)
+		write(1, buf, m);
+	free(buf);
+	return m;
+}
+
+void
+lines(int fd, int multi, vlong count, char *file)
+{
+	do{
+		if(line(fd, file) == 0)
+			break;
+	}while(multi || --count > 0);
+}
+
+void
+execread(void)
+{
+//	print("Execread\n");
+	void (*proc)(int, int, vlong, char*);
+	word *a;
+	int fd, multi = 0;
+	vlong num = 0;
+	popword(); /* "read" */
+	proc = lines;
+	while(runq->argv->words && runq->argv->words->word[0]=='-'){
+		char *f = runq->argv->words->word+1;
+		if(*f == '-'){
+			popword();
+			break;
+		}
+		proc = lines;
+		for(; *f; f++){
+			switch(*f){
+			case 'c':
+				num = atoll(runq->argv->words->next->word);
+				proc = chars;
+				break;
+			case 'n':
+				num = atoi(runq->argv->words->next->word);
+				break;
+			case 'm':
+				multi = 1;
+				break;
+			default:
+				pfmt(err, "Usage: read [ -m | -n nlines | -c nbytes | -r nrunes ] [ file ... ]\n");
+				setstatus("read usage");
+				poplist();
+				return;
+			}
+		}
+		popword();
+	}
+	if(count(runq->argv->words)==0){
+		(*proc)(0, multi, num, "<stdin>");
+	} else {
+		a = runq->argv->words->next;
+		for(;a;a = a->next){
+			fd = open(a->word, OREAD);
+			if(fd < 0){
+				fprint(2, "read: can't open %s: %r\n", a->word);
+				exits("open");
+			}
+			(*proc)(fd, multi, num, a->word);
+			close(fd);
+		}
+	}
+}
+
+void
+execns(void)
+{
+//print("Execns\n");
+}
+
+void
+execbind(void)
+{
+//print("Execbind\n");
+	ulong flag;
+	int qflag = 0;
+	popword(); /* "bind" */
+	while(runq->argv->words && runq->argv->words->word[0]=='-'){
+		char *f = runq->argv->words->word+1;
+		if(*f == '-'){
+			popword();
+			break;
+		}
+		for(; *f; f++){
+			switch(*f){
+			case 'a':
+				flag |= MAFTER;
+				break;
+			case 'b':
+				flag |= MBEFORE;
+				break;
+			case 'c':
+				flag |= MCREATE;
+				break;
+			case 'q':
+				qflag = 1;
+				break;
+			default:
+				goto Usage;
+			}
+		}
+		popword();
+	}
+	if(count(runq->argv->words)!=2 || (flag&MAFTER)&&(flag&MBEFORE)){
+		goto Usage;
+	}
+	if(bind(runq->argv->words->word, runq->argv->words->next->word, flag) == -1){
+		if(qflag)
+			return;
+		Xerror1("bind error");
+	}
+	return;
+Usage:
+	Xerror1("usage: bind [-b|-a|-c|-bc|-ac] new old");
+	return;
+}
+
+void
+catch(void *, char *m)
+{
+	pfmt(err, "%s: %s\n", argv0, m);
+}
+
+void
+execmount(void)
+{
+//print("Execmount\n");
+	char *spec = "";
+	int flag = MREPL;
+	int qflag, noauth, fd;
+	qflag = noauth = 0;
+
+	popword(); /* mount */
+	while(runq->argv->words && runq->argv->words->word[0]=='-'){
+		char *f = runq->argv->words->word+1;
+		if(*f == '-'){
+			popword();
+			break;
+		}
+		for(; *f; f++){
+			switch(*f){
+			case 'a':
+				flag |= MAFTER;
+				break;
+			case 'b':
+				flag |= MBEFORE;
+				break;
+			case 'c':
+				flag |= MCREATE;
+				break;
+			case 'C':
+				flag |= MCACHE;
+				break;
+			case 'n':
+				noauth = 1;
+				break;
+			case 'q':
+				qflag = 1;
+				break;
+			default:
+				goto Usage;
+			}
+		}
+		popword();
+	}
+	if(count(runq->argv->words)==3)
+		spec = runq->argv->words->next->next->word;
+	else if(count(runq->argv->words)!=2)
+		goto Usage;
+	if((flag&MAFTER)&&(flag&MBEFORE))
+		goto Usage;
+	fd = Open(runq->argv->words->word, ORDWR);
+	if(fd < 0){
+		if(qflag)
+			return;
+		pfmt(err, "mount: can't open %s\n", runq->argv->words->word);
+		return;
+	}
+	notify(catch);
+	if(sysmount(fd, -1, runq->argv->words->next->word, flag, spec) < 0){
+		if(qflag)
+			return;
+		pfmt(err, "mount: %r\n");
+		setstatus("mount error");
+		poplist();
+	}
+	return;
+Usage:
+	Xerror1("usage: mount [-a|-b] [-cCnNq] [-k keypattern] /srv/service dir [spec]");
+	return;
+}
+
+void
+execunmount(void)
+{
+	//unmount
+}
+
+void
 execexec(void)
 {
+//	print("Execexec\n");
 	char **argv;
 	word *path;
 
@@ -196,6 +456,7 @@
 void
 execfunc(var *func)
 {
+//	print("Execfunc\n");
 	popword();	/* name */
 	startfunc(func, Poplist(), runq->local, runq->redir);
 }
@@ -206,7 +467,7 @@
 	word *a = runq->argv->words;
 	word *cdpath;
 	char *dir;
-
+//	print("Execcd\n");
 	setstatus("can't cd");
 	switch(count(a)){
 	default:
@@ -246,6 +507,7 @@
 void
 execexit(void)
 {
+//	print("Execexit\n");
 	switch(count(runq->argv->words)){
 	default:
 		pfmt(err, "Usage: exit [status]\nExiting anyway\n");
@@ -261,6 +523,7 @@
 	int n;
 	word *a;
 	var *star;
+//	print("execshift\n");
 	switch(count(runq->argv->words)){
 	default:
 		pfmt(err, "Usage: shift [n]\n");
@@ -309,7 +572,7 @@
 execcmds(io *input, char *file, var *local, redir *redir)
 {
 	static union code rdcmds[5];
-
+//	print("Execcmds\n");
 	if(rdcmds[0].i==0){
 		rdcmds[0].i = 1;
 		rdcmds[1].s="*rdcmds*";
@@ -330,7 +593,7 @@
 	char *cmds;
 	int len;
 	io *f;
-
+//print("Execeval\n");
 	popword();	/* "eval" */
 
 	if(runq->argv->words==0){
@@ -356,7 +619,7 @@
 	int fd, bflag, iflag, qflag;
 	word *path, *argv;
 	char *file;
-
+//print("Execdot\n");
 	popword();	/* "." */
 
 	bflag = iflag = qflag = 0;
@@ -398,7 +661,7 @@
 		fd = Open(file, 0);
 		if(fd >= 0)
 			break;
-		if(strcmp(file, "/dev/stdin")==0){	/* for sun & ucb */
+		if(strcmp(file, "/fd/0")==0){
 			fd = open("/dev/cons", OREAD);
 		}
 		free(file);
@@ -431,6 +694,7 @@
 void
 execflag(void)
 {
+//	print("Execflag\n");
 	char *letter, *val;
 	switch(count(runq->argv->words)){
 	case 2:
@@ -466,6 +730,7 @@
 	io *out;
 	int found, sep;
 	a = runq->argv->words->next;
+//	print("Execwhatis\n");
 	if(a==0){
 		Xerror1("Usage: whatis name ...");
 		return;
@@ -521,6 +786,7 @@
 void
 execwait(void)
 {
+//	print("Execwait\n");
 	switch(count(runq->argv->words)){
 	default:
 		Xerror1("Usage: wait [pid]");