Browse Source

Plan 9 from Bell Labs 2013-06-14

David du Colombier 11 years ago
parent
commit
32da3aa626
50 changed files with 327 additions and 213 deletions
  1. 20 7
      rc/bin/fshalt
  2. 1 0
      sys/games/lib/fortunes
  3. 7 37
      sys/man/8/booting
  4. 6 0
      sys/man/8/fshalt
  5. 5 4
      sys/src/9/ip/arp.c
  6. 1 1
      sys/src/9/ip/chandial.c
  7. 2 2
      sys/src/9/ip/ethermedium.c
  8. 1 1
      sys/src/9/ip/icmp.c
  9. 1 1
      sys/src/9/ip/icmp6.c
  10. 2 2
      sys/src/9/ip/ipifc.c
  11. 2 1
      sys/src/9/ip/rudp.c
  12. 9 2
      sys/src/9/pc/dat.h
  13. 4 3
      sys/src/9/pc/devarch.c
  14. 1 0
      sys/src/9/pc/fns.h
  15. 22 14
      sys/src/9/pc/main.c
  16. 1 0
      sys/src/9/pc/mp.c
  17. 5 4
      sys/src/9/pc/trap.c
  18. 1 1
      sys/src/9/port/devcap.c
  19. 24 15
      sys/src/9/port/devdraw.c
  20. 2 2
      sys/src/9/port/devdup.c
  21. 3 2
      sys/src/9/port/devflash.c
  22. 1 1
      sys/src/9/port/devmouse.c
  23. 4 3
      sys/src/9/port/devproc.c
  24. 4 2
      sys/src/9/port/devsd.c
  25. 1 1
      sys/src/9/port/devsdp.c
  26. 2 1
      sys/src/9/port/devsegment.c
  27. 4 2
      sys/src/9/port/devsrv.c
  28. 2 2
      sys/src/9/port/devssl.c
  29. 1 1
      sys/src/9/port/devtls.c
  30. 5 4
      sys/src/9/port/edf.c
  31. 2 3
      sys/src/9/port/fault.c
  32. 3 0
      sys/src/9/port/fpi.c
  33. 5 0
      sys/src/9/port/fpi.h
  34. 53 0
      sys/src/9/port/fpimem.c
  35. 7 1
      sys/src/9/port/rebootcmd.c
  36. 1 1
      sys/src/cmd/5c/gc.h
  37. 19 33
      sys/src/cmd/postscript/download/download.c
  38. 15 5
      sys/src/cmd/rc/exec.c
  39. 1 2
      sys/src/cmd/rc/lex.c
  40. 2 1
      sys/src/cmd/rc/pcmd.c
  41. 41 35
      sys/src/cmd/rc/pfnc.c
  42. 1 1
      sys/src/cmd/rc/plan9.c
  43. 1 1
      sys/src/cmd/rc/rc.h
  44. 1 0
      sys/src/cmd/rc/simple.c
  45. 11 6
      sys/src/cmd/rc/var.c
  46. 11 0
      sys/src/cmd/samterm/flayer.c
  47. 1 1
      sys/src/cmd/vc/gc.h
  48. 4 4
      sys/src/cmd/vl/obj.c
  49. 2 2
      sys/src/libmach/v.c
  50. 2 1
      sys/src/libmach/vdb.c

+ 20 - 7
rc/bin/fshalt

@@ -1,16 +1,28 @@
 #!/bin/rc
-# fshalt [-r] - sync (flush) and, if possible, halt all file servers
-#	and optionally reboot
+# fshalt [-r] [new-kernel] - sync (flush) and, if possible, halt all
+#	file servers and optionally reboot
 rfork nes
+kern=()
 kerncopy=()
 reboot=no
