From: Rob Pike Date: Fri, 17 Apr 2009 07:36:15 +0000 (-0700) Subject: Step 2 of the Big Error Shift. X-Git-Tag: weekly.2009-11-06~1805 X-Git-Url: http://www.git.cypherpunks.su/?a=commitdiff_plain;h=45ed7297e85bc9bd50c0a1dfae3c6ea3fe997070;p=gostls13.git Step 2 of the Big Error Shift. Change the representation of errors in "os" to be cleaner. (But they are not really representative of the power of the new scheme.) Step 3 will be to remove all references to os.NewError. Step 4 will be to delete the second half of lib/os/error.go. R=rsc OCL=27587 CL=27587 --- diff --git a/src/lib/os/error.go b/src/lib/os/error.go index 69565d6a58..dbba16c03e 100644 --- a/src/lib/os/error.go +++ b/src/lib/os/error.go @@ -18,6 +18,67 @@ func (e *ErrorString) String() string { return *e } +// Errno is the Unix error number. Names such as EINVAL are simple +// wrappers to convert the error number into an Error. +type Errno int64 +func (e Errno) String() string { + return syscall.Errstr(e) +} + +// ErrnoToError calls NewError to create an _Error object for the string +// associated with Unix error code errno. +func ErrnoToError(errno int64) Error { + if errno == 0 { + return nil + } + return Errno(errno) +} + +// Commonly known Unix errors. +var ( + ENONE Error = Errno(syscall.ENONE); + EPERM Error = Errno(syscall.EPERM); + ENOENT Error = Errno(syscall.ENOENT); + ESRCH Error = Errno(syscall.ESRCH); + EINTR Error = Errno(syscall.EINTR); + EIO Error = Errno(syscall.EIO); + ENXIO Error = Errno(syscall.ENXIO); + E2BIG Error = Errno(syscall.E2BIG); + ENOEXEC Error = Errno(syscall.ENOEXEC); + EBADF Error = Errno(syscall.EBADF); + ECHILD Error = Errno(syscall.ECHILD); + EDEADLK Error = Errno(syscall.EDEADLK); + ENOMEM Error = Errno(syscall.ENOMEM); + EACCES Error = Errno(syscall.EACCES); + EFAULT Error = Errno(syscall.EFAULT); + ENOTBLK Error = Errno(syscall.ENOTBLK); + EBUSY Error = Errno(syscall.EBUSY); + EEXIST Error = Errno(syscall.EEXIST); + EXDEV Error = Errno(syscall.EXDEV); + ENODEV Error = Errno(syscall.ENODEV); + ENOTDIR Error = Errno(syscall.ENOTDIR); + EISDIR Error = Errno(syscall.EISDIR); + EINVAL Error = Errno(syscall.EINVAL); + ENFILE Error = Errno(syscall.ENFILE); + EMFILE Error = Errno(syscall.EMFILE); + ENOTTY Error = Errno(syscall.ENOTTY); + ETXTBSY Error = Errno(syscall.ETXTBSY); + EFBIG Error = Errno(syscall.EFBIG); + ENOSPC Error = Errno(syscall.ENOSPC); + ESPIPE Error = Errno(syscall.ESPIPE); + EROFS Error = Errno(syscall.EROFS); + EMLINK Error = Errno(syscall.EMLINK); + EPIPE Error = Errno(syscall.EPIPE); + EAGAIN Error = Errno(syscall.EAGAIN); + EDOM Error = Errno(syscall.EDOM); + ERANGE Error = Errno(syscall.ERANGE); +) + +// ----------------------- +// Everything below here is deprecated. +// Delete when all callers of NewError are gone and their uses converted +// to the new error scheme (for an example, see template). + // _Error is a structure wrapping a string describing an error. // Errors are singleton structures, created by NewError, so their addresses can // be compared to test for equality. A nil Error pointer means ``no error''. @@ -28,11 +89,6 @@ 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); @@ -55,66 +111,6 @@ func NewError(s string) Error { return err; } -// ErrnoToError calls NewError to create an _Error object for the string -// associated with Unix error code errno. -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; -} - -// Commonly known Unix errors. -var ( - // TODO(r): - // 1. these become type ENONE struct { ErrorString } - // 2. create private instances of each type: var eNONE ENONE(ErrnoToString(syscall.ENONE)); - // 3. put them in a table - // 4. ErrnoToError uses the table. its error case ECATCHALL("%d") - 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); -) // String returns the string associated with the _Error. func (e *_Error) String() string {