add an Error type to be used as a singleton pointer

put all the code in one file for now to work around compiler bug

R=gri,rsc
DELTA=168  (120 added, 41 deleted, 7 changed)
OCL=15100
CL=15100
diff --git a/src/lib/os/Makefile b/src/lib/os/Makefile
index 1196cf7..a9b3271 100644
--- a/src/lib/os/Makefile
+++ b/src/lib/os/Makefile
@@ -5,21 +5,20 @@
 O=6
 GC=$(O)g
 
-PKG=os.a
+PKG=$(GOROOT)/pkg/os.a
 
-OFILES=\
-	os.$O \
-	os_file.$O \
-
+O1=\
+	os.$O
 
 install: $(PKG)
-	cp $(PKG) $(GOROOT)/pkg/$(PKG)
 
-$(PKG): $(OFILES)
-	$(O)ar grc $(PKG) $(OFILES)
+$(PKG): a1
+
+a1: 	$(O1)
+	$(O)ar grc $(PKG) $(O1)
 
 nuke:
-	rm -f *.$(O) *.a $(GOROOT)/pkg/$(PKG)
+	rm -f *.$(O) *.a $(PKG)
 
 clean:
 	rm -f *.$(O) *.a
diff --git a/src/lib/os/os.go b/src/lib/os/os.go
index 0759a09..85417ba 100644
--- a/src/lib/os/os.go
+++ b/src/lib/os/os.go
@@ -4,7 +4,11 @@
 
 package os
 
