Change os.Error convention:
echo back context of call in error if likely to be useful.

For example, if os.Open("/etc/passwd", os.O_RDONLY)
fails with syscall.EPERM, it returns as the os.Error

	&PathError{
		Op: "open",
		Path: "/etc/passwd"
		Error: os.EPERM
	}

which formats as

	open /etc/passwd: permission denied

Not converted:

	datafmt
	go/...
	google/...
	regexp
	tabwriter
	template

R=r
DELTA=1153  (561 added, 156 deleted, 436 changed)
OCL=30738
CL=30781
diff --git a/src/pkg/os/error.go b/src/pkg/os/error.go
index 718499b..10a7d04 100644
--- a/src/pkg/os/error.go
+++ b/src/pkg/os/error.go
@@ -30,15 +30,6 @@
 	return syscall.Errstr(int(e))
 }
 
-// ErrnoToError converts errno to an Error (underneath, an Errno).
-// It returns nil for the "no error" errno.
-func ErrnoToError(errno int) Error {
-	if errno == 0 {
-		return nil
-	}
-	return Errno(errno)
-}
-
 // Commonly known Unix errors.
 var (
 	EPERM Error = Errno(syscall.EPERM);
@@ -81,3 +72,33 @@
 	ENAMETOOLONG Error = Errno(syscall.ENAMETOOLONG);
 )
 
+// PathError records an error and the operation and file path that caused it.
+type PathError struct {
+	Op string;
+	Path string;
+	Error Error;
+}
+
+func (e *PathError) String() string {
+	return e.Op + " " + e.Path + ": " + e.Error.String();
+}
+
+// SyscallError records an error from a specific system call.
+type SyscallError struct {
+	Syscall string;
+	Errno Errno;
+}
+
+func (e *SyscallError) String() string {
+	return e.Syscall + ": " + e.Errno.String();
+}
+
+// NewSyscallError returns, as an os.Error, a new SyscallError
+// with the given system call name and error number.
+// As a convenience, if errno is 0, NewSyscallError returns nil.
+func NewSyscallError(syscall string, errno int) os.Error {
+	if errno == 0 {
+		return nil;
+	}
+	return &SyscallError{syscall, Errno(errno)}
+}