github.com/tinygo-org/tinygo@v0.31.3-0.20240404173401-90b0bf646c27/src/os/errors.go (about) 1 // Copyright 2009 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 package os 6 7 import ( 8 "errors" 9 "io/fs" 10 "syscall" 11 ) 12 13 // Portable analogs of some common system call errors. 14 // 15 // Errors returned from this package may be tested against these errors 16 // with errors.Is. 17 var ( 18 // ErrInvalid indicates an invalid argument. 19 // Methods on File will return this error when the receiver is nil. 20 ErrInvalid = fs.ErrInvalid // "invalid argument" 21 22 ErrPermission = fs.ErrPermission // "permission denied" 23 ErrExist = fs.ErrExist // "file already exists" 24 ErrNotExist = fs.ErrNotExist // "file does not exist" 25 ErrClosed = fs.ErrClosed // "file already closed" 26 27 // Note that these are exported for use in the Filesystem interface. 28 ErrUnsupported = errors.New("operation not supported") 29 ErrNotImplemented = errors.New("operation not implemented") 30 ) 31 32 // The following code is copied from the official implementation. 33 // src/internal/poll/fd.go 34 35 // ErrNoDeadline is returned when a request is made to set a deadline 36 // on a file type that does not use the poller. 37 var ErrNoDeadline = errors.New("file type does not support deadline") 38 39 // ErrDeadlineExceeded is returned for an expired deadline. 40 // This is exported by the os package as os.ErrDeadlineExceeded. 41 var ErrDeadlineExceeded error = &DeadlineExceededError{} 42 43 // DeadlineExceededError is returned for an expired deadline. 44 type DeadlineExceededError struct{} 45 46 // Implement the net.Error interface. 47 // The string is "i/o timeout" because that is what was returned 48 // by earlier Go versions. Changing it may break programs that 49 // match on error strings. 50 func (e *DeadlineExceededError) Error() string { return "i/o timeout" } 51 func (e *DeadlineExceededError) Timeout() bool { return true } 52 func (e *DeadlineExceededError) Temporary() bool { return true } 53 54 // The following code is copied from the official implementation. 55 // https://github.com/golang/go/blob/4ce6a8e89668b87dce67e2f55802903d6eb9110a/src/os/error.go#L65-L104 56 57 func NewSyscallError(syscall string, err error) error { 58 if err == nil { 59 return nil 60 } 61 return &SyscallError{syscall, err} 62 } 63 64 // PathError records an error and the operation and file path that caused it. 65 type PathError = fs.PathError 66 67 // SyscallError records an error from a specific system call. 68 type SyscallError struct { 69 Syscall string 70 Err error 71 } 72 73 func (e *SyscallError) Error() string { return e.Syscall + ": " + e.Err.Error() } 74 75 func (e *SyscallError) Unwrap() error { return e.Err } 76 77 type timeout interface { 78 Timeout() bool 79 } 80 81 // Timeout reports whether this error represents a timeout. 82 func (e *SyscallError) Timeout() bool { 83 t, ok := e.Err.(timeout) 84 return ok && t.Timeout() 85 } 86 87 func IsExist(err error) bool { 88 return underlyingErrorIs(err, ErrExist) 89 } 90 91 func IsNotExist(err error) bool { 92 return underlyingErrorIs(err, ErrNotExist) 93 } 94 95 func IsPermission(err error) bool { 96 return underlyingErrorIs(err, ErrPermission) 97 } 98 99 func IsTimeout(err error) bool { 100 terr, ok := underlyingError(err).(timeout) 101 return ok && terr.Timeout() 102 } 103 104 func underlyingErrorIs(err, target error) bool { 105 // Note that this function is not errors.Is: 106 // underlyingError only unwraps the specific error-wrapping types 107 // that it historically did, not all errors implementing Unwrap(). 108 err = underlyingError(err) 109 if err == target { 110 return true 111 } 112 // To preserve prior behavior, only examine syscall errors. 113 e, ok := err.(syscall.Errno) 114 return ok && e.Is(target) 115 } 116 117 // underlyingError returns the underlying error for known os error types. 118 func underlyingError(err error) error { 119 switch err := err.(type) { 120 case *PathError: 121 return err.Err 122 case *SyscallError: 123 return err.Err 124 } 125 return err 126 }