shithub: riscv

Download patch

ref: 5331734335d2f1fbe5af90ca6b56ec10ffac48a6
parent: 81b7451972780743bcd00c963a1c9cb686a3e4ad
parent: 58201a67c1cfceda2993979852a367b213abc0ee
author: jpathy <[email protected]>
date: Wed May 22 17:55:08 EDT 2013

merge

--- a/lib/troll
+++ b/lib/troll
@@ -120,3 +120,5 @@
 I have an  IDE HD with fossil (no venti) partition on it. It contains some data precious to me.
 Would it be possible to support file:// in acme ?
 i would not be at all surprised if the nix kernel (with or without the AC stuff) ends up being the basis for continuing evolution of plan9.
+Subject: [9fans] Go tip build fails
+FWIW may be it would make more sense to install Plan 9 (9front) then?
--- a/rc/bin/netaudit
+++ b/rc/bin/netaudit
@@ -38,6 +38,16 @@
 	}
 	if not
 		echo '	we are in ipnet='^$ipnet
+	ipgw=`{ndb/ipquery sys $sysname ipgw | sed 's/^ipgw=//'}
+	if(~ $ipgw '' '::'){
+		echo '	we do not have an internet gateway, no ipgw= entry'
+	}
+	if not {
+		if(! ~ $ipgw *.*.*.* *:*:*:*:*:*:*:* *::*)
+			echo '	ipgw='$ipgw 'does not look like an ip address'
+		if not
+			echo '	ipgw='$ipgw 'looks ok'
+	}
 	dns=`{ndb/ipquery sys $sysname dns | sed 's/^dns=//'}
 	if(~ $dns '')
 		echo '	no dns= entry'
--- a/sys/games/lib/fortunes
+++ b/sys/games/lib/fortunes
@@ -4843,3 +4843,18 @@
 The development effort for 5ESS required 5000 employees, producing 100 million lines of code, with 100 million lines of header and makefiles.
 Don't forget the colon when referring to keyboards or printers.
 A Font For Supporters Of Marriage Equality
+< mveety> im on facebook on my vax right now
+(#cat-v) aiju → fiddling with russian machines is so not worth it
+Subject: [9fans] Invitation to connect on LinkedIn
+Subject: [9fans]  [gsoc] Dart9P
+The problem is that there aren't any decent languages where you can just sit down and write code, because you have to know so much about the language itself.
+China's cyber forces are said to be around 400,000 including militia, and the US has 20,000.
+readfile(): nonblocking read blocked
+(#cat-v) lf94 → this is linux
+no. -- Erik Quanstrom
+But if you'll insert it carefull, and will take it out not often, it really will campatible
+They look ugly and the fanbase is terrible.
+Rio, the Plan 9 windowing system, looks and feels like a step back to the old Amiga and Atari ST days, as the façade is nearly the same.
+But really, you need a CRT to be lagless.
+is there any real reason for hating modern thinkpads besides the keyboard and screen resolution?
+No. -- 20h
--- a/sys/include/ape/lib9.h
+++ b/sys/include/ape/lib9.h
@@ -64,12 +64,12 @@
 extern	int	mount(int, int, char*, int, char*);
 extern	int	unmount(char*, char*);
 extern	int	rfork(int);
-extern	int	segattach(int, char*, void*, unsigned long);
-extern	int	segbrk(void*, void*);
+extern	void*	segattach(int, char*, void*, unsigned long);
+extern	void*	segbrk(void*, void*);
 extern	int	segdetach(void*);
 extern	int	segflush(void*, unsigned long);
 extern	int	segfree(void*, unsigned long);
-extern	unsigned long	rendezvous(unsigned long, unsigned long);
+extern	void*	rendezvous(void*, void*);
 extern	unsigned long	getfcr(void);
 extern	unsigned long	getfsr(void);
 extern	void		setfcr(unsigned long);
--- a/sys/lib/kbmap/ru
+++ b/sys/lib/kbmap/ru
@@ -176,7 +176,7 @@
 1	47	'М
 1	48	'И
 1	49	'Т
-1	50	'ь
+1	50	'Ь
 1	51	'Б
 1	52	'Ю
 1	53	',
--- a/sys/lib/kbmap/ua
+++ b/sys/lib/kbmap/ua
@@ -176,7 +176,7 @@
 1	47	'М
 1	48	'И
 1	49	'Т
-1	50	'ь
+1	50	'Ь
 1	51	'Б
 1	52	'Ю
 1	53	',
--- a/sys/man/1/jpg
+++ b/sys/man/1/jpg
@@ -85,6 +85,8 @@
 .B -c
 .I comment
 ] [
+.B -r
+] [
 .I file
 ]
 .br
@@ -93,7 +95,6 @@
 .B -c
 .I comment
 ] [
-[
 .B -g
 .I gamma
 ] [
@@ -126,7 +127,7 @@
 them in the current window; options cause them instead to convert the images
 to Plan 9 image format and write them to standard output.
 .IR Togif ,
-.IR Toppm ,
+.IR toppm ,
 and
 .I topng
 read Plan 9 images files, convert them to GIF, PPM, or PNG, and write them to standard output.
@@ -212,6 +213,12 @@
 Both accept an option
 .B -c
 to set the comment field of the resulting file.
+The
+.B -r
+option makes
+.I toppm
+output raw PPM.
+The default is to output plain PPM.
 If there is only one input picture,
 .I togif
 converts the image to GIF format.
--- a/sys/man/6/ndb
+++ b/sys/man/6/ndb
@@ -199,7 +199,7 @@
 Internet network mask
 .TP
 .B ipgw
-Internet gateway
+Internet gateway (ip address)
 .TP
 .B auth
 authentication server to be used
--- a/sys/src/9/pc/devether.c
+++ b/sys/src/9/pc/devether.c
@@ -380,6 +380,10 @@
 	char buf[128], name[32];
 
 	ether = malloc(sizeof(Ether));
+	if(ether == nil){
+		print("etherprobe: no memory for Ether\n");
+		return nil;
+	}
 	memset(ether, 0, sizeof(Ether));
 	ether->ctlrno = ctlrno;
 	ether->tbdf = BUSUNKNOWN;
@@ -460,8 +464,7 @@
 		ether->limit = bsz;
 	}
 	if(ether->oq == nil)
-		panic("etherreset %s: can't allocate output queue of %ld bytes",
-			name, bsz);
+		panic("etherreset %s: can't allocate output queue of %ld bytes", name, bsz);
 	ether->alen = Eaddrlen;
 	memmove(ether->addr, ether->ea, Eaddrlen);
 	memset(ether->bcast, 0xFF, Eaddrlen);
--- a/sys/src/9/pc/ether8169.c
+++ b/sys/src/9/pc/ether8169.c
@@ -50,6 +50,8 @@
 	Tbianar		= 0x68,		/* TBI Auto-Negotiation Advertisment */
 	Tbilpar		= 0x6A,		/* TBI Auto-Negotiation Link Partner */
 	Phystatus	= 0x6C,		/* PHY Status */
+	Pmch		= 0x6F,		/* power management */
+	Ldps		= 0x82,		/* link down power saving */
 
 	Rms		= 0xDA,		/* Receive Packet Maximum Size */
 	Cplusc		= 0xE0,		/* C+ Command */
@@ -117,6 +119,7 @@
 	Macv27		= 0x2c800000,	/* RTL8111e */
 	Macv28		= 0x2c000000,	/* RTL8111/8168B */
 	Macv29		= 0x40800000,	/* RTL8101/8102E */
+	Macv30		= 0x24000000,	/* RTL8101E? (untested) */
 	Ifg0		= 0x01000000,	/* Interframe Gap 0 */
 	Ifg1		= 0x02000000,	/* Interframe Gap 1 */
 };
@@ -388,12 +391,26 @@
 	ctlr->mii->ctlr = ctlr;
 
 	/*
+	 * PHY wakeup
+	 */
+	switch(ctlr->macv){
+	case Macv25:
+	case Macv28:
+	case Macv29:
+	case Macv30:
+		csr8w(ctlr, Pmch, csr8r(ctlr, Pmch) | 0x80);
+		break;
+	}
+	rtl8169miimiw(ctlr->mii, 1, 0x1f, 0);
+	rtl8169miimiw(ctlr->mii, 1, 0x0e, 0);
+
+	/*
 	 * Get rev number out of Phyidr2 so can config properly.
 	 * There's probably more special stuff for Macv0[234] needed here.
 	 */
 	ctlr->phyv = rtl8169miimir(ctlr->mii, 1, Phyidr2) & 0x0F;
 	if(ctlr->macv == Macv02){
-		csr8w(ctlr, 0x82, 1);				/* magic */
+		csr8w(ctlr, Ldps, 1);				/* magic */
 		rtl8169miimiw(ctlr->mii, 1, 0x0B, 0x0000);	/* magic */
 	}
 
