github.com/likebike/go--@v0.0.0-20190911215757-0bd925d16e96/go/src/os/error.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  	"internal/poll"
    10  )
    11  
    12  // Portable analogs of some common system call errors.
    13  var (
    14  	ErrInvalid    = errors.New("invalid argument") // methods on File will return this error when the receiver is nil
    15  	ErrPermission = errors.New("permission denied")
    16  	ErrExist      = errors.New("file already exists")
    17  	ErrNotExist   = errors.New("file does not exist")
    18  	ErrClosed     = errors.New("file already closed")
    19  	ErrNoDeadline = poll.ErrNoDeadline
    20  )
    21  
    22  type timeout interface {
    23  	Timeout() bool
    24  }
    25  
    26  // PathError records an error and the operation and file path that caused it.
    27  type PathError struct {
    28  	Op   string
    29  	Path string
    30  	Err  error
    31  }
    32  
    33  func (e *PathError) Error() string { return e.Op + " " + e.Path + ": " + e.Err.Error() }
    34  
    35  // Timeout reports whether this error represents a timeout.
    36  func (e *PathError) Timeout() bool {
    37  	t, ok := e.Err.(timeout)
    38  	return ok && t.Timeout()
    39  }
    40  
    41  // SyscallError records an error from a specific system call.
    42  type SyscallError struct {
    43  	Syscall string
    44  	Err     error
    45  }
    46  
    47  func (e *SyscallError) Error() string { return e.Syscall + ": " + e.Err.Error() }
    48  
    49  // Timeout reports whether this error represents a timeout.
    50  func (e *SyscallError) Timeout() bool {
    51  	t, ok := e.Err.(timeout)
    52  	return ok && t.Timeout()
    53  }
    54  
    55  // NewSyscallError returns, as an error, a new SyscallError
    56  // with the given system call name and error details.
    57  // As a convenience, if err is nil, NewSyscallError returns nil.
    58  func NewSyscallError(syscall string, err error) error {
    59  	if err == nil {
    60  		return nil
    61  	}
    62  	return &SyscallError{syscall, err}
    63  }
    64  
    65  // IsExist returns a boolean indicating whether the error is known to report
    66  // that a file or directory already exists. It is satisfied by ErrExist as
    67  // well as some syscall errors.
    68  func IsExist(err error) bool {
    69  	return isExist(err)
    70  }
    71  
    72  // IsNotExist returns a boolean indicating whether the error is known to
    73  // report that a file or directory does not exist. It is satisfied by
    74  // ErrNotExist as well as some syscall errors.
    75  func IsNotExist(err error) bool {
    76  	return isNotExist(err)
    77  }
    78  
    79  // IsPermission returns a boolean indicating whether the error is known to
    80  // report that permission is denied. It is satisfied by ErrPermission as well
    81  // as some syscall errors.
    82  func IsPermission(err error) bool {
    83  	return isPermission(err)
    84  }
    85  
    86  // IsTimeout returns a boolean indicating whether the error is known
    87  // to report that a timeout occurred.
    88  func IsTimeout(err error) bool {
    89  	terr, ok := underlyingError(err).(timeout)
    90  	return ok && terr.Timeout()
    91  }
    92  
    93  // underlyingError returns the underlying error for known os error types.
    94  func underlyingError(err error) error {
    95  	switch err := err.(type) {
    96  	case *PathError:
    97  		return err.Err
    98  	case *LinkError:
    99  		return err.Err
   100  	case *SyscallError:
   101  		return err.Err
   102  	}
   103  	return err
   104  }