+fn usage {
+	echo usage: $1 '[-r] [new-kernel]' >[1=2]
+	exit usage
+}
+if (! ~ $#* 0)
+	switch ($1) {
+	case -r
+		reboot=yes
+		shift
+	case -*
+		usage $0
+	}
 switch ($#*) {
 case 0
 case 1
-	reboot=yes
+	kern = $1
 case *
-	echo usage: $0 '[-r]' >[1=2]
-	exit usage
+	usage $0
 }
 
 path=(/bin)
@@ -42,8 +54,9 @@ fn usekernel {
 
 # make a copy of the right kernel
 if (~ $reboot yes) {
-	kern=`{echo $terminal |
-		sed 's;^([^ ]+) .*/([^/ ]+).*$;/n/boot/'$cputype'/9\2;'}
+	if (~ $#kern 0)
+		kern=`{echo $terminal |
+			sed 's;^([^ ]+) .*/([^/ ]+).*$;/n/boot/'$cputype'/9\2;'}
 	if (isbootable $kern)
 		usekernel $kern
 	if not {

+ 1 - 0
sys/games/lib/fortunes

@@ -4311,3 +4311,4 @@ I fixed their fix and it does work.  - forsyth
 To maintain backward compatibility, the relationships between the many options are quite complex.  - ls(1) OS X Manual Page
 qemu: could not open serial device 'dev': Success
 DSM Terminator [ ABORT ] Finished [ 0 request(s) + 0 call(s) distributed in 5ms]
+Microsoft Office PowerPoint has encountered a problem and cannot exit.  We are sorry for the inconvenience.

+ 7 - 37
sys/man/8/booting

@@ -67,43 +67,13 @@ Proceed as for the PC terminal, but load
 .B /386/9pccpu
 or
 .BR /386/9pccpudisk .
-.SS SGI Challenge multiprocessor CPU Server
-The Challenge ROM monitor can boot from the Ethernet.
-To boot from the Ethernet, type
-.IP
-.EX
-.B bootp()/mips/9ch
-.EE
-.PP
-or use the ROM command
-.B setenv
-to set the variable
-.B bootfile
-to that same string and type
-.BR boot .
-To load a different file, tell
-.B bootp
-which file to load,
-and to force the download to come from a particular system,
-.BR bootp()system:file .
-Any arguments after
-.B bootp()file
-are passed to
-.BR /boot .
-If you are running a Plan 9
-.SM BOOTP
-server (see
-.IR dhcpd (8)),
-the file name can be omitted and the
-file specified by the
-.B bootf
-parameter for the machine in
-.B /lib/ndb
-will be downloaded by default.
-.PP
-Once the kernel is loaded,
-it prompts for the Ethernet
-protocol to use to reach the root file server; request the default.
+.
+.SS MIPS Routerboard CPU Server
+Configure RouterBOOT via the serial port (115200 baud)
+to always boot from Ethernet, and arrange to load
+.B /mips/9rb.elf
+in
+.IR ndb (6).
 .
 .SS ARM Systems
 All ARM systems are started by

+ 6 - 0
sys/man/8/fshalt

@@ -5,6 +5,8 @@ fshalt, reboot \- halt any local file systems and optionally reboot the system
 .B fshalt
 [
 .B -r
+] [
+.I new-kernel
 ]
 .br
 .B reboot
@@ -25,6 +27,10 @@ If given
 .BR -r ,
 .I fshalt
 will then reboot the machine.
+If
+.I new-kernel
+is given, it will be loaded as the new kernel rather than
+the currently-loaded kernel.
 The halting and rebooting is done by copying all necessary
 commands into a
 .IR ramfs (4)

+ 5 - 4
sys/src/9/ip/arp.c

@@ -523,10 +523,10 @@ enum
 char *aformat = "%-6.6s %-8.8s %-40.40I %-32.32s\n";
 
 static void
-convmac(char *p, uchar *mac, int n)
+convmac(char *p, char *ep, uchar *mac, int n)
 {
 	while(n-- > 0)
-		p += sprint(p, "%2.2ux", *mac++);
+		p = seprint(p, ep, "%2.2ux", *mac++);
 }
 
 int
@@ -552,8 +552,9 @@ arpread(Arp *arp, char *p, ulong offset, int len)
 		}
 		len--;
 		qlock(arp);
-		convmac(mac, a->mac, a->type->maclen);
-		n += sprint(p+n, aformat, a->type->name, arpstate[a->state], a->ip, mac);
+		convmac(mac, &mac[sizeof mac], a->mac, a->type->maclen);
+		n += snprint(p+n, Alinelen+1, aformat, a->type->name,
+			arpstate[a->state], a->ip, mac);	/* +1 for NUL */
 		qunlock(arp);
 	}
 

+ 1 - 1
sys/src/9/ip/chandial.c

@@ -66,7 +66,7 @@ call(char *clone, char *dest, DS *ds)
 	name[n] = 0;
 	for(p = name; *p == ' '; p++)
 		;
-	sprint(name, "%lud", strtoul(p, 0, 0));
+	snprint(name, sizeof name, "%lud", strtoul(p, 0, 0));
 	p = strrchr(clone, '/');
 	*p = 0;
 	if(ds->dir)

+ 2 - 2
sys/src/9/ip/ethermedium.c

@@ -412,7 +412,7 @@ etheraddmulti(Ipifc *ifc, uchar *a, uchar *)
 	int version;
 
 	version = multicastea(mac, a);
-	sprint(buf, "addmulti %E", mac);
+	snprint(buf, sizeof buf, "addmulti %E", mac);
 	switch(version){
 	case V4:
 		devtab[er->cchan4->type]->write(er->cchan4, buf, strlen(buf), 0);
@@ -434,7 +434,7 @@ etherremmulti(Ipifc *ifc, uchar *a, uchar *)
 	int version;
 
 	version = multicastea(mac, a);
-	sprint(buf, "remmulti %E", mac);
+	snprint(buf, sizeof buf, "remmulti %E", mac);
 	switch(version){
 	case V4:
 		devtab[er->cchan4->type]->write(er->cchan4, buf, strlen(buf), 0);

+ 1 - 1
sys/src/9/ip/icmp.c

@@ -393,7 +393,7 @@ icmpiput(Proto *icmp, Ipifc*, Block *bp)
 		break;
 	case TimeExceed:
 		if(p->code == 0){
-			sprint(m2, "ttl exceeded at %V", p->src);
+			snprint(m2, sizeof m2, "ttl exceeded at %V", p->src);
 
 			bp->rp += ICMP_IPSIZE+ICMP_HDRSIZE;
 			if(blocklen(bp) < MinAdvise){

+ 1 - 1
sys/src/9/ip/icmp6.c

@@ -765,7 +765,7 @@ icmpiput6(Proto *icmp, Ipifc *ipifc, Block *bp)
 
 	case TimeExceedV6:
 		if(p->code == 0){
-			sprint(m2, "ttl exceeded at %I", p->src);
+			snprint(m2, sizeof m2, "ttl exceeded at %I", p->src);
 
 			bp->rp += IPICMPSZ;
 			if(blocklen(bp) < 8){

+ 2 - 2
sys/src/9/ip/ipifc.c

@@ -1650,8 +1650,8 @@ ipifcadd6(Ipifc *ifc, char**argv, int argc)
 	if(!ifc->m->pref2addr)
 		return Ebadarg;
 	ifc->m->pref2addr(prefix, ifc->mac);	/* mac → v6 link-local addr */
-	sprint(addr, "%I", prefix);
-	sprint(preflen, "/%d", plen);
+	snprint(addr, sizeof addr, "%I", prefix);
+	snprint(preflen, sizeof preflen, "/%d", plen);
 	params[0] = "add";
 	params[1] = addr;
 	params[2] = preflen;

+ 2 - 1
sys/src/9/ip/rudp.c

@@ -202,7 +202,8 @@ rudpstartackproc(Proto *rudp)
 	if(rpriv->ackprocstarted == 0){
 		qlock(&rpriv->apl);
 		if(rpriv->ackprocstarted == 0){
-			sprint(kpname, "#I%drudpack", rudp->f->dev);
+			snprint(kpname, sizeof kpname, "#I%drudpack",
+				rudp->f->dev);
 			kproc(kpname, relackproc, rudp);
 			rpriv->ackprocstarted = 1;
 		}

+ 9 - 2
sys/src/9/pc/dat.h

@@ -19,6 +19,7 @@ typedef struct Page	Page;
 typedef struct PMMU	PMMU;
 typedef struct Proc	Proc;
 typedef struct Segdesc	Segdesc;
+typedef struct SFPssestate SFPssestate;
 typedef vlong		Tval;
 typedef struct Ureg	Ureg;
 typedef struct Vctl	Vctl;
@@ -101,7 +102,13 @@ struct	FPssestate		/* SSE fp state */
 	ulong	mxcsr;		/* MXCSR register state */
 	ulong	mxcsr_mask;	/* MXCSR mask register */
 	uchar	xregs[480];	/* extended registers */
-	uchar	alignpad[FPalign];
+};
+
+struct	SFPssestate		/* SSE fp state with alignment slop */
+{
+	FPssestate;
+	uchar	alignpad[FPalign]; /* slop to allow copying to aligned addr */
+	ulong	magic;		/* debugging: check for overrun */
 };
 
 /*
@@ -110,7 +117,7 @@ struct	FPssestate		/* SSE fp state */
  */
 union FPsave {
 	FPstate;
-	FPssestate;
+	SFPssestate;
 };
 
 struct Confmem

+ 4 - 3
sys/src/9/pc/devarch.c

@@ -414,7 +414,8 @@ archread(Chan *c, void *a, long n, vlong offset)
 	for(m = iomap.m; n > 0 && m != nil; m = m->next){
 		if(offset-- > 0)
 			continue;
-		sprint(p, "%8lux %8lux %-12.12s\n", m->start, m->end-1, m->tag);
+		seprint(p, &buf[n], "%8lux %8lux %-12.12s\n", m->start,
+			m->end-1, m->tag);
 		p += Linelen;
 		n--;
 	}
@@ -722,8 +723,8 @@ cpuidprint(void)
 	int i;
 	char buf[128];
 
-	i = sprint(buf, "cpu%d: %s%dMHz ", m->machno, m->machno < 10? " ": "",
-		m->cpumhz);
+	i = snprint(buf, sizeof buf, "cpu%d: %s%dMHz ", m->machno,
+		m->machno < 10? " ": "", m->cpumhz);
 	if(m->cpuidid[0])
 		i += sprint(buf+i, "%12.12s ", m->cpuidid);
 	seprint(buf+i, buf + sizeof buf - 1,

+ 1 - 0
sys/src/9/pc/fns.h

@@ -34,6 +34,7 @@ void	fpoff(void);
 void	fpon(void);
 void	(*fprestore)(FPsave*);
 void	(*fpsave)(FPsave*);
+void	fpsavealloc(void);
 void	fpsserestore(FPsave*);
 void	fpsserestore0(FPsave*);
 void	fpssesave(FPsave*);

+ 22 - 14
sys/src/9/pc/main.c

@@ -75,6 +75,14 @@ options(void)
 extern void mmuinit0(void);
 extern void (*i8237alloc)(void);
 
+void
+fpsavealloc(void)
+{
+	m->fpsavalign = mallocalign(sizeof(FPssestate), FPalign, 0, 0);
+	if (m->fpsavalign == nil)
+		panic("cpu%d: can't allocate fpsavalign", m->machno);
+}
+
 void
 main(void)
 {
@@ -104,6 +112,7 @@ main(void)
 	printinit();
 	cpuidprint();
 	mmuinit();
+	fpsavealloc();
 	if(arch->intrinit)	/* launches other processors on an mp */
 		arch->intrinit();
 	timersinit();
@@ -306,10 +315,11 @@ bootargs(void *base)
 	cp[BOOTLINELEN-1] = 0;
 	buf[0] = 0;
 	if(strncmp(cp, "fd", 2) == 0){
-		sprint(buf, "local!#f/fd%lddisk", strtol(cp+2, 0, 0));
+		snprint(buf, sizeof buf, "local!#f/fd%lddisk",
+			strtol(cp+2, 0, 0));
 		av[ac++] = pusharg(buf);
 	} else if(strncmp(cp, "sd", 2) == 0){
-		sprint(buf, "local!#S/sd%c%c/fs", *(cp+2), *(cp+3));
+		snprint(buf, sizeof buf, "local!#S/sd%c%c/fs", *(cp+2), *(cp+3));
 		av[ac++] = pusharg(buf);
 	} else if(strncmp(cp, "ether", 5) == 0)
 		av[ac++] = pusharg("-n");
@@ -527,7 +537,7 @@ mathnote(void)
 
 /*
  * sse fp save and restore buffers have to be 16-byte (FPalign) aligned,
- * so we shuffle the data up and down as needed or make copies.
+ * so we shuffle the data down as needed or make copies.
  */
 
 void
@@ -535,10 +545,13 @@ fpssesave(FPsave *fps)
 {
 	FPsave *afps;
 
+	fps->magic = 0x1234;
 	afps = (FPsave *)ROUND(((uintptr)fps), FPalign);
 	fpssesave0(afps);
 	if (fps != afps)  /* not aligned? shuffle down from aligned buffer */
-		memmove(fps, afps, sizeof(FPssestate) - FPalign);
+		memmove(fps, afps, sizeof(FPssestate));
+	if (fps->magic != 0x1234)
+		print("fpssesave: magic corrupted\n");
 }
 
 void
@@ -546,20 +559,15 @@ fpsserestore(FPsave *fps)
 {
 	FPsave *afps;
 
+	fps->magic = 0x4321;
 	afps = (FPsave *)ROUND(((uintptr)fps), FPalign);
 	if (fps != afps) {
-		if (m->fpsavalign == nil)
-			m->fpsavalign = mallocalign(sizeof(FPssestate),
-				FPalign, 0, 0);
-		if (m->fpsavalign)
-			afps = m->fpsavalign;
-		/* copy or shuffle up to make aligned */
-		memmove(afps, fps, sizeof(FPssestate) - FPalign);
+		afps = m->fpsavalign;
+		memmove(afps, fps, sizeof(FPssestate));	/* make aligned copy */
 	}
 	fpsserestore0(afps);
-	/* if we couldn't make a copy, shuffle regs back down */
-	if (fps != afps && afps != m->fpsavalign)
-		memmove(fps, afps, sizeof(FPssestate) - FPalign);
+	if (fps->magic != 0x4321)
+		print("fpsserestore: magic corrupted\n");
 }
 
 /*

+ 1 - 0
sys/src/9/pc/mp.c

@@ -399,6 +399,7 @@ squidboy(Apic* apic)
 //	iprint("Hello Squidboy\n");
 
 	machinit();
+	fpsavealloc();
 	mmuinit();
 
 	cpuidentify();

+ 5 - 4
sys/src/9/pc/trap.c

@@ -363,7 +363,7 @@ trap(Ureg* ureg)
 	}
 	else if(vno < nelem(excname) && user){
 		spllo();
-		sprint(buf, "sys: trap: %s", excname[vno]);
+		snprint(buf, sizeof buf, "sys: trap: %s", excname[vno]);
 		postnote(up, 1, buf, NDebug);
 	}
 	else if(vno >= VectorPIC && vno != VectorSYSCALL){
@@ -591,7 +591,7 @@ debugbpt(Ureg* ureg, void*)
 		panic("kernel bpt");
 	/* restore pc to instruction that caused the trap */
 	ureg->pc--;
-	sprint(buf, "sys: breakpoint");
+	snprint(buf, sizeof buf, "sys: breakpoint");
 	postnote(up, 1, buf, NDebug);
 }
 
@@ -641,7 +641,7 @@ fault386(Ureg* ureg, void*)
 		}
 		checkpages();
 		checkfault(addr, ureg->pc);
-		sprint(buf, "sys: trap: fault %s addr=0x%lux",
+		snprint(buf, sizeof buf, "sys: trap: fault %s addr=0x%lux",
 			read ? "read" : "write", addr);
 		postnote(up, 1, buf, NDebug);
 	}
@@ -806,7 +806,8 @@ notify(Ureg* ureg)
 		l = strlen(n->msg);
 		if(l > ERRMAX-15)	/* " pc=0x12345678\0" */
 			l = ERRMAX-15;
-		sprint(n->msg+l, " pc=0x%.8lux", ureg->pc);
+		seprint(n->msg+l, &n->msg[sizeof n->msg], " pc=0x%.8lux",
+			ureg->pc);
 	}
 
 	if(n->flag!=NUser && (up->notified || up->notify==0)){

+ 1 - 1
sys/src/9/port/devcap.c

@@ -112,7 +112,7 @@ hashstr(uchar *hash)
 	int i;
 
 	for(i = 0; i < Hashlen; i++)
-		sprint(buf+2*i, "%2.2ux", hash[i]);
+		seprint(buf+2*i, &buf[sizeof buf], "%2.2ux", hash[i]);
 	buf[2*Hashlen] = 0;
 	return buf;
 }

+ 24 - 15
sys/src/9/port/devdraw.c

@@ -228,9 +228,10 @@ drawgen(Chan *c, char*, Dirtab*, int, int s, Dir *dp)
 		case Q3rd:
 			cl = drawclientofpath(c->qid.path);
 			if(cl == nil)
-				strcpy(up->genbuf, "??");
+				strncpy(up->genbuf, "??", sizeof up->genbuf);
 			else
-				sprint(up->genbuf, "%d", cl->clientid);
+				snprint(up->genbuf, sizeof up->genbuf,
+					"%d", cl->clientid);
 			mkqid(&q, Q2nd, 0, QTDIR);
 			devdir(c, q, up->genbuf, 0, eve, 0500, dp);
 			break;
@@ -272,7 +273,8 @@ drawgen(Chan *c, char*, Dirtab*, int, int s, Dir *dp)
 			cl = sdraw.client[s-1];
 			if(cl == 0)
 				return 0;
-			sprint(up->genbuf, "%d", cl->clientid);
+			snprint(up->genbuf, sizeof up->genbuf, "%d",
+				cl->clientid);
 			mkqid(&q, (s<<QSHIFT)|Q3rd, 0, QTDIR);
 			devdir(c, q, up->genbuf, 0, eve, 0555, dp);
 			return 1;
@@ -1186,10 +1188,13 @@ drawread(Chan *c, void *a, long n, vlong off)
 				error(Enodrawimage);
 			i = di->image;
 		}
-		n = sprint(a, "%11d %11d %11s %11d %11d %11d %11d %11d %11d %11d %11d %11d ",
-			cl->clientid, cl->infoid, chantostr(buf, i->chan), (i->flags&Frepl)==Frepl,
+		n = snprint(a, n,
+			"%11d %11d %11s %11d %11d %11d %11d %11d %11d %11d %11d %11d ",
+			cl->clientid, cl->infoid, chantostr(buf, i->chan),
+			(i->flags&Frepl)==Frepl,
 			i->r.min.x, i->r.min.y, i->r.max.x, i->r.max.y,
-			i->clipr.min.x, i->clipr.min.y, i->clipr.max.x, i->clipr.max.y);
+			i->clipr.min.x, i->clipr.min.y, i->clipr.max.x,
+			i->clipr.max.y);
 		cl->infoid = -1;
 		break;
 
@@ -1201,7 +1206,9 @@ drawread(Chan *c, void *a, long n, vlong off)
 		m = 0;
 		for(index = 0; index < 256; index++){
 			getcolor(index, &red, &green, &blue);
-			m += sprint((char*)p+m, "%11d %11lud %11lud %11lud\n", index, red>>24, green>>24, blue>>24);
+			m += snprint((char*)p+m, 4*12*256+1 - m,
+				"%11d %11lud %11lud %11lud\n", index,
+				red>>24, green>>24, blue>>24);
 		}
 		n = readstr(offset, a, n, (char*)p);
 		free(p);
@@ -1370,7 +1377,7 @@ printmesg(char *fmt, uchar *a, int plsprnt)
 {
 	char buf[256];
 	char *p, *q;
-	int s;
+	int s, left;
 
 	if(1|| plsprnt==0){
 		SET(s,q,p);
@@ -1380,32 +1387,34 @@ printmesg(char *fmt, uchar *a, int plsprnt)
 	q = buf;
 	*q++ = *a++;
 	for(p=fmt; *p; p++){
+		left = sizeof buf - 2 - (q - buf);	/* 2 for \n\0 */
 		switch(*p){
 		case 'l':
-			q += sprint(q, " %ld", (long)BGLONG(a));
+			q += snprint(q, left, " %ld", (long)BGLONG(a));
 			a += 4;
 			break;
 		case 'L':
-			q += sprint(q, " %.8lux", (ulong)BGLONG(a));
+			q += snprint(q, left, " %.8lux", (ulong)BGLONG(a));
 			a += 4;
 			break;
 		case 'R':
-			q += sprint(q, " [%d %d %d %d]", BGLONG(a), BGLONG(a+4), BGLONG(a+8), BGLONG(a+12));
+			q += snprint(q, left, " [%d %d %d %d]", BGLONG(a),
+				BGLONG(a+4), BGLONG(a+8), BGLONG(a+12));
 			a += 16;
 			break;
 		case 'P':
-			q += sprint(q, " [%d %d]", BGLONG(a), BGLONG(a+4));
+			q += snprint(q, left, " [%d %d]", BGLONG(a), BGLONG(a+4));
 			a += 8;
 			break;
 		case 'b':
-			q += sprint(q, " %d", *a++);
+			q += snprint(q, left, " %d", *a++);
 			break;
 		case 's':
-			q += sprint(q, " %d", BGSHORT(a));
+			q += snprint(q, left, " %d", BGSHORT(a));
 			a += 2;
 			break;
 		case 'S':
-			q += sprint(q, " %.4ux", BGSHORT(a));
+			q += snprint(q, left, " %.4ux", BGSHORT(a));
 			a += 2;
 			break;
 		}

+ 2 - 2
sys/src/9/port/devdup.c

@@ -29,10 +29,10 @@ dupgen(Chan *c, char *, Dirtab*, int, int s, Dir *dp)
 		return 0;
 	if(s & 1){
 		p = 0400;
-		sprint(up->genbuf, "%dctl", s/2);
+		snprint(up->genbuf, sizeof up->genbuf, "%dctl", s/2);
 	}else{
 		p = perm[f->mode&3];
-		sprint(up->genbuf, "%d", s/2);
+		snprint(up->genbuf, sizeof up->genbuf, "%d", s/2);
 	}
 	mkqid(&q, s+1, 0, QTFILE);
 	devdir(c, q, up->genbuf, 0, eve, p, dp);

+ 3 - 2
sys/src/9/port/devflash.c

@@ -89,7 +89,7 @@ flashgen(Chan *c, char*, Dirtab*, int, int s, Dir *dp)
 		mkqid(&q, QID(0, Qtopdir), 0, QTDIR);
 		n = "#F";
 		if(c->dev != 0){
-			sprint(up->genbuf, "#F%ld", c->dev);
+			snprint(up->genbuf, sizeof up->genbuf, "#F%ld", c->dev);
 			n = up->genbuf;
 		}
 		devdir(c, q, n, 0, eve, 0555, dp);
@@ -102,7 +102,8 @@ flashgen(Chan *c, char*, Dirtab*, int, int s, Dir *dp)
 		mkqid(&q, QID(0, Qflashdir), 0, QTDIR);
 		n = "flash";
 		if(c->dev != 0){
-			sprint(up->genbuf, "flash%ld", c->dev);
+			snprint(up->genbuf, sizeof up->genbuf, "flash%ld",
+				c->dev);
 			n = up->genbuf;
 		}
 		devdir(c, q, n, 0, eve, 0555, dp);

+ 1 - 1
sys/src/9/port/devmouse.c

@@ -303,7 +303,7 @@ mouseread(Chan *c, void *va, long n, vlong off)
 				b = 16;
 			else if (b == 16)
 				b = 8;
-		sprint(buf, "m%11d %11d %11d %11lud ",
+		snprint(buf, sizeof buf, "m%11d %11d %11d %11lud ",
 			m.xy.x, m.xy.y,
 			b,
 			m.msec);

+ 4 - 3
sys/src/9/port/devproc.c

@@ -215,7 +215,7 @@ procgen(Chan *c, char *name, Dirtab *tab, int, int s, Dir *dp)
 		pid = p->pid;
 		if(pid == 0)
 			return 0;
-		sprint(up->genbuf, "%lud", pid);
+		snprint(up->genbuf, sizeof up->genbuf, "%lud", pid);
 		/*
 		 * String comparison is done in devwalk so name must match its formatted pid
 		*/
@@ -528,7 +528,7 @@ procqidwidth(Chan *c)
 {
 	char buf[32];
 
-	return sprint(buf, "%lud", c->qid.vers);
+	return snprint(buf, sizeof buf, "%lud", c->qid.vers);
 }
 
 int
@@ -875,7 +875,8 @@ procread(Chan *c, void *va, long n, vlong off)
 			sg = p->seg[i];
 			if(sg == 0)
 				continue;
-			j += sprint(statbuf+j, "%-6s %c%c %.8lux %.8lux %4ld\n",
+			j += snprint(statbuf+j, sizeof statbuf - j,
+				"%-6s %c%c %.8lux %.8lux %4ld\n",
 				sname[sg->type&SG_TYPE],
 				sg->type&SG_RONLY ? 'R' : ' ',
 				sg->profile ? 'P' : ' ',

+ 4 - 2
sys/src/9/port/devsd.c

@@ -485,7 +485,8 @@ sdgen(Chan* c, char*, Dirtab*, int, int s, Dir* dp)
 	case Qtopdir:
 		if(s == DEVDOTDOT){
 			mkqid(&q, QID(0, 0, 0, Qtopdir), 0, QTDIR);
-			sprint(up->genbuf, "#%C", sddevtab.dc);
+			snprint(up->genbuf, sizeof up->genbuf, "#%C",
+				sddevtab.dc);
 			devdir(c, q, up->genbuf, 0, eve, 0555, dp);
 			return 1;
 		}
@@ -533,7 +534,8 @@ sdgen(Chan* c, char*, Dirtab*, int, int s, Dir* dp)
 	case Qunitdir:
 		if(s == DEVDOTDOT){
 			mkqid(&q, QID(0, 0, 0, Qtopdir), 0, QTDIR);
-			sprint(up->genbuf, "#%C", sddevtab.dc);
+			snprint(up->genbuf, sizeof up->genbuf, "#%C",
+				sddevtab.dc);
 			devdir(c, q, up->genbuf, 0, eve, 0555, dp);
 			return 1;
 		}

+ 1 - 1
sys/src/9/port/devsdp.c

@@ -557,7 +557,7 @@ sdpread(Chan *ch, void *a, long n, vlong off)
 		qunlock(c);
 		return n;
 	case Qctl:
-		sprint(buf, "%lud", CONV(ch->qid));
+		snprint(buf, sizeof buf, "%lud", CONV(ch->qid));
 		return readstr(off, a, n, buf);
 	case Qcontrol:
 		b = readcontrol(sdp->conv[CONV(ch->qid)], n);

+ 2 - 1
sys/src/9/port/devsegment.c

@@ -327,7 +327,8 @@ segmentread(Chan *c, void *a, long n, vlong voff)
 		g = c->aux;
 		if(g->s == nil)
 			error("segment not yet allocated");
-		sprint(buf, "va %#lux %#lux\n", g->s->base, g->s->top-g->s->base);
+		snprint(buf, sizeof buf, "va %#lux %#lux\n", g->s->base,
+			g->s->top-g->s->base);
 		return readstr(voff, a, n, buf);
 	case Qdata:
 		g = c->aux;

+ 4 - 2
sys/src/9/port/devsrv.c

@@ -86,13 +86,15 @@ srvstat(Chan *c, uchar *db, int n)
 char*
 srvname(Chan *c)
 {
+	int size;
 	Srv *sp;
 	char *s;
 
 	for(sp = srv; sp; sp = sp->link)
 		if(sp->chan == c){
-			s = smalloc(3+strlen(sp->name)+1);
-			sprint(s, "#s/%s", sp->name);
+			size = 3+strlen(sp->name)+1;
+			s = smalloc(size);
+			snprint(s, size, "#s/%s", sp->name);
 			return s;
 		}
 	return nil;

+ 2 - 2
sys/src/9/port/devssl.c

@@ -168,7 +168,7 @@ sslgen(Chan *c, char*, Dirtab *d, int nd, int s, Dir *dp)
 			else
 				nm = eve;
 			if(dsname[s] == nil){
-				sprint(name, "%d", s);
+				snprint(name, sizeof name, "%d", s);
 				kstrdup(&dsname[s], name);
 			}
 			devdir(c, q, dsname[s], 0, nm, 0555, dp);
@@ -671,7 +671,7 @@ sslread(Chan *c, void *a, long n, vlong off)
 		error(Ebadusefd);
 	case Qctl:
 		ft = CONV(c->qid);
-		sprint(buf, "%d", ft);
+		snprint(buf, sizeof buf, "%d", ft);
 		return readstr(offset, a, n, buf);
 	case Qdata:
 		b = sslbread(c, n, offset);

+ 1 - 1
sys/src/9/port/devtls.c

@@ -324,7 +324,7 @@ tlsgen(Chan *c, char*, Dirtab *, int, int s, Dir *dp)
 			nm = eve;
 		if((name = trnames[s]) == nil){
 			name = trnames[s] = smalloc(16);
-			sprint(name, "%d", s);
+			snprint(name, 16, "%d", s);
 		}
 		devdir(c, q, name, 0, nm, 0555, dp);
 		unlock(&tdlock);

+ 5 - 4
sys/src/9/port/edf.c

@@ -72,13 +72,14 @@ timeconv(Fmt *f)
 		sign = "";
 	if (t > Onesecond){
 		t += OneRound;
-		sprint(buf, "%s%d.%.3ds", sign, (int)(t / Onesecond),
+		snprint(buf, sizeof buf, "%s%d.%.3ds", sign,
+			(int)(t / Onesecond),
 			(int)(t % Onesecond)/Onemillisecond);
 	}else if (t > Onemillisecond)
-		sprint(buf, "%s%d.%.3dms", sign, (int)(t / Onemillisecond),
-			(int)(t % Onemillisecond));
+		snprint(buf, sizeof buf, "%s%d.%.3dms", sign,
+			(int)(t / Onemillisecond), (int)(t % Onemillisecond));
 	else
-		sprint(buf, "%s%dµs", sign, (int)t);
+		snprint(buf, sizeof buf, "%s%dµs", sign, (int)t);
 	return fmtstrcpy(f, buf);
 }
 

+ 2 - 3
sys/src/9/port/fault.c

@@ -22,7 +22,7 @@ fault(ulong addr, int read)
 	spllo();
 
 	m->pfault++;
-	for(tries = 200; tries > 0; tries--) {	/* TODO: reset to 20 */
+	for(tries = 200; tries > 0; tries--) {
 		s = seg(up, addr, 1);		/* leaves s->lk qlocked if seg != nil */
 		if(s == 0) {
 			up->psstate = sps;
@@ -41,8 +41,7 @@ fault(ulong addr, int read)
 	/*
 	 * if we loop more than a few times, we're probably stuck on
 	 * an unfixable address, almost certainly due to a bug
-	 * elsewhere (e.g., bad page tables) so there's no point
-	 * in spinning forever.
+	 * elsewhere, so there's no point in spinning forever.
 	 */
 	if (tries <= 0)
 		panic("fault: fault stuck on va %#8.8p read %d\n", addr, read);

+ 3 - 0
sys/src/9/port/fpi.c

@@ -1,6 +1,9 @@
 /*
  * Floating Point Interpreter.
  * shamelessly stolen from an original by ark.
+ *
+ * NB: the Internal arguments to fpisub and fpidiv are reversed from
+ * what you might naively expect: they compute y-x and y/x, respectively.
  */
 #include "fpi.h"
 

+ 5 - 0
sys/src/9/port/fpi.h

@@ -1,4 +1,5 @@
 typedef long Word;
+typedef long long Vlong;
 typedef unsigned long Single;
 typedef struct {
 	unsigned long l;
@@ -24,8 +25,10 @@ enum {
 };
 
 typedef struct {
+	/* order matters: must start with s, e, l, h in that order */
 	unsigned char s;
 	short e;
+	/* double bits */
 	long l;				/* 0000FFFFFFFFFFFFFFFFFFFFFFFFFGGG */
 	long h;				/* 0000HFFFFFFFFFFFFFFFFFFFFFFFFFFF */
 } Internal;
@@ -56,6 +59,8 @@ extern void fpinormalise(Internal*);
 extern void fpis2i(Internal *, void *);
 extern void fpid2i(Internal *, void *);
 extern void fpiw2i(Internal *, void *);
+extern void fpiv2i(Internal *, void *);
 extern void fpii2s(void *, Internal *);
 extern void fpii2d(void *, Internal *);
 extern void fpii2w(Word *, Internal *);
+extern void fpii2v(Vlong *, Internal *);

+ 53 - 0
sys/src/9/port/fpimem.c

@@ -70,6 +70,38 @@ fpiw2i(Internal *i, void *v)
 	i->e = (e - 1) + ExpBias;
 }
 
+void
+fpiv2i(Internal *i, void *v)
+{
+	Vlong w, word = *(Vlong*)v;
+	short e;
+
+	if(word < 0){
+		i->s = 1;
+		word = -word;
+	}
+	else
+		i->s = 0;
+	if(word == 0){
+		SetZero(i);
+		return;
+	}
+	if(word > 0){
+		for (e = 0, w = word; w; w >>= 1, e++)
+			;
+	} else
+		e = 32;
+	if(e > FractBits){
+		i->h = word>>(e - FractBits);
+		i->l = (word & ((1<<(e - FractBits)) - 1))<<(2*FractBits - e);
+	}
+	else {
+		i->h = word<<(FractBits - e);
+		i->l = 0;
+	}
+	i->e = (e - 1) + ExpBias;
+}
+
 void
 fpii2s(void *v, Internal *i)
 {
@@ -134,3 +166,24 @@ fpii2w(Word *word, Internal *i)
 		w = -w;
 	*word = w;
 }
+
+void
+fpii2v(Vlong *word, Internal *i)
+{
+	Vlong w;
+	short e;
+
+	fpiround(i);
+	e = (i->e - ExpBias) + 1;
+	if(e <= 0)
+		w = 0;
+	else if(e > 63)
+		w = (1ull<<63) - 1;		/* maxlong */
+	else if(e > FractBits)
+		w = (Vlong)i->h<<(e - FractBits) | i->l>>(2*FractBits - e);
+	else
+		w = i->h>>(FractBits-e);
+	if(i->s)
+		w = -w;
+	*word = w;
+}

+ 7 - 1
sys/src/9/port/rebootcmd.c

@@ -72,7 +72,13 @@ rebootcmd(int argc, char *argv[])
 	entry = l2be(exec.entry);
 	text = l2be(exec.text);
 	data = l2be(exec.data);
-	if(magic != AOUT_MAGIC)
+	/*
+	 * AOUT_MAGIC is sometimes defined like this:
+	 * #define AOUT_MAGIC	V_MAGIC || magic==M_MAGIC
+	 * so we can only use it in a fairly stylized manner.
+	 */
+	if(magic == AOUT_MAGIC) {
+	} else
 		error(Ebadexec);
 
 	/* round text out to page boundary */

+ 1 - 1
sys/src/cmd/5c/gc.h

@@ -125,7 +125,7 @@ struct	Reg
 };
 #define	R	((Reg*)0)
 
-#define	NRGN	600
+#define	NRGN	1000		/* was 600; raised for paranoia.c */
 struct	Rgn
 {
 	Reg*	enter;

+ 19 - 33
sys/src/cmd/postscript/download/download.c

@@ -1,5 +1,4 @@
 /*
- *
  * download - host resident font downloader
  *
  * Prepends host resident fonts to PostScript input files. The program assumes
@@ -49,15 +48,16 @@
  *
  * Was written quickly, so there's much room for improvement. Undoubtedly should
  * be a more general program (e.g. scan for other comments).
- *
  */
 
 #include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <string.h>
 #include <signal.h>
 #include <sys/types.h>
-#include <fcntl.h>
 #include <sys/stat.h>
-#include <string.h>
 
 #include "comments.h"			/* PostScript file structuring comments */
 #include "gen.h"			/* general purpose definitions */
@@ -236,7 +236,7 @@ readmap()
 	return;
 
     if ( *mapname != '/' ) {
-	if ( (path = (char *)malloc(strlen(hostfontdir) + strlen(mapname) +
+	if ( (path = malloc(strlen(hostfontdir) + strlen(mapname) +
 						strlen(suffix) + 2)) == NULL )
 	    error(FATAL, "no memory");
 	sprintf(path, "%s/%s%s", hostfontdir, mapname, suffix);
@@ -245,8 +245,8 @@ readmap()
     if ( (fd = open(path, 0)) != -1 ) {
 	if ( fstat(fd, &sbuf) == -1 )
 	    error(FATAL, "can't fstat %s", path);
-	if ( (stringspace = (char *)malloc(sbuf.st_size + 2)) == NULL )
-	    error(FATAL, "no memory");
+	if ( (stringspace = malloc(sbuf.st_size + 2)) == NULL )
+	    error(FATAL, "no memory for %s (%d bytes)", path, sbuf.st_size + 2);
 	if ( read(fd, stringspace, sbuf.st_size) == -1 )
 	    error(FATAL, "can't read %s", path);
 	close(fd);
@@ -444,7 +444,7 @@ copyfonts(list)
 	}   /* End if */
 	if ( (n = lookup(font)) < next ) {
 	    if ( *map[n].file != '/' ) {
-		if ( (path = (char *)malloc(strlen(hostfontdir)+strlen(map[n].file)+2)) == NULL )
+		if ( (path = malloc(strlen(hostfontdir)+strlen(map[n].file)+2)) == NULL )
 		    error(FATAL, "no memory");
 		sprintf(path, "%s/%s", hostfontdir, map[n].file);
 		cat(path);
@@ -512,32 +512,18 @@ lookup(font)
 
 }   /* End of lookup */
 
-/*****************************************************************************/
-
-Map *allocate(ptr, num)
-
-    Map		*ptr;
-    int		num;
-
-{
-
 /*
- *
  * Allocates space for num Map elements. Calls malloc() if ptr is NULL and
  * realloc() otherwise.
- *
  */
-
-    if ( ptr == NULL )
-	ptr = (Map *)malloc(num * sizeof(Map));
-    else ptr = (Map *)realloc(ptr, num * sizeof(Map));
-
-    if ( ptr == NULL )
-	error(FATAL, "no map memory");
-
-    return(ptr);
-
-}   /* End of allocate */
-
-/*****************************************************************************/
-
+Map *
+allocate(Map *ptr, int num)
+{
+	if (ptr == NULL)
+		ptr = (Map *)malloc(num * sizeof(Map));
+	else
+		ptr = (Map *)realloc(ptr, num * sizeof(Map));
+	if (ptr == NULL)
+		error(FATAL, "no map memory");
+	return ptr;
+}

+ 15 - 5
sys/src/cmd/rc/exec.c

@@ -154,6 +154,7 @@ main(int argc, char *argv[])
 				:(word *)0);
 	setvar("rcname", newword(argv[0], (word *)0));
 	i = 0;
+	memset(bootstrap, 0, sizeof bootstrap);
 	bootstrap[i++].i = 1;
 	bootstrap[i++].f = Xmark;
 	bootstrap[i++].f = Xword;
@@ -202,14 +203,18 @@ main(int argc, char *argv[])
  * Xconc(left, right)			concatenate, push results
  * Xcount(name)				push var count
  * Xdelfn(name)				delete function definition
- * Xdeltraps(names)			delete named traps
+ * Xdelhere
  * Xdol(name)				get variable value
- * Xqdol(name)				concatenate variable components
  * Xdup[i j]				dup file descriptor
+ * Xeflag
+ * Xerror
  * Xexit				rc exits with status
  * Xfalse{...}				execute {} if false
  * Xfn(name){... Xreturn}			define function
  * Xfor(var, list){... Xreturn}		for loop
+ * Xglob
+ * Xif
+ * Xifnot
  * Xjump[addr]				goto
  * Xlocal(name, val)			create local variable, assign value
  * Xmark				mark stack
@@ -218,16 +223,21 @@ main(int argc, char *argv[])
  * 					wait for both
  * Xpipefd[type]{... Xreturn}		connect {} to pipe (input or output,
  * 					depending on type), push /dev/fd/??
+ * Xpipewait
  * Xpopm(value)				pop value from stack
+ * Xpopredir
+ * Xrdcmds
+ * Xrdfn
  * Xrdwr(file)[fd]			open file for reading and writing
  * Xread(file)[fd]			open file to read
- * Xsettraps(names){... Xreturn}		define trap functions
- * Xshowtraps				print trap list
- * Xsimple(args)			run command and wait
+ * Xqdol(name)				concatenate variable components
  * Xreturn				kill thread
+ * Xsimple(args)			run command and wait
+ * Xsub
  * Xsubshell{... Xexit}			execute {} in a subshell and wait
  * Xtrue{...}				execute {} if true
  * Xunlocal				delete local variable
+ * Xwastrue
  * Xword[string]			push string
  * Xwrite(file)[fd]			open file to write
  */

+ 1 - 2
sys/src/cmd/rc/lex.c

@@ -366,8 +366,7 @@ yylex(void)
 		return c;
 	}
 	for(;;){
-		/* next line should have (char)c==GLOB, but ken's compiler is broken */
-		if(c=='*' || c=='[' || c=='?' || c==(unsigned char)GLOB)
+		if(c=='*' || c=='[' || c=='?' || c==GLOB)
 			w = addtok(w, GLOB);
 		w = addutf(w, c);
 		c = nextc();

+ 2 - 1
sys/src/cmd/rc/pcmd.c

@@ -21,8 +21,9 @@ pcmd(io *f, tree *t)
 {
 	if(t==0)
 		return;
+	assert(f != nil);
 	switch(t->type){
-	default:	pfmt(f, "bad %d %p %p %p", t->type, c0, c1, c2);
+	default:	pfmt(f, "bad cmd %d %p %p %p", t->type, c0, c1, c2);
 	break;
 	case '$':	pfmt(f, "$%t", c0);
 	break;

+ 41 - 35
sys/src/cmd/rc/pfnc.c

@@ -2,55 +2,58 @@
 #include "exec.h"
 #include "io.h"
 #include "fns.h"
+
 struct{
-	void (*f)(void);
-	char *name;
-}fname[] = {
+	void	(*f)(void);
+	char	*name;
+} fname[] = {
 	Xappend, "Xappend",
+	Xassign, "Xassign",
 	Xasync, "Xasync",
+	Xbackq, "Xbackq",
 	Xbang, "Xbang",
+	Xcase, "Xcase",
 	Xclose, "Xclose",
+	Xconc, "Xconc",
+	Xcount, "Xcount",
+	Xdelfn, "Xdelfn",
+	Xdelhere, "Xdelhere",
+	Xdol, "Xdol",
 	Xdup, "Xdup",
 	Xeflag, "Xeflag",
+	(void (*)(void))Xerror, "Xerror",
 	Xexit, "Xexit",
 	Xfalse, "Xfalse",
+	Xfn, "Xfn",
+	Xfor, "Xfor",
+	Xglob, "Xglob",
+	Xif, "Xif",
 	Xifnot, "Xifnot",
 	Xjump, "Xjump",
+	Xlocal, "Xlocal",
 	Xmark, "Xmark",
+	Xmatch, "Xmatch",
+	Xpipe, "Xpipe",
+	Xpipefd, "Xpipefd",
+	Xpipewait, "Xpipewait",
 	Xpopm, "Xpopm",
+	Xpopredir, "Xpopredir",
+	Xqdol, "Xqdol",
+	Xrdcmds, "Xrdcmds",
+	Xrdfn, "Xrdfn",
 	Xrdwr, "Xrdwr",
 	Xread, "Xread",
 	Xreturn, "Xreturn",
+	Xsimple, "Xsimple",
+	Xsub, "Xsub",
+	Xsubshell, "Xsubshell",
 	Xtrue, "Xtrue",
-	Xif, "Xif",
+	Xunlocal, "Xunlocal",
 	Xwastrue, "Xwastrue",
 	Xword, "Xword",
 	Xwrite, "Xwrite",
-	Xmatch, "Xmatch",
-	Xcase, "Xcase",
-	Xconc, "Xconc",
-	Xassign, "Xassign",
-	Xdol, "Xdol",
-	Xcount, "Xcount",
-	Xlocal, "Xlocal",
-	Xunlocal, "Xunlocal",
-	Xfn, "Xfn",
-	Xdelfn, "Xdelfn",
-	Xpipe, "Xpipe",
-	Xpipewait, "Xpipewait",
-	Xrdcmds, "Xrdcmds",
-	(void (*)(void))Xerror, "Xerror",
-	Xbackq, "Xbackq",
-	Xpipefd, "Xpipefd",
-	Xsubshell, "Xsubshell",
-	Xdelhere, "Xdelhere",
-	Xfor, "Xfor",
-	Xglob, "Xglob",
-	Xrdfn, "Xrdfn",
-	Xsimple, "Xsimple",
-	Xsub, "Xsub",
-	Xqdol, "Xqdol",
-0};
+	0
+};
 
 void
 pfnc(io *fd, thread *t)
@@ -58,14 +61,17 @@ pfnc(io *fd, thread *t)
 	int i;
 	void (*fn)(void) = t->code[t->pc].f;
 	list *a;
+
 	pfmt(fd, "pid %d cycle %p %d ", getpid(), t->code, t->pc);
-	for(i = 0;fname[i].f;i++) if(fname[i].f==fn){
-		pstr(fd, fname[i].name);
-		break;
-	}
-	if(!fname[i].f)
+	for (i = 0; fname[i].f; i++) 
+		if (fname[i].f == fn) {
+			pstr(fd, fname[i].name);
+			break;
+		}
+	if (!fname[i].f)
 		pfmt(fd, "%p", fn);
-	for(a = t->argv;a;a = a->next) pfmt(fd, " (%v)", a->words);
+	for (a = t->argv; a; a = a->next) 
+		pfmt(fd, " (%v)", a->words);
 	pchr(fd, '\n');
 	flush(fd);
 }

+ 1 - 1
sys/src/cmd/rc/plan9.c

@@ -621,7 +621,7 @@ Memcpy(void *a, void *b, long n)
 void*
 Malloc(ulong n)
 {
-	return malloc(n);
+	return mallocz(n, 1);
 }
 
 int *waitpids;

+ 1 - 1
sys/src/cmd/rc/rc.h

@@ -125,7 +125,7 @@ int mypid;
  *	GLOB[...] matches anything in the brackets
  *	GLOBGLOB matches GLOB
  */
-#define	GLOB	((char)0x01)
+#define	GLOB	'\001'
 
 char **argp;
 char **args;

+ 1 - 0
sys/src/cmd/rc/simple.c

@@ -460,6 +460,7 @@ execwhatis(void){	/* mildly wrong -- should fork before writing */
 		return;
 	}
 	setstatus("");
+	memset(out, 0, sizeof out);
 	out->fd = mapfd(1);
 	out->bufp = out->buf;
 	out->ebuf = &out->buf[NBUF];

+ 11 - 6
sys/src/cmd/rc/var.c

@@ -2,14 +2,19 @@
 #include "exec.h"
 #include "fns.h"
 
-int
-hash(char *s, int n)
+unsigned
+hash(char *as, int n)
 {
-	int h = 0, i = 1;
-	while(*s) h+=*s++*i++;
-	h%=n;
-	return h<0?h+n:h;
+	int i = 1;
+	unsigned h = 0;
+	uchar *s;
+
+	s = (uchar *)as;
+	while (*s)
+		h += *s++ * i++;
+	return h % n;
 }
+
 #define	NKW	30
 struct kw{
 	char *name;

+ 11 - 0
sys/src/cmd/samterm/flayer.c

@@ -70,6 +70,13 @@ flrect(Flayer *l, Rectangle r)
 	return r;
 }
 
+static void
+fontbuggered(char *name)
+{
+	fprint(2, "samterm: font %s has zero-width \"0\" character\n", name);
+	threadexits("font zero-width");
+}
+
 void
 flinit(Flayer *l, Rectangle r, Font *ft, Image **cols)
 {
@@ -79,6 +86,8 @@ flinit(Flayer *l, Rectangle r, Font *ft, Image **cols)
 	l->origin = l->p0 = l->p1 = 0;
 	frinit(&l->f, insetrect(flrect(l, r), FLMARGIN), ft, screen, cols);
 	l->f.maxtab = maxtab*stringwidth(ft, "0");
+	if(l->f.maxtab == 0)
+		fontbuggered(ft->name);
 	newvisibilities(1);
 	draw(screen, l->entire, l->f.cols[BACK], nil, ZP);
 	scrdraw(l, 0L);
@@ -414,6 +423,8 @@ flprepare(Flayer *l)
 		n = f->nchars;
 		frinit(f, f->entire, f->font, f->b, 0);
 		f->maxtab = maxtab*stringwidth(f->font, "0");
+		if(f->maxtab == 0)
+			fontbuggered(f->font->name);
 		r = (*l->textfn)(l, n, &n);
 		frinsert(f, r, r+n, (ulong)0);
 		frdrawsel(f, frptofchar(f, f->p0), f->p0, f->p1, 0);

+ 1 - 1
sys/src/cmd/vc/gc.h

@@ -120,7 +120,7 @@ struct	Reg
 };
 #define	R	((Reg*)0)
 
-#define	NRGN	600
+#define	NRGN	1000		/* was 600; raised for paranoia.c */
 struct	Rgn
 {
 	Reg*	enter;

+ 4 - 4
sys/src/cmd/vl/obj.c

@@ -18,7 +18,7 @@ static	int	maxlibdir = 0;
 /*
  *	-H0 -T0x40004C -D0x10000000	is abbrev unix
  *	-H1 -T0x80020000 -R4		is bootp() format for 3k
- *	-H2 -T4128 -R4096		is plan9 format
+ *	-H2 -T16416 -R16384		is plan9 format
  *	-H3 -T0x80020000 -R8		is bootp() format for 4k
  *	-H4 -T0x400000 -R4		is sgi unix coff executable
  *	-H5 -T0x4000A0 -R4		is sgi unix elf executable
@@ -153,12 +153,12 @@ main(int argc, char *argv[])
 		break;
 	case 2:	/* plan 9 */
 		HEADR = 32L;
-		if(INITTEXT == -1)
-			INITTEXT = 4128;
 		if(INITDAT == -1)
 			INITDAT = 0;
 		if(INITRND == -1)
-			INITRND = 4096;
+			INITRND = 16*1024;
+		if(INITTEXT == -1)
+			INITTEXT = INITRND + HEADR;
 		break;
 	case 3:	/* boot for 4k */
 		HEADR = 20L+56L+3*40L;

+ 2 - 2
sys/src/libmach/v.c

@@ -107,8 +107,8 @@ Mach mmips =
 	"setR30",	/* static base register name */
 	0,		/* value */
 	0x1000,		/* page size */
-	0xC0000000ULL,	/* kernel base */
-	0x40000000ULL,	/* kernel text mask */
+	0x80000000ULL,	/* kernel base */
+	0x80000000ULL,	/* kernel text mask */
 	0x7FFFFFFFULL,	/* user stack top */
 	4,		/* quantization of pc */
 	4,		/* szaddr */

+ 2 - 1
sys/src/libmach/vdb.c

@@ -131,7 +131,8 @@ mipsexcep(Map *map, Rgetter rget)
 	long c;
 
 	c = (*rget)(map, "CAUSE");
-	if(c & 0x00002000)	/* INTR3 */
+	/* i don't think this applies to any current machines */
+	if(0 && c & 0x00002000)	/* INTR3 */
 		e = 16;		/* Floating point exception */
 	else
 		e = (c>>2)&0x0F;