@@ -405,6 +422,10 @@
 	print("rtl8169: oui %#ux phyno %d, macv = %#8.8ux phyv = %#4.4ux\n",
 		phy->oui, phy->phyno, ctlr->macv, ctlr->phyv);
 
+	miireset(ctlr->mii);
+
+	microdelay(100);
+
 	miiane(ctlr->mii, ~0, ~0, ~0);
 
 	return 0;
@@ -1018,6 +1039,7 @@
 	case Macv27:
 	case Macv28:
 	case Macv29:
+	case Macv30:
 		break;
 	}
 	return 0;
--- a/sys/src/9/pc/sdide.c
+++ b/sys/src/9/pc/sdide.c
@@ -2079,6 +2079,10 @@
 		case (0x7111<<16)|0x8086:	/* 82371[AE]B (PIIX4[E]) */
 			maxdma = 0x20000;
 			break;
+		case (0x1c00<<16)|0x8086:	/* SERIES6 SATA */
+		case (0x1c01<<16)|0x8086:	/* SERIES6 SATA */
+		case (0x1c08<<16)|0x8086:	/* SERIES6 SATA */
+		case (0x1c09<<16)|0x8086:	/* SERIES6 SATA */
 		case (0x2411<<16)|0x8086:	/* 82801AA (ICH) */
 		case (0x2421<<16)|0x8086:	/* 82801AB (ICH0) */
 		case (0x244A<<16)|0x8086:	/* 82801BA (ICH2, Mobile) */
