summaryrefslogtreecommitdiff
path: root/src/lib/os/error.go
diff options
context:
space:
mode:
authorRob Pike <r@golang.org>2009-02-10 16:40:06 -0800
committerRob Pike <r@golang.org>2009-02-10 16:40:06 -0800
commit879b59292bb9e353db4119de2f9f4fe2f9a9f5b0 (patch)
tree03c80d9386fe4cae2f10d51b4732f643d6401868 /src/lib/os/error.go
parent7084c22609d33779cea64c51d2a4d14260c9f2cd (diff)
downloadgolang-879b59292bb9e353db4119de2f9f4fe2f9a9f5b0.tar.gz
drop the os_ prefix on the file names in os. os_test.go can stay.
R=rsc DELTA=793 (392 added, 392 deleted, 9 changed) OCL=24777 CL=24804
Diffstat (limited to 'src/lib/os/error.go')
-rw-r--r--src/lib/os/error.go100
1 files changed, 100 insertions, 0 deletions
diff --git a/src/lib/os/error.go b/src/lib/os/error.go
new file mode 100644
index 000000000..63b2dbcca
--- /dev/null
+++ b/src/lib/os/error.go
@@ -0,0 +1,100 @@
+// 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"
+
+// Errors are singleton structures. Use the String() method to get their contents --
+// it handles the nil (no error) case.
+type Error struct {
+ s string
+}
+
+// Indexed by errno.
+// If we worry about syscall speed (only relevant on failure), we could
+// make it an array, but it's probably not important.
+var errorTab = make(map[int64] *Error);
+
+// Table of all known errors in system. Use the same error string twice,
+// get the same *os.Error.
+var errorStringTab = make(map[string] *Error);
+
+// These functions contain a race if two goroutines add identical
+// errors simultaneously but the consequences are unimportant.
+
+// Allocate an Error object, but if it's been seen before, share that one.
+func NewError(s string) *Error {
+ if s == "" {
+ return nil
+ }
+ err, ok := errorStringTab[s];
+ if ok {
+ return err
+ }
+ err = &Error{s};
+ errorStringTab[s] = err;
+ return err;
+}
+
+// Allocate an Error objecct, but if it's been seen before, share that one.
+func ErrnoToError(errno int64) *Error {
+ if errno == 0 {
+ return nil
+ }
+ // Quick lookup by errno.
+ err, ok := errorTab[errno];
+ if ok {
+ return err
+ }
+ err = NewError(syscall.Errstr(errno));
+ errorTab[errno] = err;
+ return err;
+}
+
+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);
+)
+
+func (e *Error) String() string {
+ if e == nil {
+ return "No Error"
+ }
+ return e.s
+}