code: 9ferno

Download patch

ref: 9febeeb92c8dd89a519a1c45bc67648b5284d3ab
parent: f86de033419f1c8733da7d05a9b824bcdb6c3aac
author: 9ferno <gophone2015@gmail.com>
date: Wed Nov 10 16:29:10 EST 2021

fixed initialization bugs with the updated proc.c

--- a/appl/cmd/sh/sh.b
+++ b/appl/cmd/sh/sh.b
@@ -94,7 +94,7 @@
 
 badmodule(path: string)
 {
-	sys->fprint(sys->fildes(2), "sh: cannot load %s: %r\n", path);
+	sys->fprint(sys->fildes(2), "sh: badmodule() cannot load %s: %r\n", path);
 	raise "fail:bad module" ;
 }
 
@@ -782,6 +782,7 @@
 runexternal(ctxt: ref Context, args: list of ref Listnode, last: int): string
 {
 	progname := (hd args).word;
+	if (DEBUG) debug(sys->sprint("runexternal progname %s\n", progname));
 	disfile := 0;
 	if (len progname >= 4 && progname[len progname-4:] == ".dis")
 		disfile = 1;
@@ -801,9 +802,11 @@
 		else
 			path = progname;
 
+		if (DEBUG) debug(sys->sprint("runexternal path %s\n", path));
 		npath := path;
 		if (!disfile)
 			npath += ".dis";
+		if (DEBUG) debug(sys->sprint("runexternal npath %s\n", npath));
 		mod := load Command npath;
 		if (mod != nil) {
 			argv := list2stringlist(args);
--- a/appl/lib/bufio.b
+++ b/appl/lib/bufio.b
@@ -36,12 +36,15 @@
 	return ref Iobuf(fd, array[Bufsize+Maxrune] of byte, 0, 0, 0, big 0, big 0, mode, mode);
 }
 
+# seeking on a pipe throws out an error in kseek(), hence the fd != 0
 fopen(fd: ref Sys->FD, mode: int): ref Iobuf
 {
 	if (sys == nil)
 		sys = load Sys Sys->PATH;
-	if ((filpos := sys->seek(fd, big 0, 1)) < big 0)
-		filpos = big 0;
+	filpos := big 0;
+#	stdin := sys->fildes(0);
+#	if ((fd != stdin) && (filpos = sys->seek(fd, big 0, 1)) < big 0)
+#		filpos = big 0;
 	return ref Iobuf(fd, array[Bufsize+Maxrune] of byte, 0, 0, 0, filpos, filpos, mode, mode);
 }
 
--- a/dis/diskparts
+++ b/dis/diskparts
@@ -1,4 +1,4 @@
-#!/dis/sh
+#!/dis/sh -n
 load std
 
 disks=$*
@@ -10,7 +10,9 @@
 # no plan 9 partition table will delete all extant partitions.
 fn setup {
 	disk=$1
+	parts=()
 	if {ftest -f $disk^/data && ftest -f $disk^/ctl} {
+		#disk/fdisk -p $disk^/data | grep -v '^delpart '
 		{ @{disk/fdisk -p $disk^/data} |
 			grep -v '^delpart ' >$disk^/ctl } >[2]/dev/null
 	}
@@ -21,6 +23,7 @@
 
 	for part in $parts {
 		if{ftest -f $part} {
+			#disk/prep -p $part | grep -v '^delpart '
 			{ disk/prep -p $part |
 				grep -v '^delpart ' >$disk^/ctl } >[2]/dev/null
 		}
@@ -27,7 +30,7 @@
 	}
 }
 
-if{~ $#disks 0}{
+if {~ $#disks 0}{
 	# set up any disk partitions
 	or { ftest -e /dev/sdctl } { bind -b '#S' /dev }
 	for disk in /dev/sd* { setup $disk }
@@ -44,6 +47,7 @@
 	#}
 } {
 	for disk in $disks {
+		echo setup $disk
 		setup $disk
 	}
 }
--- a/dis/init
+++ b/dis/init
@@ -1,4 +1,4 @@
-#!/dis/sh
+#!/dis/sh -n
 
 # boot initialization
 #	configure boot devices
@@ -197,7 +197,7 @@
 	# if tcp, bind ether0 as ipifc and get on with it
 
 	if { ~ $"connectmethod local }{
-		sh /dis/diskparts
+		sh -n /dis/diskparts
 		mountlocal $localdevice
 	} {~ $"connectmethod tcp}{
 		if{~ $"localdevice dhcp}{
@@ -227,10 +227,10 @@
 	#	avoids putting machine specific stuff in devroot
 	and {! ~ $"sysname ''} {
 		ftest -f /lib/init/$sysname }{
-		sh /lib/init/$sysname
+		sh -n /lib/init/$sysname
 	}
 }
 
 # if I add /lib/sh/profile to devroot,
 #	all the above binds can be moved to $home/namespace
-sh -l -i #-l # to run the /lib/sh/profile
+sh -n -l -i #-l # to run the /lib/sh/profile
--- a/emu/port/fns.h
+++ b/emu/port/fns.h
@@ -231,11 +231,11 @@
 int		kmount(int, int, char*, int, char*);
 int		kunmount(char*, char*);
 int		kopen(char*, int);
-long		kread(int, void*, long);
+s32		kread(int, void*, s32);
 int		kremove(char*);
 vlong	kseek(int, vlong, int);
 int		kstat(char*, uchar*, int);
-long		kwrite(int, void*, long);
+s32		kwrite(int, void*, s32);
 int		kwstat(char*, uchar*, int);
 Dir*		kdirstat(char*);
 Dir*		kdirfstat(int);
--- a/emu/port/main.c
+++ b/emu/port/main.c
@@ -378,6 +378,7 @@
 	error(buf);
 }
 
+/* os uses struct Label instead of jmp_buf */
 void
 showjmpbuf(char *str)
 {
--- a/emu/port/sysfile.c
+++ b/emu/port/sysfile.c
@@ -655,14 +655,14 @@
 	return n;
 }
 
-long
-kread(int fd, void *va, long n)
+s32
+kread(int fd, void *va, s32 n)
 {
 	return rread(fd, va, n, nil);
 }
 
-long
-kpread(int fd, void *va, long n, vlong off)
+s32
+kpread(int fd, void *va, s32 n, s64 off)
 {
 	return rread(fd, va, n, &off);
 }
@@ -865,14 +865,14 @@
 	return m;
 }
 
-long
-kwrite(int fd, void *va, long n)
+s32
+kwrite(int fd, void *va, s32 n)
 {
 	return rwrite(fd, va, n, nil);
 }
 
-long
-kpwrite(int fd, void *va, long n, vlong off)
+s32
+kpwrite(int fd, void *va, s32 n, s64 off)
 {
 	return rwrite(fd, va, n, &off);
 }
--- a/libinterp/xec.c
+++ b/libinterp/xec.c
@@ -735,7 +735,7 @@
 	R.FP = f->fp;
 	if(R.FP == nil) {
 		R.FP = (uchar*)f;
-		error("");
+		error(""); /* goto vmachine()'s waserror() and call progexit() there */
 	}
 	R.SP = (uchar*)f;
 	R.PC = f->lr;
--- a/os/init/disinit.b
+++ b/os/init/disinit.b
@@ -67,16 +67,16 @@
 	sh := load Sh "/dis/sh.dis";
 	(s, nil) := sys->stat("/dis/init");
 	if(s == 0){
-		sys->print("spawn sh -n -x /dis/init\n");
+		sys->print("spawn sh -n /dis/init\n");
 		{
-			sh->init(nil, "sh" :: "-n" :: "-x" :: "/dis/init" :: nil);
+			sh->init(nil, "sh" :: "-n" :: "/dis/init" :: nil);
 		} exception e {
 			"*" =>
 				sys->fprint(stderr, "dis/init status: %s\nStarting fallback shell\n", e);
 				# fallback console
 				sh1 := load Sh "/dis/sh.dis";
-				sys->print("sh -x\n");
-				sh1->init(nil, "sh" :: "-n" :: "-x" :: nil);
+				sys->print("sh -n\n");
+				sh1->init(nil, "sh" :: "-n" :: nil);
 		}
 	}{
 		# fallback console
--- a/os/pc64/fns.h
+++ b/os/pc64/fns.h
@@ -215,7 +215,6 @@
 int	kbdinready(void);
 
 #define	userureg(ur)	(((ur)->cs & 3) == 3)
-#define	waserror()	(up->nerrlab++, setlabel(&up->errlab[up->nerrlab-1]))
 #define getcallerpc(x)	(((uintptr*)(x))[-1])
 #define KADDR(a)	((void*)((uintptr)(a)|KZERO))
 #define PADDR(a)	((uintptr)(a)&~(uintptr)KZERO)
--- a/os/pc64/l.s
+++ b/os/pc64/l.s
@@ -612,19 +612,23 @@
 
 /*
  * Label consists of a stack pointer and a programme counter
+ * We need to store the return PC so we can jump back to the
+ * 	same place on a gotolabel() but with a different return
+ *	value this time.
+ * emu uses jmp_buf and setjmp()/longjmp() to do the same
  */
 TEXT gotolabel(SB), 1, $-4
-	MOVQ	0(RARG), SP			/* restore SP */
-	MOVQ	8(RARG), AX			/* put return PC on the stack */
-	MOVQ	AX, 0(SP)
+	MOVQ	0(RARG), SP			/* restore SP from the address in the first argument */
+	MOVQ	8(RARG), BX			/* put return PC on the stack */
+	MOVQ	BX, 0(SP)			/*	to top of stack so the next RET uses it */
 	MOVL	$1, AX				/* return 1 */
 	RET
 
 TEXT setlabel(SB), 1, $-4
-	MOVQ	SP, 0(RARG)			/* store SP */
-	MOVQ	0(SP), BX			/* store return PC */
-	MOVQ	BX, 8(RARG)
-	MOVL	$0, AX				/* return 0 */
+	MOVQ	SP, 0(RARG)		/* store SP to the address in the first argument */
+	MOVQ	0(SP), BX		/* store return PC - top of stack */
+	MOVQ	BX, 8(RARG)		/*		to the next location at the same address */
+	MOVL	$0, AX			/* return 0 */
 	RET
 
 TEXT halt(SB), 1, $-4
--- a/os/port/portfns.h
+++ b/os/port/portfns.h
@@ -213,7 +213,8 @@
 void		pexit(char*, int);
 void		pgrpcpy(Pgrp*, Pgrp*);
 ulong		pidalloc(Proc*);
-#define		poperror()		up->nerrlab--
+#define		waserror()	setlabel(&up->errlab[up->nerrlab++])
+#define		poperror()	up->nerrlab--
 int		poolread(char*, int, u64);
 void		poolsize(Pool *, u64, int);
 int		postnote(Proc *, int, char *, int);
--- a/os/port/proc.c
+++ b/os/port/proc.c
@@ -991,19 +991,44 @@
 }
 
 void
+showerrlabs(void)
+{
+	int i;
+
+	for(i=0; i<up->nerrlab; i++){
+		print("i %d SP 0x%p PC 0x%p\n", i, up->errlab[i].sp, up->errlab[i].pc);
+	}
+}
+
+/* we set the errlab[NERR-1] to know where the error was raised(?) */
+void
 error(char *err)
 {
 	if(up == nil)
 		panic("error(%s) not in a process", err);
 	spllo();
-	if(up->nerrlab > NERR)
+
+	if(up->nerrlab >= NERR)
 		panic("error stack too deep");
-	if(err != up->env->errstr)
-		kstrcpy(up->env->errstr, err, ERRMAX);
-	setlabel(&up->errlab[NERR-1]);
+	kstrcpy(up->env->errstr, err, ERRMAX);
+	/* proactively show issues */
+	/* if(err[0] != '\0')
+		print("up->nerrlab %d error %s raised by 0x%zx\n",
+			up->nerrlab, err, getcallerpc(&err));
+	showerrlabs();
+	*/
+	setlabel(&up->errlab[NERR-1]); /* to store the location where error() was raised(?) */
 	nexterror();
 }
 
+void
+nexterror(void)
+{
+	if(up->nerrlab < 1)
+		panic("nothing on the error stack to go back to");
+	gotolabel(&up->errlab[--up->nerrlab]);
+}
+
 #include "errstr.h"
 
 /* Set kernel error string */
@@ -1052,12 +1077,6 @@
 	vseprint(buf, buf+sizeof(buf), fmt, arg);
 	va_end(arg);
 	kstrcpy(up->env->errstr, buf, ERRMAX);
-}
-
-void
-nexterror(void)
-{
-	gotolabel(&up->errlab[--up->nerrlab]);
 }
 
 /* for dynamic modules - functions not macros */
--- a/os/port/sysfile.c
+++ b/os/port/sysfile.c
@@ -1086,8 +1086,18 @@
 		cclose(c);
 		nexterror();
 	}
-	if(devtab[c->type]->dc == L'|')
+	if(devtab[c->type]->dc == L'|'){
+		/* print("kseek on stream called by 0x%p\n", getcallerpc(&fd)); */
+		/*
+		 * grep.b calls bufio.fopen() which seeks first.
+		 * An error() here breaks grep.b
+		 * fixed in bufio.fopen()
+		 */
+		/*cclose(c);
+		poperror();
+		return -1;*/
 		error(Eisstream);
+	}
 
 	off = 0;
 	switch(type){