Fighting the good fight.

Move libfmt, libutf into subdirectories of lib9.

Add poll-based socket i/o to libthread, so that we can
avoid using multiple procs when possible, thus removing
dependence on crappy pthreads implementations.

Convert samterm, acme to the single-proc libthread.

Bring libcomplete, acme up-to-date w.r.t. Plan 9 distribution.
diff --git a/src/libfs/fs.c b/src/libfs/fs.c
index 91d4af1..d912391 100644
--- a/src/libfs/fs.c
+++ b/src/libfs/fs.c
@@ -5,6 +5,7 @@
 #include <libc.h>
 #include <fcall.h>
 #include <fs.h>
+#include <thread.h>
 #include "fsimpl.h"
 
 static int _fssend(Mux*, void*);
@@ -270,7 +271,7 @@
 	Fsys *fs;
 
 	fs = mux->aux;
-	n = readn(fs->fd, buf, 4);
+	n = threadreadn(fs->fd, buf, 4);
 	if(n != 4)
 		return nil;
 	n = GBIT32(buf);
@@ -280,12 +281,12 @@
 		return nil;
 	}
 	PBIT32(pkt, n);
-	if(readn(fs->fd, pkt+4, n-4) != n-4){
+	if(threadreadn(fs->fd, pkt+4, n-4) != n-4){
 		free(pkt);
 		return nil;
 	}
 	if(pkt[4] == Ropenfd){
-		if((nfd=recvfd(fs->fd)) < 0){
+		if((nfd=threadrecvfd(fs->fd)) < 0){
 			fprint(2, "recv fd error: %r\n");
 			free(pkt);
 			return nil;
diff --git a/src/libfs/read.c b/src/libfs/read.c
index 1ef2cb3..7cd4fd1 100644
--- a/src/libfs/read.c
+++ b/src/libfs/read.c
@@ -12,7 +12,12 @@
 {
 	Fcall tx, rx;
 	void *freep;
+	uint msize;
 
+	msize = fid->fs->msize - IOHDRSZ;
+fprint(2, "n %d msize %d\n", n, msize);
+	if(n > msize)
+		n = msize;
 	tx.type = Tread;
 	tx.fid = fid->fid;
 	if(offset == -1){
diff --git a/src/libfs/write.c b/src/libfs/write.c
index 5652b49..bae2083 100644
--- a/src/libfs/write.c
+++ b/src/libfs/write.c
@@ -7,8 +7,8 @@
 #include <fs.h>
 #include "fsimpl.h"
 
-long
-fspwrite(Fid *fid, void *buf, long n, vlong offset)
+static long
+_fspwrite(Fid *fid, void *buf, long n, vlong offset)
 {
 	Fcall tx, rx;
 	void *freep;
@@ -40,6 +40,31 @@
 }
 
 long
+fspwrite(Fid *fid, void *buf, long n, vlong offset)
+{
+	long tot, want, got;
+	uint msize;
+
+	msize = fid->fs->msize - IOHDRSZ;
+	tot = 0;
+	while(tot < n){
+		want = n - tot;
+		if(want > msize)
+			want = msize;
+		got = _fspwrite(fid, buf, want, offset);
+		if(got < 0){
+			if(tot == 0)
+				return got;
+			break;
+		}
+		tot += got;
+		if(offset != -1)
+			offset += got;
+	}
+	return tot;
+}
+
+long
 fswrite(Fid *fid, void *buf, long n)
 {
 	return fspwrite(fid, buf, n, -1);