--- a/sys/src/9/pc/uarti8250.c
+++ b/sys/src/9/pc/uarti8250.c
@@ -621,12 +621,14 @@
 {
 	Ctlr *ctlr;
 
-	if((ctlr = malloc(sizeof(Ctlr))) != nil){
-		ctlr->io = io;
-		ctlr->irq = irq;
-		ctlr->tbdf = tbdf;
+	ctlr = malloc(sizeof(Ctlr));
+	if(ctlr == nil){
+		print("i8250alloc: no memory for Ctlr\n");
+		return nil;
 	}
-
+	ctlr->io = io;
+	ctlr->irq = irq;
+	ctlr->tbdf = tbdf;
 	return ctlr;
 }
 
--- a/sys/src/9/pc/uartisa.c
+++ b/sys/src/9/pc/uartisa.c
@@ -18,16 +18,22 @@
 	Uart *uart;
 	char buf[64];
 
+	uart = malloc(sizeof(Uart));
+	if(uart == nil){
+		print("uartisa: no memory for Uart\n");
+		return nil;
+	}
+
 	io = isa->port;
 	snprint(buf, sizeof(buf), "%s%d", isaphysuart.name, ctlrno);
 	if(ioalloc(io, 8, 0, buf) < 0){
 		print("uartisa: I/O 0x%uX in use\n", io);
+		free(uart);
 		return nil;
 	}
 
-	uart = malloc(sizeof(Uart));
 	ctlr = i8250alloc(io, isa->irq, BUSUNKNOWN);
-	if(uart == nil || ctlr == nil){
+	if(ctlr == nil){
 		iofree(io);
 		free(uart);
 		return nil;
--- a/sys/src/9/pc/uartpci.c
+++ b/sys/src/9/pc/uartpci.c
@@ -21,17 +21,23 @@
 	char buf[64];
 	Uart *head, *uart;
 
+	head = malloc(sizeof(Uart)*n);
+	if(head == nil){
+		print("uartpci: no memory for Uarts\n");
+		return nil;
+	}
+
 	io = p->mem[barno].bar & ~0x01;
 	snprint(buf, sizeof(buf), "%s%d", pciphysuart.name, ctlrno);
 	if(ioalloc(io, p->mem[barno].size, 0, buf) < 0){
 		print("uartpci: I/O 0x%uX in use\n", io);
+		free(head);
 		return nil;
 	}
 
-	head = uart = malloc(sizeof(Uart)*n);
+	uart = head;
 	for(i = 0; i < n; i++){
-		ctlr = i8250alloc(io, p->intl, p->tbdf);
-		io += iosize;
+		ctlr = i8250alloc(io + i*iosize, p->intl, p->tbdf);
 		if(ctlr == nil)
 			continue;
 
@@ -44,16 +50,20 @@
 			(uart-1)->next = uart;
 		uart++;
 	}
-
-	if (head) {
-		if(perlehead != nil)
-			perletail->next = head;
-		else
-			perlehead = head;
-		for(perletail = head; perletail->next != nil;
-		    perletail = perletail->next)
-			;
+	if(head == uart){
+		iofree(io);
+		free(head);
+		return nil;
 	}
+
+	if(perlehead != nil)
+		perletail->next = head;
+	else
+		perlehead = head;
+	for(perletail = head; perletail->next != nil;
+	    perletail = perletail->next)
+		;
+
 	return head;
 }
 
--- a/sys/src/9/pc/wifi.c
+++ b/sys/src/9/pc/wifi.c
@@ -464,8 +464,14 @@
 	Wifi *wifi;
 
 	wifi = malloc(sizeof(Wifi));
-	wifi->ether = ether;
+	if(wifi == nil)
+		error(Enomem);
 	wifi->iq = qopen(8*1024, 0, 0, 0);
+	if(wifi->iq == nil){
+		free(wifi);
+		error(Enomem);
+	}
+	wifi->ether = ether;
 	wifi->transmit = transmit;
 	wifi->status = Snone;
 
--- a/sys/src/9/port/alloc.c
+++ b/sys/src/9/port/alloc.c
@@ -175,7 +175,7 @@
 		if(v != nil)
 			break;
 		if(!waserror()){
-			tsleep(&up->sleep, return0, 0, 100);
+			resrcwait(0);
 			poperror();
 		}
 	}
--- a/sys/src/9/port/devaoe.c
+++ b/sys/src/9/port/devaoe.c
@@ -1362,7 +1362,7 @@
 		return 0;
 	l = d->dl + i;
 
-	s = p = malloc(READSTR);
+	s = p = smalloc(READSTR);
 	e = s + READSTR;
 
 	p = seprint(p, e, "addr: ");
@@ -1398,7 +1398,7 @@
 	char *s, *p, *e;
 	Netlink *n;
 
-	s = p = malloc(READSTR);
+	s = p = smalloc(READSTR);
 	e = s + READSTR;
 
 	p = seprint(p, e, "debug: %d\n", debug);
@@ -1463,7 +1463,7 @@
 	if(len > sizeof d->config)
 		error(Etoobig);
 	srb = srballoc(len);
-	s = malloc(len);
+	s = smalloc(len);
 	memmove(s, db, len);
 	if(waserror()){
 		srbfree(srb);
@@ -1679,7 +1679,7 @@
 	case Qconfig:
 		if(off + n > sizeof d->config)
 			error(Etoobig);
-		buf = malloc(sizeof d->config);
+		buf = smalloc(sizeof d->config);
 		if(waserror()){
 			free(buf);
 			nexterror();
--- a/sys/src/9/port/devmnt.c
+++ b/sys/src/9/port/devmnt.c
@@ -61,7 +61,6 @@
 void	mntflushfree(Mnt*, Mntrpc*);
 void	mntfree(Mntrpc*);
 void	mntgate(Mnt*);
-void	mntpntfree(Mnt*);
 void	mntqrm(Mnt*, Mntrpc*);
 Mntrpc*	mntralloc(Chan*, ulong);
 long	mntrdwr(int, Chan*, void*, long, vlong);
@@ -101,6 +100,7 @@
 	uchar *msg;
 	Mnt *m;
 	char *v;
+	Queue *q;
 	long k, l;
 	uvlong oo;
 	char buf[128];
@@ -199,7 +199,17 @@
 	k = strlen(f.version);
 	if(strncmp(f.version, v, k) != 0)
 		error("bad 9P version returned from server");
+	if(returnlen > 0 && returnlen < k)
+		error(Eshort);
 
+	v = nil;
+	kstrdup(&v, f.version);
+	q = qopen(10*MAXRPC, 0, nil, nil);
+	if(q == nil){
+		free(v);
+		exhausted("mount queues");
+	}
+
 	/* now build Mnt associated with this connection */
 	lock(&mntalloc);
 	m = mntalloc.mntfree;
@@ -208,6 +218,8 @@
 	else {
 		m = malloc(sizeof(Mnt));
 		if(m == 0) {
+			qfree(q);
+			free(v);
 			unlock(&mntalloc);
 			exhausted("mount devices");
 		}
@@ -214,18 +226,14 @@
 	}
 	m->list = mntalloc.list;
 	mntalloc.list = m;
-	m->version = nil;
-	kstrdup(&m->version, f.version);
+	m->version = v;
 	m->id = mntalloc.id++;
-	m->q = qopen(10*MAXRPC, 0, nil, nil);
+	m->q = q;
 	m->msize = f.msize;
 	unlock(&mntalloc);
 
-	if(returnlen > 0){
-		if(returnlen < k)
-			error(Eshort);
-		memmove(version, f.version, k);
-	}
+	if(returnlen > 0)
+		memmove(version, f.version, k);	/* length was checked above */
 
 	poperror();	/* msg */
 	free(msg);
@@ -564,24 +572,19 @@
 void
 muxclose(Mnt *m)
 {
-	Mntrpc *q, *r;
+	Mnt *f, **l;
+	Mntrpc *r;
 
-	for(q = m->queue; q; q = r) {
-		r = q->list;
-		mntfree(q);
+	while((r = m->queue) != nil){
+		m->queue = r->list;
+		mntfree(r);
 	}
 	m->id = 0;
 	free(m->version);
 	m->version = nil;
-	mntpntfree(m);
-}
+	qfree(m->q);
+	m->q = nil;
 
-void
-mntpntfree(Mnt *m)
-{
-	Mnt *f, **l;
-	Queue *q;
-
 	lock(&mntalloc);
 	l = &mntalloc.list;
 	for(f = *l; f; f = f->list) {
@@ -593,10 +596,7 @@
 	}
 	m->list = mntalloc.mntfree;
 	mntalloc.mntfree = m;
-	q = m->q;
 	unlock(&mntalloc);
-
-	qfree(q);
 }
 
 static void
--- a/sys/src/9/port/devsd.c
+++ b/sys/src/9/port/devsd.c
@@ -847,9 +847,12 @@
 		b = (uchar*)a;
 		allocd = 0;
 	}else{
-		b = sdmalloc(nb*unit->secsize);
-		if(b == nil)
-			error(Enomem);
+		while((b = sdmalloc(nb*unit->secsize)) == nil){
+			if(!waserror()){
+				resrcwait("no memory for sdbio");
+				poperror();
+			}
+		}
 		allocd = 1;
 	}
 	if(waserror()){
@@ -929,8 +932,12 @@
 	}
 
 	data = nil;
-	if(n > 0 && (data = sdmalloc(n)) == nil)
-		error(Enomem);
+	while(n > 0 && (data = sdmalloc(n)) == nil){
+		if(!waserror()){
+			resrcwait("no memory for sdrio");
+			poperror();
+		}
+	}
 	if(waserror()){
 		sdfree(data);
 		r->data = nil;
@@ -1484,8 +1491,7 @@
 			}		
 			if(n < 6 || n > sizeof(req->cmd))
 				error(Ebadarg);
-			if((req = malloc(sizeof(SDreq))) == nil)
-				error(Enomem);
+			req = smalloc(sizeof(SDreq));
 			req->unit = unit;
 			if(waserror()){
 				free(req);
--- a/sys/src/9/port/pgrp.c
+++ b/sys/src/9/port/pgrp.c
@@ -306,6 +306,10 @@
 
 	p = up->psstate;
 	if(reason) {
+		if(waserror()){
+			up->psstate = p;
+			nexterror();
+		}
 		up->psstate = reason;
 		now = seconds();
 		/* don't tie up the console with complaints */
@@ -314,7 +318,9 @@
 			print("%s\n", reason);
 		}
 	}
-
-	tsleep(&up->sleep, return0, 0, 300);
-	up->psstate = p;
+	tsleep(&up->sleep, return0, 0, 100+nrand(200));
+	if(reason) {
+		up->psstate = p;
+		poperror();
+	}
 }
--- a/sys/src/9/port/sdscsi.c
+++ b/sys/src/9/port/sdscsi.c
@@ -384,8 +384,7 @@
 	SDreq *r;
 	long rlen;
 
-	if((r = malloc(sizeof(SDreq))) == nil)
-		error(Enomem);
+	r = smalloc(sizeof(SDreq));
 	r->unit = unit;
 	r->lun = lun;
 again:
--- a/sys/src/ape/lib/9/rendezvous.c
+++ b/sys/src/ape/lib/9/rendezvous.c
@@ -1,9 +1,9 @@
 #include <lib9.h>
 
-extern	unsigned long	_RENDEZVOUS(unsigned long, unsigned long);
+extern	void*	_RENDEZVOUS(void*, void*);
 
-unsigned long
-rendezvous(unsigned long tag, unsigned long value)
+void*
+rendezvous(void *tag, void *value)
 {
 	return _RENDEZVOUS(tag, value);
 }
--- a/sys/src/ape/lib/9/segattach.c
+++ b/sys/src/ape/lib/9/segattach.c
@@ -1,8 +1,8 @@
 #include <lib9.h>
 
-extern	int	_SEGATTACH(int, char*, void*, unsigned long);
+extern	void*	_SEGATTACH(int, char*, void*, unsigned long);
 
-int
+void*
 segattach(int attr, char *class, void *va, unsigned long len)
 {
 	return _SEGATTACH(attr, class, va, len);
--- a/sys/src/ape/lib/9/segbrk.c
+++ b/sys/src/ape/lib/9/segbrk.c
@@ -1,8 +1,8 @@
 #include <lib9.h>
 
-extern int	_SEGBRK(void*, void*);
+extern void*	_SEGBRK(void*, void*);
 
-int
+void*
 segbrk(void *saddr, void *addr)
 {
 	return _SEGBRK(saddr, addr);
--- a/sys/src/ape/lib/ap/mips/lock.c
+++ b/sys/src/ape/lib/ap/mips/lock.c
@@ -31,8 +31,7 @@
 	arch = C_fcr0();
 	switch(arch) {
 	case POWER:
-		n = _SEGATTACH(0,  "lock", (void*)Lockaddr, Pagesize);
-		if(n < 0) {
+		if(_SEGATTACH(0,  "lock", (void*)Lockaddr, Pagesize) == (void*)-1) {
 			arch = MAGNUM;
 			break;
 		}
--- a/sys/src/ape/lib/ap/plan9/9iounit.c
+++ b/sys/src/ape/lib/ap/plan9/9iounit.c
@@ -14,7 +14,7 @@
 getfields(char *str, char **args, int max, int mflag)
 {
 	char r;
-	int nr, intok, narg;
+	int intok, narg;
 
 	if(max <= 0)
 		return 0;
@@ -24,8 +24,8 @@
 	if(!mflag)
 		narg++;
 	intok = 0;
-	for(;;) {
-		r = *str++;
+	for(;; str++) {
+		r = *str;
 		if(r == 0)
 			break;
 		if(r == ' ' || r == '\t'){
@@ -33,7 +33,7 @@
 				break;
 			*str = 0;
 			intok = 0;
-			args[narg] = str + nr;
+			args[narg] = str + 1;
 			if(!mflag)
 				narg++;
 		} else {
--- a/sys/src/ape/lib/ap/plan9/_buf.c
+++ b/sys/src/ape/lib/ap/plan9/_buf.c
@@ -49,9 +49,10 @@
 int
 _startbuf(int fd)
 {
-	int i, pid, sid;
+	int i, pid;
 	Fdinfo *f;
 	Muxbuf *b;
+	void *v;
 
 	if(mux == 0){
 		_RFORK(RFREND);
@@ -111,16 +112,20 @@
 		for(i=0; i<OPEN_MAX; i++)
 			if(i!=fd && (_fdinfo[i].flags&FD_ISOPEN))
 				_CLOSE(i);
-		_RENDEZVOUS(0, _muxsid);
+		while(_RENDEZVOUS(&b->copypid, (void*)_muxsid) == (void*)~0)
+			;
 		_copyproc(fd, b);
 	}
-
 	/* parent process continues ... */
 	b->copypid = pid;
 	f->buf = b;
 	f->flags |= FD_BUFFERED;
 	unlock(&mux->lock);
-	_muxsid = _RENDEZVOUS(0, 0);
+
+	while((v = _RENDEZVOUS(&b->copypid, 0)) == (void*)~0)
+		;
+	_muxsid = (int)v;
+
 	/* leave fd open in parent so system doesn't reuse it */
 	return 0;
 }
@@ -168,7 +173,7 @@
 				/* sleep until there's room */
 				b->roomwait = 1;
 				unlock(&mux->lock);
-				_RENDEZVOUS((unsigned long)&b->roomwait, 0);
+				_RENDEZVOUS(&b->roomwait, 0);
 			}
 		} else
 			unlock(&mux->lock);
@@ -193,15 +198,15 @@
 			if(mux->selwait && FD_ISSET(fd, &mux->ewant)) {
 				mux->selwait = 0;
 				unlock(&mux->lock);
-				_RENDEZVOUS((unsigned long)&mux->selwait, fd);
+				_RENDEZVOUS(&mux->selwait, (void*)fd);
 			} else if(b->datawait) {
 				b->datawait = 0;
 				unlock(&mux->lock);
-				_RENDEZVOUS((unsigned long)&b->datawait, 0);
+				_RENDEZVOUS(&b->datawait, 0);
 			} else if(mux->selwait && FD_ISSET(fd, &mux->rwant)) {
 				mux->selwait = 0;
 				unlock(&mux->lock);
-				_RENDEZVOUS((unsigned long)&mux->selwait, fd);
+				_RENDEZVOUS(&mux->selwait, (void*)fd);
 			} else
 				unlock(&mux->lock);
 			_exit(0);
@@ -214,12 +219,12 @@
 					b->datawait = 0;
 					unlock(&mux->lock);
 					/* wake up _bufreading process */
-					_RENDEZVOUS((unsigned long)&b->datawait, 0);
+					_RENDEZVOUS(&b->datawait, 0);
 				} else if(mux->selwait && FD_ISSET(fd, &mux->rwant)) {
 					mux->selwait = 0;
 					unlock(&mux->lock);
 					/* wake up selecting process */
-					_RENDEZVOUS((unsigned long)&mux->selwait, fd);
+					_RENDEZVOUS(&mux->selwait, (void*)fd);
 				} else
 					unlock(&mux->lock);
 			} else
@@ -265,7 +270,7 @@
 		/* sleep until there's data */
 		b->datawait = 1;
 		unlock(&mux->lock);
-		_RENDEZVOUS((unsigned long)&b->datawait, 0);
+		_RENDEZVOUS(&b->datawait, 0);
 		lock(&mux->lock);
 		if(b->fd != fd){
 			unlock(&mux->lock);
@@ -287,7 +292,7 @@
 		b->roomwait = 0;
 		unlock(&mux->lock);
 		/* wake up copy process */
-		_RENDEZVOUS((unsigned long)&b->roomwait, 0);
+		_RENDEZVOUS(&b->roomwait, 0);
 	} else
 		unlock(&mux->lock);
 	return ngot;
@@ -390,7 +395,7 @@
 	}
 	mux->selwait = 1;
 	unlock(&mux->lock);
-	fd = _RENDEZVOUS((unsigned long)&mux->selwait, 0);
+	fd = (int)_RENDEZVOUS(&mux->selwait, 0);
 	if(fd >= 0 && fd < nfds) {
 		b = _fdinfo[fd].buf;
 		if(b == 0 || b->fd != fd) {
@@ -435,7 +440,8 @@
 		signal(SIGALRM, alarmed);
 		for(i=0; i<OPEN_MAX; i++)
 				_CLOSE(i);
-		_RENDEZVOUS(1, 0);
+		while(_RENDEZVOUS(&timerpid, 0) == (void*)~0)
+			;
 		for(;;) {
 			_SLEEP(mux->waittime);
 			if(timerreset) {
@@ -446,7 +452,7 @@
 					mux->selwait = 0;
 					mux->waittime = LONGWAIT;
 					unlock(&mux->lock);
-					_RENDEZVOUS((unsigned long)&mux->selwait, -2);
+					_RENDEZVOUS(&mux->selwait, (void*)-2);
 				} else {
 					mux->waittime = LONGWAIT;
 					unlock(&mux->lock);
@@ -454,9 +460,12 @@
 			}
 		}
 	}
-	atexit(_killtimerproc);
 	/* parent process continues */
-	_RENDEZVOUS(1, 0);
+	if(timerpid > 0){
+		atexit(_killtimerproc);
+		while(_RENDEZVOUS(&timerpid, 0) == (void*)~0)
+			;
+	}
 }
 
 static void
--- a/sys/src/ape/lib/ap/plan9/_envsetup.c
+++ b/sys/src/ape/lib/ap/plan9/_envsetup.c
@@ -32,7 +32,6 @@
 _envsetup(void)
 {
 	int dfd;
-	struct dirent *de;
 	int n, nd, m, i, j, f;
 	int psize, cnt;
 	int nohandle;
@@ -107,7 +106,7 @@
 static void
 sigsetup(char *s, char *se)
 {
-	int i, sig;
+	int sig;
 	char *e;
 
 	while(s < se){
--- a/sys/src/ape/lib/ap/plan9/_exit.c
+++ b/sys/src/ape/lib/ap/plan9/_exit.c
@@ -19,7 +19,6 @@
 void
 _finish(int status, char *term)
 {
-	int i, nalive;
 	char *cp;
 
 	if(_finishing)
--- a/sys/src/ape/lib/ap/plan9/_fdinfo.c
+++ b/sys/src/ape/lib/ap/plan9/_fdinfo.c
@@ -97,11 +97,9 @@
 static void
 sfdinit(int usedproc, char *s, char *se)
 {
-	int i;
 	Fdinfo *fi;
 	unsigned long fd, fl, ofl;
 	char *e;
-	struct stat sbuf;
 
 	while(s < se){
 		fd = strtoul(s, &e, 10);
--- a/sys/src/ape/lib/ap/plan9/access.c
+++ b/sys/src/ape/lib/ap/plan9/access.c
@@ -11,7 +11,7 @@
 int
 access(const char *name, int mode)
 {
-	int fd, n;
+	int fd;
 	Dir *db;
 	struct stat st;
 	static char omode[] = {
--- a/sys/src/ape/lib/ap/plan9/ctime.c
+++ b/sys/src/ape/lib/ap/plan9/ctime.c
@@ -148,7 +148,7 @@
 	struct tm *ct;
 	time_t t, tim;
 	long *p;
-	int i, dlflag;
+	int dlflag;
 
 	tim = *timp;
 	if(tz.stname[0] == 0)
--- a/sys/src/ape/lib/ap/plan9/dup.c
+++ b/sys/src/ape/lib/ap/plan9/dup.c
@@ -11,8 +11,6 @@
 int
 dup2(int oldd, int newd)
 {
-	int n;
-
 	if(newd < 0 || newd >= OPEN_MAX){
 		errno = EBADF;
 		return -1;
--- a/sys/src/ape/lib/ap/plan9/isatty.c
+++ b/sys/src/ape/lib/ap/plan9/isatty.c
@@ -8,7 +8,6 @@
 int
 _isatty(int fd)
 {
-	int t;
 	char buf[64];
 
 	if(_FD2PATH(fd, buf, sizeof buf) < 0)
--- a/sys/src/ape/lib/ap/plan9/open.c
+++ b/sys/src/ape/lib/ap/plan9/open.c
@@ -18,7 +18,6 @@
 	int mode;
 	Fdinfo *fi;
 	va_list va;
-	struct stat sbuf;
 
 	f = flags&O_ACCMODE;
 	if(flags&O_CREAT){
--- a/sys/src/ape/lib/ap/plan9/opendir.c
+++ b/sys/src/ape/lib/ap/plan9/opendir.c
@@ -84,7 +84,7 @@
 struct dirent *
 readdir(DIR *d)
 {
-	int i, n;
+	int i;
 	struct dirent *dr;
 	Dir *dirs;
 
--- a/sys/src/ape/lib/ap/plan9/qlock.c
+++ b/sys/src/ape/lib/ap/plan9/qlock.c
@@ -73,7 +73,7 @@
 	unlock(&q->lock);
 
 	/* wait */
-	while((*_rendezvousp)((ulong)mp, 1) == ~0)
+	while((*_rendezvousp)(mp, (void*)1) == (void*)~0)
 		;
 	mp->inuse = 0;
 }
@@ -91,7 +91,7 @@
 		if(q->head == nil)
 			q->tail = nil;
 		unlock(&q->lock);
-		while((*_rendezvousp)((ulong)p, 0x12345) == ~0)
+		while((*_rendezvousp)(p, (void*)0x12345) == (void*)~0)
 			;
 		return;
 	}
@@ -140,7 +140,7 @@
 	unlock(&q->lock);
 
 	/* wait in kernel */
-	while((*_rendezvousp)((ulong)mp, 1) == ~0)
+	while((*_rendezvousp)(mp, (void*)1) == (void*)~0)
 		;
 	mp->inuse = 0;
 }
@@ -183,7 +183,7 @@
 	unlock(&q->lock);
 
 	/* wakeup waiter */
-	while((*_rendezvousp)((ulong)p, 0) == ~0)
+	while((*_rendezvousp)(p, (void*)0) == (void*)~0)
 		;
 }
 
@@ -213,7 +213,7 @@
 	unlock(&q->lock);
 
 	/* wait in kernel */
-	while((*_rendezvousp)((ulong)mp, 1) == ~0)
+	while((*_rendezvousp)(mp, (void*)1) == (void*)~0)
 		;
 	mp->inuse = 0;
 }
@@ -252,7 +252,7 @@
 		if(q->head == nil)
 			q->tail = nil;
 		unlock(&q->lock);
-		while((*_rendezvousp)((ulong)p, 0) == ~0)
+		while((*_rendezvousp)(p, (void*)0) == (void*)~0)
 			;
 		return;
 	}
@@ -265,7 +265,7 @@
 		p = q->head;
 		q->head = p->next;
 		q->readers++;
-		while((*_rendezvousp)((ulong)p, 0) == ~0)
+		while((*_rendezvousp)(p, (void*)0) == (void*)~0)
 			;
 	}
 	if(q->head == nil)
@@ -303,7 +303,7 @@
 		if(r->l->head == nil)
 			r->l->tail = nil;
 		unlock(&r->l->lock);
-		while((*_rendezvousp)((ulong)t, 0x12345) == ~0)
+		while((*_rendezvousp)(t, (void*)0x12345) == (void*)~0)
 			;
 	}else{
 		r->l->locked = 0;
@@ -311,7 +311,7 @@
 	}
 
 	/* wait for a wakeup */
-	while((*_rendezvousp)((ulong)me, 1) == ~0)
+	while((*_rendezvousp)(me, (void*)1) == (void*)~0)
 		;
 	me->inuse = 0;
 }
--- a/sys/src/ape/lib/ap/plan9/rename.c
+++ b/sys/src/ape/lib/ap/plan9/rename.c
@@ -13,7 +13,6 @@
 	int n, i;
 	char *f, *t;
 	Dir *d, nd;
-	long mode;
 
 	if(access(to, 0) >= 0){
 		if(_REMOVE(to) < 0){
--- a/sys/src/ape/lib/ap/plan9/sys9.h
+++ b/sys/src/ape/lib/ap/plan9/sys9.h
@@ -98,10 +98,10 @@
 extern	long	_PWRITE(int, void*, long, long long);
 extern	long	_READ(int, void*, long);
 extern	int	_REMOVE(const char*);
-extern	int	_RENDEZVOUS(unsigned long, unsigned long);
+extern	void*	_RENDEZVOUS(void*, void*);
 extern	int	_RFORK(int);
-extern	int	_SEGATTACH(int, char*, void*, unsigned long);
-extern	int	_SEGBRK(void*, void*);
+extern	void*	_SEGATTACH(int, char*, void*, unsigned long);
+extern	void*	_SEGBRK(void*, void*);
 extern	int	_SEGDETACH(void*);
 extern	int	_SEGFLUSH(void*, unsigned long);
 extern	int	_SEGFREE(void*, unsigned long);
--- a/sys/src/ape/lib/bsd/listen.c
+++ b/sys/src/ape/lib/bsd/listen.c
@@ -31,14 +31,11 @@
 static int
 listenproc(Rock *r, int fd)
 {
-	Rock *nr;
-	char *net;
-	int cfd, nfd, dfd;
-	int pfd[2];
+	char listen[Ctlsize], name[Ctlsize], *net, *p;
+	int cfd, nfd, dfd, pfd[2];
 	struct stat d;
-	char *p;
-	char listen[Ctlsize];
-	char name[Ctlsize];
+	Rock *nr;
+	void *v;
 
 	switch(r->stype){
 	case SOCK_DGRAM:
@@ -81,11 +78,14 @@
 			_muxsid = getpgrp();
 		} else
 			setpgid(getpid(), _muxsid);
-		_RENDEZVOUS(2, _muxsid);
+		while(_RENDEZVOUS(r, (void*)_muxsid) == (void*)~0)
+			;
 		break;
 	default:
+		while((v = _RENDEZVOUS(r, 0)) == (void*)~0)
+			;
+		_muxsid = (int)v;
 		atexit(_killmuxsid);
-		_muxsid = _RENDEZVOUS(2, 0);
 		close(pfd[1]);
 		close(nfd);
 		return 0;
--- a/sys/src/ape/lib/draw/libc.h
+++ b/sys/src/ape/lib/draw/libc.h
@@ -84,10 +84,10 @@
 extern	long	_PWRITE(int, void*, long, long long);
 extern	long	_READ(int, void*, long);
 extern	int	_REMOVE(const char*);
-extern	int	_RENDEZVOUS(unsigned long, unsigned long);
+extern	void*	_RENDEZVOUS(void*, void*);
 extern	int	_RFORK(int);
-extern	int	_SEGATTACH(int, char*, void*, unsigned long);
-extern	int	_SEGBRK(void*, void*);
+extern	void*	_SEGATTACH(int, char*, void*, unsigned long);
+extern	void*	_SEGBRK(void*, void*);
 extern	int	_SEGDETACH(void*);
 extern	int	_SEGFLUSH(void*, unsigned long);
 extern	int	_SEGFREE(void*, unsigned long);
--- a/sys/src/cmd/acme/disk.c
+++ b/sys/src/cmd/acme/disk.c
@@ -120,10 +120,20 @@
 void
 diskread(Disk *d, Block *b, Rune *r, uint n)
 {
+	int tot, nr;
+	char *p;
+
 	if(n > b->n)
 		error("internal error: diskread");
 
 	ntosize(b->n, nil);
-	if(pread(d->fd, r, n*sizeof(Rune), b->addr) != n*sizeof(Rune))
+	n *= sizeof(Rune);
+	p = (char*)r;
+	for(tot = 0; tot < n; tot += nr){
+		nr = pread(d->fd, p+tot, n-tot, b->addr+tot);
+		if(nr <= 0)
+			error("read error from temp file");
+	}
+	if(tot != n)
 		error("read error from temp file");
 }
--- a/sys/src/cmd/awk/mkfile
+++ b/sys/src/cmd/awk/mkfile
@@ -41,7 +41,7 @@
 	rm -f *.[$OS] [$OS].out [$OS].maketab y.tab.? y.debug y.output $TARG
 
 nuke:V:
-	rm -f *.[$OS] [$OS].out [$OS].maketab y.tab.? y.debug y.output awkgram.c $TARG
+	rm -f *.[$OS] [$OS].out [$OS].maketab y.tab.? y.debug y.output awkgram.c proctab.c $TARG
 
 proctab.c:	$cpuobjtype.maketab
 	./$cpuobjtype.maketab >proctab.c
--- a/sys/src/cmd/awk/proctab.c
+++ /dev/null
@@ -1,205 +1,0 @@
-#include <stdio.h>
-#include "awk.h"
-#include "y.tab.h"
-
-static char *printname[92] = {
-	(char *) "FIRSTTOKEN",	/* 57346 */
-	(char *) "PROGRAM",	/* 57347 */
-	(char *) "PASTAT",	/* 57348 */
-	(char *) "PASTAT2",	/* 57349 */
-	(char *) "XBEGIN",	/* 57350 */
-	(char *) "XEND",	/* 57351 */
-	(char *) "NL",	/* 57352 */
-	(char *) "ARRAY",	/* 57353 */
-	(char *) "MATCH",	/* 57354 */
-	(char *) "NOTMATCH",	/* 57355 */
-	(char *) "MATCHOP",	/* 57356 */
-	(char *) "FINAL",	/* 57357 */
-	(char *) "DOT",	/* 57358 */
-	(char *) "ALL",	/* 57359 */
-	(char *) "CCL",	/* 57360 */
-	(char *) "NCCL",	/* 57361 */
-	(char *) "CHAR",	/* 57362 */
-	(char *) "OR",	/* 57363 */
-	(char *) "STAR",	/* 57364 */
-	(char *) "QUEST",	/* 57365 */
-	(char *) "PLUS",	/* 57366 */
-	(char *) "AND",	/* 57367 */
-	(char *) "BOR",	/* 57368 */
-	(char *) "APPEND",	/* 57369 */
-	(char *) "EQ",	/* 57370 */
-	(char *) "GE",	/* 57371 */
-	(char *) "GT",	/* 57372 */
-	(char *) "LE",	/* 57373 */
-	(char *) "LT",	/* 57374 */
-	(char *) "NE",	/* 57375 */
-	(char *) "IN",	/* 57376 */
-	(char *) "ARG",	/* 57377 */
-	(char *) "BLTIN",	/* 57378 */
-	(char *) "BREAK",	/* 57379 */
-	(char *) "CLOSE",	/* 57380 */
-	(char *) "CONTINUE",	/* 57381 */
-	(char *) "DELETE",	/* 57382 */
-	(char *) "DO",	/* 57383 */
-	(char *) "EXIT",	/* 57384 */
-	(char *) "FOR",	/* 57385 */
-	(char *) "FUNC",	/* 57386 */
-	(char *) "SUB",	/* 57387 */
-	(char *) "GSUB",	/* 57388 */
-	(char *) "IF",	/* 57389 */
-	(char *) "INDEX",	/* 57390 */
-	(char *) "LSUBSTR",	/* 57391 */
-	(char *) "MATCHFCN",	/* 57392 */
-	(char *) "NEXT",	/* 57393 */
-	(char *) "NEXTFILE",	/* 57394 */
-	(char *) "ADD",	/* 57395 */
-	(char *) "MINUS",	/* 57396 */
-	(char *) "MULT",	/* 57397 */
-	(char *) "DIVIDE",	/* 57398 */
-	(char *) "MOD",	/* 57399 */
-	(char *) "ASSIGN",	/* 57400 */
-	(char *) "ASGNOP",	/* 57401 */
-	(char *) "ADDEQ",	/* 57402 */
-	(char *) "SUBEQ",	/* 57403 */
-	(char *) "MULTEQ",	/* 57404 */
-	(char *) "DIVEQ",	/* 57405 */
-	(char *) "MODEQ",	/* 57406 */
-	(char *) "POWEQ",	/* 57407 */
-	(char *) "PRINT",	/* 57408 */
-	(char *) "PRINTF",	/* 57409 */
-	(char *) "SPRINTF",	/* 57410 */
-	(char *) "ELSE",	/* 57411 */
-	(char *) "INTEST",	/* 57412 */
-	(char *) "CONDEXPR",	/* 57413 */
-	(char *) "POSTINCR",	/* 57414 */
-	(char *) "PREINCR",	/* 57415 */
-	(char *) "POSTDECR",	/* 57416 */
-	(char *) "PREDECR",	/* 57417 */
-	(char *) "VAR",	/* 57418 */
-	(char *) "IVAR",	/* 57419 */
-	(char *) "VARNF",	/* 57420 */
-	(char *) "CALL",	/* 57421 */
-	(char *) "NUMBER",	/* 57422 */
-	(char *) "STRING",	/* 57423 */
-	(char *) "REGEXPR",	/* 57424 */
-	(char *) "GETLINE",	/* 57425 */
-	(char *) "RETURN",	/* 57426 */
-	(char *) "SPLIT",	/* 57427 */
-	(char *) "SUBSTR",	/* 57428 */
-	(char *) "WHILE",	/* 57429 */
-	(char *) "CAT",	/* 57430 */
-	(char *) "NOT",	/* 57431 */
-	(char *) "UMINUS",	/* 57432 */
-	(char *) "POWER",	/* 57433 */
-	(char *) "DECR",	/* 57434 */
-	(char *) "INCR",	/* 57435 */
-	(char *) "INDIRECT",	/* 57436 */
-	(char *) "LASTTOKEN",	/* 57437 */
-};
-
-
-Cell *(*proctab[92])(Node **, int) = {
-	nullproc,	/* FIRSTTOKEN */
-	program,	/* PROGRAM */
-	pastat,	/* PASTAT */
-	dopa2,	/* PASTAT2 */
-	nullproc,	/* XBEGIN */
-	nullproc,	/* XEND */
-	nullproc,	/* NL */
-	array,	/* ARRAY */
-	matchop,	/* MATCH */
-	matchop,	/* NOTMATCH */
-	nullproc,	/* MATCHOP */
-	nullproc,	/* FINAL */
-	nullproc,	/* DOT */
-	nullproc,	/* ALL */
-	nullproc,	/* CCL */
-	nullproc,	/* NCCL */
-	nullproc,	/* CHAR */
-	nullproc,	/* OR */
-	nullproc,	/* STAR */
-	nullproc,	/* QUEST */
-	nullproc,	/* PLUS */
-	boolop,	/* AND */
-	boolop,	/* BOR */
-	nullproc,	/* APPEND */
-	relop,	/* EQ */
-	relop,	/* GE */
-	relop,	/* GT */
-	relop,	/* LE */
-	relop,	/* LT */
-	relop,	/* NE */
-	instat,	/* IN */
-	arg,	/* ARG */
-	bltin,	/* BLTIN */
-	jump,	/* BREAK */
-	closefile,	/* CLOSE */
-	jump,	/* CONTINUE */
-	awkdelete,	/* DELETE */
-	dostat,	/* DO */
-	jump,	/* EXIT */
-	forstat,	/* FOR */
-	nullproc,	/* FUNC */
-	sub,	/* SUB */
-	gsub,	/* GSUB */
-	ifstat,	/* IF */
-	sindex,	/* INDEX */
-	nullproc,	/* LSUBSTR */
-	matchop,	/* MATCHFCN */
-	jump,	/* NEXT */
-	jump,	/* NEXTFILE */
-	arith,	/* ADD */
-	arith,	/* MINUS */
-	arith,	/* MULT */
-	arith,	/* DIVIDE */
-	arith,	/* MOD */
-	assign,	/* ASSIGN */
-	nullproc,	/* ASGNOP */
-	assign,	/* ADDEQ */
-	assign,	/* SUBEQ */
-	assign,	/* MULTEQ */
-	assign,	/* DIVEQ */
-	assign,	/* MODEQ */
-	assign,	/* POWEQ */
-	printstat,	/* PRINT */
-	awkprintf,	/* PRINTF */
-	awksprintf,	/* SPRINTF */
-	nullproc,	/* ELSE */
-	intest,	/* INTEST */
-	condexpr,	/* CONDEXPR */
-	incrdecr,	/* POSTINCR */
-	incrdecr,	/* PREINCR */
-	incrdecr,	/* POSTDECR */
-	incrdecr,	/* PREDECR */
-	nullproc,	/* VAR */
-	nullproc,	/* IVAR */
-	getnf,	/* VARNF */
-	call,	/* CALL */
-	nullproc,	/* NUMBER */
-	nullproc,	/* STRING */
-	nullproc,	/* REGEXPR */
-	getline,	/* GETLINE */
-	jump,	/* RETURN */
-	split,	/* SPLIT */
-	substr,	/* SUBSTR */
-	whilestat,	/* WHILE */
-	cat,	/* CAT */
-	boolop,	/* NOT */
-	arith,	/* UMINUS */
-	arith,	/* POWER */
-	nullproc,	/* DECR */
-	nullproc,	/* INCR */
-	indirect,	/* INDIRECT */
-	nullproc,	/* LASTTOKEN */
-};
-
-char *tokname(int n)
-{
-	static char buf[100];
-
-	if (n < FIRSTTOKEN || n > LASTTOKEN) {
-		sprintf(buf, "token %d", n);
-		return buf;
-	}
-	return printname[n-FIRSTTOKEN];
-}
--- a/sys/src/cmd/faces/main.c
+++ b/sys/src/cmd/faces/main.c
@@ -113,7 +113,7 @@
 	tinyfont = openfont(display, "/lib/font/bit/misc/ascii.5x7.font");
 	if(tinyfont == nil)
 		tinyfont = font;
- 	mediumfont = openfont(display, "/lib/font/bit/dejavusans/dejavusans.12.font");
+ 	mediumfont = openfont(display, "/lib/font/bit/misc/unicode.6x13.font");
  	if(mediumfont == nil)
  		mediumfont = font;
 	datefont = font;
--- a/sys/src/cmd/file.c
+++ b/sys/src/cmd/file.c
@@ -828,7 +828,11 @@
 	"OggS",			"ogg audio",		4,	"audio/ogg",
 	".snd",			"sun audio",		4,	"audio/basic",
 	"\211PNG",		"PNG image",		4,	"image/png",
+	"P1\n",			"ppm",				3,	"image/ppm",
+	"P2\n",			"ppm",				3,	"image/ppm",
 	"P3\n",			"ppm",				3,	"image/ppm",
+	"P4\n",			"ppm",				3,	"image/ppm",
+	"P5\n",			"ppm",				3,	"image/ppm",
 	"P6\n",			"ppm",				3,	"image/ppm",
 	"/* XPM */\n",	"xbm",				10,	"image/xbm",
 	".HTML ",		"troff -ms input",	6,	"text/troff",
--- a/sys/src/cmd/jpg/imagefile.h
+++ b/sys/src/cmd/jpg/imagefile.h
@@ -71,8 +71,8 @@
 Image*		onechan(Image*);
 Memimage*	memonechan(Memimage*);
 
-char*		writeppm(Biobuf*, Image*, char*);
-char*		memwriteppm(Biobuf*, Memimage*, char*);
+char*		writeppm(Biobuf*, Image*, char*, int);
+char*		memwriteppm(Biobuf*, Memimage*, char*, int);
 Image*		multichan(Image*);
 Memimage*	memmultichan(Memimage*);
 
--- a/sys/src/cmd/jpg/toppm.c
+++ b/sys/src/cmd/jpg/toppm.c
@@ -9,7 +9,7 @@
 void
 usage(void)
 {
-	fprint(2, "usage: toppm [-c 'comment'] [file]\n");
+	fprint(2, "usage: toppm [-c 'comment'] [-r] [file]\n");
 	exits("usage");
 }
 
@@ -18,10 +18,11 @@
 {
 	Biobuf bout;
 	Memimage *i, *ni;
-	int fd;
+	int fd, rflag;
 	char buf[256];
 	char *err, *comment;
 
+	rflag = 0;
 	comment = nil;
 	ARGBEGIN{
 	case 'c':
@@ -33,6 +34,9 @@
 			usage();
 		}
 		break;
+	case 'r':
+		rflag = 1;
+		break;
 	default:
 		usage();
 	}ARGEND
@@ -45,8 +49,6 @@
 
 	memimageinit();
 
-	err = nil;
-
 	if(argc == 0){
 		i = readmemimage(0);
 		if(i == nil)
@@ -58,8 +60,7 @@
 			freememimage(i);
 			i = ni;
 		}
-		if(err == nil)
-			err = memwriteppm(&bout, i, comment);
+		err = memwriteppm(&bout, i, comment, rflag);
 	}else{
 		fd = open(argv[0], OREAD);
 		if(fd < 0)
@@ -70,16 +71,16 @@
 		close(fd);
 		ni = memmultichan(i);
 		if(ni == nil)
-			sysfatal("converting image to RGBV: %r");
+			sysfatal("converting image to RGB24: %r");
 		if(i != ni){
 			freememimage(i);
 			i = ni;
 		}
 		if(comment)
-			err = memwriteppm(&bout, i, comment);
+			err = memwriteppm(&bout, i, comment, rflag);
 		else{
 			snprint(buf, sizeof buf, "Converted by Plan 9 from %s", argv[0]);
-			err = memwriteppm(&bout, i, buf);
+			err = memwriteppm(&bout, i, buf, rflag);
 		}
 		freememimage(i);
 	}
--- a/sys/src/cmd/jpg/writeppm.c
+++ b/sys/src/cmd/jpg/writeppm.c
@@ -12,12 +12,32 @@
 	-1, -1, -1, -1, -1, -1, -1, 4 /* BUG */, -1, -1, -1, -1, -1, -1, -1, 5
 };
 
+static int bitc = 0;
+static int nbit = 0;
+
+static
+void
+Bputbit(Biobufhdr *b, int c)
+{
+	if(c >= 0x0){
+		bitc = (bitc << 1) | (c & 0x1);
+		nbit++;
+	}else if(nbit > 0){
+		for(; nbit < 8; nbit++)
+			bitc <<= 1;
+	}
+	if(nbit == 8){
+		Bputc(b, bitc);
+		bitc = nbit = 0;
+	}
+}
+
 /*
  * Write data
  */
 static
 char*
-writedata(Biobuf *fd, Image *image, Memimage *memimage)
+writedata(Biobuf *fd, Image *image, Memimage *memimage, int rflag)
 {
 	char *err;
 	uchar *data;
@@ -51,7 +71,7 @@
 		err = malloc(ERRMAX);
 		if(err == nil)
 			return "WritePPM: malloc failed";
-		snprint(err, ERRMAX, "WriteGIF: %r");
+		snprint(err, ERRMAX, "WritePPM: %r");
 		free(data);
 		return err;
 	}
@@ -70,7 +90,19 @@
 				pix = (data[i]>>depth*((xmask-x)&xmask))&pmask;
 				if(((x+1)&xmask) == 0)
 					i++;
-				col += Bprint(fd, "%d ", pix);
+				if(chan == GREY1){
+					pix ^= 1;
+					if(rflag){
+						Bputbit(fd, pix);
+						continue;
+					}
+				} else {
+					if(rflag){
+						Bputc(fd, pix);
+						continue;
+					}
+				}
+				col += Bprint(fd, "%d", pix);
 				if(col >= MAXLINE-(2+1)){
 					Bprint(fd, "\n");
 					col = 0;
@@ -77,11 +109,17 @@
 				}else
 					col += Bprint(fd, " ");
 			}
+			if(rflag)
+				Bputbit(fd, -1);
 		}
 		break;
-	case	GREY8:
+	case GREY8:
 		for(i=0; i<ndata; i++){
-			col += Bprint(fd, "%d ", data[i]);
+			if(rflag){
+				Bputc(fd, data[i]);
+				continue;
+			}
+			col += Bprint(fd, "%d", data[i]);
 			if(col >= MAXLINE-(4+1)){
 				Bprint(fd, "\n");
 				col = 0;
@@ -91,6 +129,12 @@
 		break;
 	case RGB24:
 		for(i=0; i<ndata; i+=3){
+			if(rflag){
+				Bputc(fd, data[i+2]);
+				Bputc(fd, data[i+1]);
+				Bputc(fd, data[i]);
+				continue;
+			}
 			col += Bprint(fd, "%d %d %d", data[i+2], data[i+1], data[i]);
 			if(col >= MAXLINE-(4+4+4+1)){
 				Bprint(fd, "\n");
@@ -108,21 +152,21 @@
 
 static
 char*
-writeppm0(Biobuf *fd, Image *image, Memimage *memimage, Rectangle r, int chan, char *comment)
+writeppm0(Biobuf *fd, Image *image, Memimage *memimage, Rectangle r, int chan, char *comment, int rflag)
 {
 	char *err;
 
 	switch(chan){
 	case GREY1:
-		Bprint(fd, "P1\n");
+		Bprint(fd, "%s\n", rflag? "P4": "P1");
 		break;
 	case GREY2:
 	case GREY4:
-	case	GREY8:
-		Bprint(fd, "P2\n");
+	case GREY8:
+		Bprint(fd, "%s\n", rflag? "P5": "P2");
 		break;
 	case RGB24:
-		Bprint(fd, "P3\n");
+		Bprint(fd, "%s\n", rflag? "P6": "P3");
 		break;
 	default:
 		return "WritePPM: can't handle channel type";
@@ -143,27 +187,28 @@
 	case GREY4:
 		Bprint(fd, "%d\n", 15);
 		break;
-	case	GREY8:
+	case GREY8:
 	case RGB24:
 		Bprint(fd, "%d\n", 255);
 		break;
 	}
 
-	err = writedata(fd, image, memimage);
+	err = writedata(fd, image, memimage, rflag);
 
-	Bprint(fd, "\n");
+	if(!rflag)
+		Bprint(fd, "\n");
 	Bflush(fd);
 	return err;
 }
 
 char*
-writeppm(Biobuf *fd, Image *image, char *comment)
+writeppm(Biobuf *fd, Image *image, char *comment, int rflag)
 {
-	return writeppm0(fd, image, nil, image->r, image->chan, comment);
+	return writeppm0(fd, image, nil, image->r, image->chan, comment, rflag);
 }
 
 char*
-memwriteppm(Biobuf *fd, Memimage *memimage, char *comment)
+memwriteppm(Biobuf *fd, Memimage *memimage, char *comment, int rflag)
 {
-	return writeppm0(fd, nil, memimage, memimage->r, memimage->chan, comment);
+	return writeppm0(fd, nil, memimage, memimage->r, memimage->chan, comment, rflag);
 }
--- a/sys/src/cmd/nusb/kb/kb.c
+++ b/sys/src/cmd/nusb/kb/kb.c
@@ -57,6 +57,11 @@
  */
 
 /*
+ * scan codes >= 0x80 are extended (E0 XX)
+ */
+#define isext(sc)	((sc) >= 0x80)
+
+/*
  * key code to scan code; for the page table used by
  * the logitech bluetooth keyboard.
  */
@@ -70,15 +75,15 @@
 [0x28]	0x1c,	0x1,	0xe,	0xf,	0x39,	0xc,	0xd,	0x1a,
 [0x30]	0x1b,	0x2b,	0x2b,	0x27,	0x28,	0x29,	0x33,	0x34,
 [0x38]	0x35,	0x3a,	0x3b,	0x3c,	0x3d,	0x3e,	0x3f,	0x40,
-[0x40]	0x41,	0x42,	0x43,	0x44,	0x57,	0x58,	0x63,	0x46,
-[0x48]	0x77,	0x52,	0x47,	0x49,	0x53,	0x4f,	0x51,	0x4d,
-[0x50]	0x4b,	0x50,	0x48,	0x45,	0x35,	0x37,	0x4a,	0x4e,
-[0x58]	0x1c,	0x4f,	0x50,	0x51,	0x4b,	0x4c,	0x4d,	0x47,
-[0x60]	0x48,	0x49,	0x52,	0x53,	0x56,	0x7f,	0x74,	0x75,
-[0x68]	0x55,	0x59,	0x5a,	0x5b,	0x5c,	0x5d,	0x5e,	0x5f,
-[0x70]	0x78,	0x79,	0x7a,	0x7b,	0x0,	0x0,	0x0,	0x0,
-[0x78]	0x0,	0x0,	0x0,	0x0,	0x0,	0x0,	0x0,	0x71,
-[0x80]	0x73,	0x72,	0x0,	0x0,	0x0,	0x7c,	0x0,	0x0,
+[0x40]	0x41,	0x42,	0x43,	0x44,	0x57,	0x58,	0xe3,	0x46,
+[0x48]	0xf7,	0xd2,	0xc7,	0xc9,	0xd3,	0xcf,	0xd1,	0xcd,
+[0x50]	0xcb,	0xd0,	0xc8,	0x45,	0x35,	0x37,	0x4a,	0x4e,
+[0x58]	0x1c,	0xcf,	0xd0,	0xd1,	0xcb,	0xcc,	0xcd,	0xc7,
+[0x60]	0xc8,	0xc9,	0xd2,	0xd3,	0x56,	0xff,	0xf4,	0xf5,
+[0x68]	0xd5,	0xd9,	0xda,	0xdb,	0xdc,	0xdd,	0xde,	0xdf,
+[0x70]	0xf8,	0xf9,	0xfa,	0xfb,	0x0,	0x0,	0x0,	0x0,
+[0x78]	0x0,	0x0,	0x0,	0x0,	0x0,	0x0,	0x0,	0xf1,
+[0x80]	0xf3,	0xf2,	0x0,	0x0,	0x0,	0xfc,	0x0,	0x0,
 [0x88]	0x0,	0x0,	0x0,	0x0,	0x0,	0x0,	0x0,	0x0,
 [0x90]	0x0,	0x0,	0x0,	0x0,	0x0,	0x0,	0x0,	0x0,
 [0x98]	0x0,	0x0,	0x0,	0x0,	0x0,	0x0,	0x0,	0x0,
@@ -90,8 +95,8 @@
 [0xc8]	0x0,	0x0,	0x0,	0x0,	0x0,	0x0,	0x0,	0x0,
 [0xd0]	0x0,	0x0,	0x0,	0x0,	0x0,	0x0,	0x0,	0x0,
 [0xd8]	0x0,	0x0,	0x0,	0x0,	0x0,	0x0,	0x0,	0x0,
-[0xe0]	0x1d,	0x2a,	0x38,	0x7d,	0x61,	0x36,	0x64,	0x7e,
-[0xe8]	0x0,	0x0,	0x0,	0x0,	0x0,	0x73,	0x72,	0x71,
+[0xe0]	0x1d,	0x2a,	0xb8,	0xfd,	0xe1,	0x36,	0xe4,	0xfe,
+[0xe8]	0x0,	0x0,	0x0,	0x0,	0x0,	0xf3,	0xf2,	0xf1,
 [0xf0]	0x0,	0x0,	0x0,	0x0,	0x0,	0x0,	0x0,	0x0,
 [0xf8]	0x0,	0x0,	0x0,	0x0,	0x0,	0x0,	0x0,	0x0,
 };
@@ -513,14 +518,16 @@
 }
 
 static void
-putscan(int fd, uchar esc, uchar sc)
+putscan(int fd, uchar sc, uchar up)
 {
 	uchar s[2] = {SCesc1, 0};
 
-	s[1] = sc;
-	if(esc && sc != 0)
+	if(sc == 0)
+		return;
+	s[1] = up | sc&Keymask;
+	if(isext(sc))
 		write(fd, s, 2);
-	else if(sc != 0)
+	else
 		write(fd, s+1, 1);
 }
 
@@ -563,7 +570,7 @@
 	Channel *repeatc, *sleepc;
 	int kbdinfd;
 	ulong l, t;
-	uchar esc1, sc;
+	uchar sc;
 	Alt a[3];
 
 	repeatc = f->repeatc;
@@ -590,13 +597,12 @@
 			l = recvul(repeatc);
 			continue;
 		}
-		esc1 = l >> 8;
-		sc = l;
+		sc = l & 0xff;
 		t = Kbdelay;
 		if(alt(a) == 1){
 			t = Kbrepeat;
 			while(alt(a) == 1)
-				putscan(kbdinfd, esc1, sc);
+				putscan(kbdinfd, sc, 0);
 		}
 	}
 	if(sleepc != nil)
@@ -612,19 +618,11 @@
 }
 
 static void
-startrepeat(KDev *f, uchar esc1, uchar sc)
+startrepeat(KDev *f, uchar sc)
 {
-	ulong c;
-
-	if(esc1)
-		c = SCesc1 << 8 | (sc & 0xff);
-	else
-		c = sc;
-	sendul(f->repeatc, c);
+	sendul(f->repeatc, sc);
 }
 
-#define hasesc1(sc)	(((sc) >= 0x47) || ((sc) == 0x38))
-
 /*
  * This routine diffs the state with the last known state
  * and invents the scan codes that would have been sent
@@ -654,8 +652,8 @@
 			 	break;
 		if(j == n && buf[i] != 0){
 			dk = sctab[buf[i]];
-			putscan(fd, hasesc1(dk), dk);
-			startrepeat(f, hasesc1(dk), dk);
+			putscan(fd, dk, 0);
+			startrepeat(f, dk);
 		}
 	}
 
@@ -667,7 +665,7 @@
 				break;
 		if(j == n && obuf[i] != 0){
 			uk = sctab[obuf[i]];
-			putscan(fd, hasesc1(uk), uk|Keyup);
+			putscan(fd, uk, Keyup);
 		}
 	}
 	if(uk && (dk == 0 || dk == uk)){
--- a/sys/src/cmd/rio/wind.c
+++ b/sys/src/cmd/rio/wind.c
@@ -471,7 +471,7 @@
 	int i;
 	Fmt f;
 	Rune *rp;
-	uint nr, qline, q0;
+	uint nr, qline;
 	char *s;
 
 	runefmtstrinit(&f);
@@ -490,20 +490,21 @@
 		}
 		fmtprint(&f, "]\n");
 	}
-	/* place text at beginning of line before host point */
-	qline = w->qh;
-	while(qline>0 && w->r[qline-1] != '\n')
-		qline--;
-
 	rp = runefmtstrflush(&f);
 	nr = runestrlen(rp);
 
-	q0 = w->q0;
-	q0 += winsert(w, rp, nr, qline) - qline;
-	if(q0 >= w->qh)
-		w->qh += nr;
+	/* place text at beginning of line before cursor and host point */
+	qline = min(w->qh, w->q0);
+	while(qline>0 && w->r[qline-1] != '\n')
+		qline--;
+
+	if(qline == w->qh){
+		/* advance host point to avoid readback */
+		w->qh = winsert(w, rp, nr, qline)+nr;
+	} else {
+		winsert(w, rp, nr, qline);
+	}
 	free(rp);
-	wsetselect(w, q0+nr, q0+nr);
 }
 
 Rune*
--- a/sys/src/cmd/srv.c
+++ b/sys/src/cmd/srv.c
@@ -51,6 +51,7 @@
 		rfork(RFNOTEG);
 		dup(p[0], 0);
 		dup(p[0], 1);
+		close(p[0]);
 		close(p[1]);
 		execl("/bin/rc", "rc", "-c", cmd, nil);
 		fprint(2, "exec failed: %r\n");