-// Support routines for OS library
+import syscall "syscall"
+
+// Support types and routines for OS library
+
+func WriteString(fd int64, s string) (ret int64, err *Error);
 
 export func StringToBytes(b *[]byte, s string) bool {
 	if len(s) >= len(b) {
@@ -16,3 +20,117 @@
 	b[len(s)] = '\000';	// not necessary - memory is zeroed - but be explicit
 	return true
 }
+
+// Errors are singleton structures. Use the Print()/String() methods to get their contents --
+// it handles the nil (no error) case.
+
+export type Error struct {
+	s string
+}
+
+const NoError = "No Error"
+
+func (e *Error) Print() {
+	if e == nil {
+		WriteString(2, NoError)
+	} else {
+		WriteString(2, e.s)
+	}
+}
+
+func (e *Error) String() string {
+	if e == nil {
+		return NoError
+	} else {
+		return e.s
+	}
+}
+
+var ErrorTab = new(map[int64] *Error);
+
+func ErrnoToError(errno int64) *Error {
+	if errno == 0 {
+		return nil
+	}
+	err, ok := ErrorTab[errno]
+	if ok {
+		return err
+	}
+	e := new(Error);
+	e.s = syscall.errstr(errno);
+	ErrorTab[errno] = e;
+	return e;
+}
+
+export var (
+	ENONE = ErrnoToError(syscall.ENONE);
+	EPERM = ErrnoToError(syscall.EPERM);
+	ENOENT = ErrnoToError(syscall.ENOENT);
+	ESRCH = ErrnoToError(syscall.ESRCH);
+	EINTR = ErrnoToError(syscall.EINTR);
+	EIO = ErrnoToError(syscall.EIO);
+	ENXIO = ErrnoToError(syscall.ENXIO);
+	E2BIG = ErrnoToError(syscall.E2BIG);
+	ENOEXEC = ErrnoToError(syscall.ENOEXEC);
+	EBADF = ErrnoToError(syscall.EBADF);
+	ECHILD = ErrnoToError(syscall.ECHILD);
+	EDEADLK = ErrnoToError(syscall.EDEADLK);
+	ENOMEM = ErrnoToError(syscall.ENOMEM);
+	EACCES = ErrnoToError(syscall.EACCES);
+	EFAULT = ErrnoToError(syscall.EFAULT);
+	ENOTBLK = ErrnoToError(syscall.ENOTBLK);
+	EBUSY = ErrnoToError(syscall.EBUSY);
+	EEXIST = ErrnoToError(syscall.EEXIST);
+	EXDEV = ErrnoToError(syscall.EXDEV);
+	ENODEV = ErrnoToError(syscall.ENODEV);
+	ENOTDIR = ErrnoToError(syscall.ENOTDIR);
+	EISDIR = ErrnoToError(syscall.EISDIR);
+	EINVAL = ErrnoToError(syscall.EINVAL);
+	ENFILE = ErrnoToError(syscall.ENFILE);
+	EMFILE = ErrnoToError(syscall.EMFILE);
+	ENOTTY = ErrnoToError(syscall.ENOTTY);
+	ETXTBSY = ErrnoToError(syscall.ETXTBSY);
+	EFBIG = ErrnoToError(syscall.EFBIG);
+	ENOSPC = ErrnoToError(syscall.ENOSPC);
+	ESPIPE = ErrnoToError(syscall.ESPIPE);
+	EROFS = ErrnoToError(syscall.EROFS);
+	EMLINK = ErrnoToError(syscall.EMLINK);
+	EPIPE = ErrnoToError(syscall.EPIPE);
+	EDOM = ErrnoToError(syscall.EDOM);
+	ERANGE = ErrnoToError(syscall.ERANGE);
+	EAGAIN = ErrnoToError(syscall.EAGAIN);
+)
+
+export func Open(name string, mode int64, flags int64) (ret int64, err *Error) {
+	var buf [512]byte;
+	if !StringToBytes(&buf, name) {
+		return -1, ErrnoToError(syscall.ENAMETOOLONG)
+	}
+	r, e := syscall.open(&buf[0], mode, flags);
+	return r, ErrnoToError(e)
+}
+
+export func Close(fd int64) (ret int64, err *Error) {
+	r, e := syscall.close(fd);
+	return r, ErrnoToError(e)
+}
+
+export func Read(fd int64, b *[]byte) (ret int64, err *Error) {
+	r, e := syscall.read(fd, &b[0], int64(len(b)));
+	return r, ErrnoToError(e)
+}
+
+export func Write(fd int64, b *[]byte) (ret int64, err *Error) {
+	r, e := syscall.write(fd, &b[0], int64(len(b)));
+	return r, ErrnoToError(e)
+}
+
+export func WriteString(fd int64, s string) (ret int64, err *Error) {
+	b := new([]byte, len(s)+1);
+	if !StringToBytes(b, s) {
+		return -1, ErrnoToError(syscall.ENAMETOOLONG)
+	}
+	r, e := syscall.write(fd, &b[0], int64(len(s)));
+	return r, ErrnoToError(e)
+}
+
diff --git a/src/lib/os/os_file.go b/src/lib/os/os_file.go
deleted file mode 100644
index 8edb2d0..0000000
--- a/src/lib/os/os_file.go
+++ /dev/null
@@ -1,42 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package os
-
-import syscall "syscall"
-import os "os"
-
-export func Open(name string, mode int64, flags int64) (ret int64, errno int64) {
-	var buf [512]byte;
-	if !StringToBytes(&buf, name) {
-		return -1, syscall.ENAMETOOLONG
-	}
-	r, e := syscall.open(&buf[0], mode, flags);  // BUG: should be able to just return
-	return r, e
-}
-
-export func Close(fd int64) (ret int64, errno int64) {
-	r, e := syscall.close(fd);  // BUG: should be able to just return
-	return r, e
-}
-
-export func Read(fd int64, b *[]byte) (ret int64, errno int64) {
-	r, e := syscall.read(fd, &b[0], int64(len(b)));  // BUG: should be able to just return
-	return r, e
-}
-
-export func Write(fd int64, b *[]byte) (ret int64, errno int64) {
-	r, e := syscall.write(fd, &b[0], int64(len(b)));  // BUG: should be able to just return
-	return r, e
-}
-
-export func WriteString(fd int64, s string) (ret int64, errno int64) {
-	b := new([]byte, len(s)+1);
-	if !StringToBytes(b, s) {
-		return -1, syscall.EIO
-	}
-	r, e := syscall.write(fd, &b[0], int64(len(s)));  // BUG: should be able to just return
-	return r, e
-}
-