github.com/SagerNet/gvisor@v0.0.0-20210707092255-7731c139d75c/pkg/errors/linuxerr/linuxerr.go (about)

     1  // Copyright 2021 The gVisor Authors.
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License"),;
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //     http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  // Package linuxerr contains syscall error codes exported as an error interface
    16  // pointers. This allows for fast comparison and return operations comperable
    17  // to unix.Errno constants.
    18  package linuxerr
    19  
    20  import (
    21  	"fmt"
    22  
    23  	"golang.org/x/sys/unix"
    24  	"github.com/SagerNet/gvisor/pkg/abi/linux/errno"
    25  	"github.com/SagerNet/gvisor/pkg/errors"
    26  )
    27  
    28  const maxErrno uint32 = errno.EHWPOISON + 1
    29  
    30  var (
    31  	NOERROR = errors.New(errno.NOERRNO, "not an error")
    32  	EPERM   = errors.New(errno.EPERM, "operation not permitted")
    33  	ENOENT  = errors.New(errno.ENOENT, "no such file or directory")
    34  	ESRCH   = errors.New(errno.ESRCH, "no such process")
    35  	EINTR   = errors.New(errno.EINTR, "interrupted system call")
    36  	EIO     = errors.New(errno.EIO, "I/O error")
    37  	ENXIO   = errors.New(errno.ENXIO, "no such device or address")
    38  	E2BIG   = errors.New(errno.E2BIG, "argument list too long")
    39  	ENOEXEC = errors.New(errno.ENOEXEC, "exec format error")
    40  	EBADF   = errors.New(errno.EBADF, "bad file number")
    41  	ECHILD  = errors.New(errno.ECHILD, "no child processes")
    42  	EAGAIN  = errors.New(errno.EAGAIN, "try again")
    43  	ENOMEM  = errors.New(errno.ENOMEM, "out of memory")
    44  	EACCES  = errors.New(errno.EACCES, "permission denied")
    45  	EFAULT  = errors.New(errno.EFAULT, "bad address")
    46  	ENOTBLK = errors.New(errno.ENOTBLK, "block device required")
    47  	EBUSY   = errors.New(errno.EBUSY, "device or resource busy")
    48  	EEXIST  = errors.New(errno.EEXIST, "file exists")
    49  	EXDEV   = errors.New(errno.EXDEV, "cross-device link")
    50  	ENODEV  = errors.New(errno.ENODEV, "no such device")
    51  	ENOTDIR = errors.New(errno.ENOTDIR, "not a directory")
    52  	EISDIR  = errors.New(errno.EISDIR, "is a directory")
    53  	EINVAL  = errors.New(errno.EINVAL, "invalid argument")
    54  	ENFILE  = errors.New(errno.ENFILE, "file table overflow")
    55  	EMFILE  = errors.New(errno.EMFILE, "too many open files")
    56  	ENOTTY  = errors.New(errno.ENOTTY, "not a typewriter")
    57  	ETXTBSY = errors.New(errno.ETXTBSY, "text file busy")
    58  	EFBIG   = errors.New(errno.EFBIG, "file too large")
    59  	ENOSPC  = errors.New(errno.ENOSPC, "no space left on device")
    60  	ESPIPE  = errors.New(errno.ESPIPE, "illegal seek")
    61  	EROFS   = errors.New(errno.EROFS, "read-only file system")
    62  	EMLINK  = errors.New(errno.EMLINK, "too many links")
    63  	EPIPE   = errors.New(errno.EPIPE, "broken pipe")
    64  	EDOM    = errors.New(errno.EDOM, "math argument out of domain of func")
    65  	ERANGE  = errors.New(errno.ERANGE, "math result not representable")
    66  
    67  	// Errno values from include/uapi/asm-generic/errno.h.
    68  	EDEADLK         = errors.New(errno.EDEADLK, "resource deadlock would occur")
    69  	ENAMETOOLONG    = errors.New(errno.ENAMETOOLONG, "file name too long")
    70  	ENOLCK          = errors.New(errno.ENOLCK, "no record locks available")
    71  	ENOSYS          = errors.New(errno.ENOSYS, "invalid system call number")
    72  	ENOTEMPTY       = errors.New(errno.ENOTEMPTY, "directory not empty")
    73  	ELOOP           = errors.New(errno.ELOOP, "too many symbolic links encountered")
    74  	ENOMSG          = errors.New(errno.ENOMSG, "no message of desired type")
    75  	EIDRM           = errors.New(errno.EIDRM, "identifier removed")
    76  	ECHRNG          = errors.New(errno.ECHRNG, "channel number out of range")
    77  	EL2NSYNC        = errors.New(errno.EL2NSYNC, "level 2 not synchronized")
    78  	EL3HLT          = errors.New(errno.EL3HLT, "level 3 halted")
    79  	EL3RST          = errors.New(errno.EL3RST, "level 3 reset")
    80  	ELNRNG          = errors.New(errno.ELNRNG, "link number out of range")
    81  	EUNATCH         = errors.New(errno.EUNATCH, "protocol driver not attached")
    82  	ENOCSI          = errors.New(errno.ENOCSI, "no CSI structure available")
    83  	EL2HLT          = errors.New(errno.EL2HLT, "level 2 halted")
    84  	EBADE           = errors.New(errno.EBADE, "invalid exchange")
    85  	EBADR           = errors.New(errno.EBADR, "invalid request descriptor")
    86  	EXFULL          = errors.New(errno.EXFULL, "exchange full")
    87  	ENOANO          = errors.New(errno.ENOANO, "no anode")
    88  	EBADRQC         = errors.New(errno.EBADRQC, "invalid request code")
    89  	EBADSLT         = errors.New(errno.EBADSLT, "invalid slot")
    90  	EBFONT          = errors.New(errno.EBFONT, "bad font file format")
    91  	ENOSTR          = errors.New(errno.ENOSTR, "device not a stream")
    92  	ENODATA         = errors.New(errno.ENODATA, "no data available")
    93  	ETIME           = errors.New(errno.ETIME, "timer expired")
    94  	ENOSR           = errors.New(errno.ENOSR, "out of streams resources")
    95  	ENOPKG          = errors.New(errno.ENOPKG, "package not installed")
    96  	EREMOTE         = errors.New(errno.EREMOTE, "object is remote")
    97  	ENOLINK         = errors.New(errno.ENOLINK, "link has been severed")
    98  	EADV            = errors.New(errno.EADV, "advertise error")
    99  	ESRMNT          = errors.New(errno.ESRMNT, "srmount error")
   100  	ECOMM           = errors.New(errno.ECOMM, "communication error on send")
   101  	EPROTO          = errors.New(errno.EPROTO, "protocol error")
   102  	EMULTIHOP       = errors.New(errno.EMULTIHOP, "multihop attempted")
   103  	EDOTDOT         = errors.New(errno.EDOTDOT, "RFS specific error")
   104  	EBADMSG         = errors.New(errno.EBADMSG, "not a data message")
   105  	EOVERFLOW       = errors.New(errno.EOVERFLOW, "value too large for defined data type")
   106  	ENOTUNIQ        = errors.New(errno.ENOTUNIQ, "name not unique on network")
   107  	EBADFD          = errors.New(errno.EBADFD, "file descriptor in bad state")
   108  	EREMCHG         = errors.New(errno.EREMCHG, "remote address changed")
   109  	ELIBACC         = errors.New(errno.ELIBACC, "can not access a needed shared library")
   110  	ELIBBAD         = errors.New(errno.ELIBBAD, "accessing a corrupted shared library")
   111  	ELIBSCN         = errors.New(errno.ELIBSCN, ".lib section in a.out corrupted")
   112  	ELIBMAX         = errors.New(errno.ELIBMAX, "attempting to link in too many shared libraries")
   113  	ELIBEXEC        = errors.New(errno.ELIBEXEC, "cannot exec a shared library directly")
   114  	EILSEQ          = errors.New(errno.EILSEQ, "illegal byte sequence")
   115  	ERESTART        = errors.New(errno.ERESTART, "interrupted system call should be restarted")
   116  	ESTRPIPE        = errors.New(errno.ESTRPIPE, "streams pipe error")
   117  	EUSERS          = errors.New(errno.EUSERS, "too many users")
   118  	ENOTSOCK        = errors.New(errno.ENOTSOCK, "socket operation on non-socket")
   119  	EDESTADDRREQ    = errors.New(errno.EDESTADDRREQ, "destination address required")
   120  	EMSGSIZE        = errors.New(errno.EMSGSIZE, "message too long")
   121  	EPROTOTYPE      = errors.New(errno.EPROTOTYPE, "protocol wrong type for socket")
   122  	ENOPROTOOPT     = errors.New(errno.ENOPROTOOPT, "protocol not available")
   123  	EPROTONOSUPPORT = errors.New(errno.EPROTONOSUPPORT, "protocol not supported")
   124  	ESOCKTNOSUPPORT = errors.New(errno.ESOCKTNOSUPPORT, "socket type not supported")
   125  	EOPNOTSUPP      = errors.New(errno.EOPNOTSUPP, "operation not supported on transport endpoint")
   126  	EPFNOSUPPORT    = errors.New(errno.EPFNOSUPPORT, "protocol family not supported")
   127  	EAFNOSUPPORT    = errors.New(errno.EAFNOSUPPORT, "address family not supported by protocol")
   128  	EADDRINUSE      = errors.New(errno.EADDRINUSE, "address already in use")
   129  	EADDRNOTAVAIL   = errors.New(errno.EADDRNOTAVAIL, "cannot assign requested address")
   130  	ENETDOWN        = errors.New(errno.ENETDOWN, "network is down")
   131  	ENETUNREACH     = errors.New(errno.ENETUNREACH, "network is unreachable")
   132  	ENETRESET       = errors.New(errno.ENETRESET, "network dropped connection because of reset")
   133  	ECONNABORTED    = errors.New(errno.ECONNABORTED, "software caused connection abort")
   134  	ECONNRESET      = errors.New(errno.ECONNRESET, "connection reset by peer")
   135  	ENOBUFS         = errors.New(errno.ENOBUFS, "no buffer space available")
   136  	EISCONN         = errors.New(errno.EISCONN, "transport endpoint is already connected")
   137  	ENOTCONN        = errors.New(errno.ENOTCONN, "transport endpoint is not connected")
   138  	ESHUTDOWN       = errors.New(errno.ESHUTDOWN, "cannot send after transport endpoint shutdown")
   139  	ETOOMANYREFS    = errors.New(errno.ETOOMANYREFS, "too many references: cannot splice")
   140  	ETIMEDOUT       = errors.New(errno.ETIMEDOUT, "connection timed out")
   141  	ECONNREFUSED    = errors.New(errno.ECONNREFUSED, "connection refused")
   142  	EHOSTDOWN       = errors.New(errno.EHOSTDOWN, "host is down")
   143  	EHOSTUNREACH    = errors.New(errno.EHOSTUNREACH, "no route to host")
   144  	EALREADY        = errors.New(errno.EALREADY, "operation already in progress")
   145  	EINPROGRESS     = errors.New(errno.EINPROGRESS, "operation now in progress")
   146  	ESTALE          = errors.New(errno.ESTALE, "stale file handle")
   147  	EUCLEAN         = errors.New(errno.EUCLEAN, "structure needs cleaning")
   148  	ENOTNAM         = errors.New(errno.ENOTNAM, "not a XENIX named type file")
   149  	ENAVAIL         = errors.New(errno.ENAVAIL, "no XENIX semaphores available")
   150  	EISNAM          = errors.New(errno.EISNAM, "is a named type file")
   151  	EREMOTEIO       = errors.New(errno.EREMOTEIO, "remote I/O error")
   152  	EDQUOT          = errors.New(errno.EDQUOT, "quota exceeded")
   153  	ENOMEDIUM       = errors.New(errno.ENOMEDIUM, "no medium found")
   154  	EMEDIUMTYPE     = errors.New(errno.EMEDIUMTYPE, "wrong medium type")
   155  	ECANCELED       = errors.New(errno.ECANCELED, "operation Canceled")
   156  	ENOKEY          = errors.New(errno.ENOKEY, "required key not available")
   157  	EKEYEXPIRED     = errors.New(errno.EKEYEXPIRED, "key has expired")
   158  	EKEYREVOKED     = errors.New(errno.EKEYREVOKED, "key has been revoked")
   159  	EKEYREJECTED    = errors.New(errno.EKEYREJECTED, "key was rejected by service")
   160  	EOWNERDEAD      = errors.New(errno.EOWNERDEAD, "owner died")
   161  	ENOTRECOVERABLE = errors.New(errno.ENOTRECOVERABLE, "state not recoverable")
   162  	ERFKILL         = errors.New(errno.ERFKILL, "operation not possible due to RF-kill")
   163  	EHWPOISON       = errors.New(errno.EHWPOISON, "memory page has hardware error")
   164  
   165  	// Errors equivalent to other errors.
   166  	EWOULDBLOCK = EAGAIN
   167  	EDEADLOCK   = EDEADLK
   168  	ENONET      = ENOENT
   169  	ENOATTR     = ENODATA
   170  	ENOTSUP     = EOPNOTSUPP
   171  )
   172  
   173  // A nil *errors.Error denotes no error and is placed at the 0 index of
   174  // errorSlice. Thus, any other empty index should not be nil or a valid error.
   175  // This marks that index as an invalid error so any comparison to nil or a
   176  // valid linuxerr fails.
   177  var errNotValidError = errors.New(errno.Errno(maxErrno), "not a valid error")
   178  
   179  // The following errorSlice holds errors by errno for fast translation between
   180  // errnos (especially uint32(sycall.Errno)) and *Error.
   181  var errorSlice = []*errors.Error{
   182  	// Errno values from include/uapi/asm-generic/errno-base.h.
   183  	errno.NOERRNO: NOERROR,
   184  	errno.EPERM:   EPERM,
   185  	errno.ENOENT:  ENOENT,
   186  	errno.ESRCH:   ESRCH,
   187  	errno.EINTR:   EINTR,
   188  	errno.EIO:     EIO,
   189  	errno.ENXIO:   ENXIO,
   190  	errno.E2BIG:   E2BIG,
   191  	errno.ENOEXEC: ENOEXEC,
   192  	errno.EBADF:   EBADF,
   193  	errno.ECHILD:  ECHILD,
   194  	errno.EAGAIN:  EAGAIN,
   195  	errno.ENOMEM:  ENOMEM,
   196  	errno.EACCES:  EACCES,
   197  	errno.EFAULT:  EFAULT,
   198  	errno.ENOTBLK: ENOTBLK,
   199  	errno.EBUSY:   EBUSY,
   200  	errno.EEXIST:  EEXIST,
   201  	errno.EXDEV:   EXDEV,
   202  	errno.ENODEV:  ENODEV,
   203  	errno.ENOTDIR: ENOTDIR,
   204  	errno.EISDIR:  EISDIR,
   205  	errno.EINVAL:  EINVAL,
   206  	errno.ENFILE:  ENFILE,
   207  	errno.EMFILE:  EMFILE,
   208  	errno.ENOTTY:  ENOTTY,
   209  	errno.ETXTBSY: ETXTBSY,
   210  	errno.EFBIG:   EFBIG,
   211  	errno.ENOSPC:  ENOSPC,
   212  	errno.ESPIPE:  ESPIPE,
   213  	errno.EROFS:   EROFS,
   214  	errno.EMLINK:  EMLINK,
   215  	errno.EPIPE:   EPIPE,
   216  	errno.EDOM:    EDOM,
   217  	errno.ERANGE:  ERANGE,
   218  
   219  	// Errno values from include/uapi/asm-generic/errno.h.
   220  	errno.EDEADLK:         EDEADLK,
   221  	errno.ENAMETOOLONG:    ENAMETOOLONG,
   222  	errno.ENOLCK:          ENOLCK,
   223  	errno.ENOSYS:          ENOSYS,
   224  	errno.ENOTEMPTY:       ENOTEMPTY,
   225  	errno.ELOOP:           ELOOP,
   226  	errno.ELOOP + 1:       errNotValidError, // No valid errno between ELOOP and ENOMSG.
   227  	errno.ENOMSG:          ENOMSG,
   228  	errno.EIDRM:           EIDRM,
   229  	errno.ECHRNG:          ECHRNG,
   230  	errno.EL2NSYNC:        EL2NSYNC,
   231  	errno.EL3HLT:          EL3HLT,
   232  	errno.EL3RST:          EL3RST,
   233  	errno.ELNRNG:          ELNRNG,
   234  	errno.EUNATCH:         EUNATCH,
   235  	errno.ENOCSI:          ENOCSI,
   236  	errno.EL2HLT:          EL2HLT,
   237  	errno.EBADE:           EBADE,
   238  	errno.EBADR:           EBADR,
   239  	errno.EXFULL:          EXFULL,
   240  	errno.ENOANO:          ENOANO,
   241  	errno.EBADRQC:         EBADRQC,
   242  	errno.EBADSLT:         EBADSLT,
   243  	errno.EBADSLT + 1:     errNotValidError, // No valid errno between EBADSLT and ENOPKG.
   244  	errno.EBFONT:          EBFONT,
   245  	errno.ENOSTR:          ENOSTR,
   246  	errno.ENODATA:         ENODATA,
   247  	errno.ETIME:           ETIME,
   248  	errno.ENOSR:           ENOSR,
   249  	errno.ENOSR + 1:       errNotValidError, // No valid errno betweeen ENOSR and ENOPKG.
   250  	errno.ENOPKG:          ENOPKG,
   251  	errno.EREMOTE:         EREMOTE,
   252  	errno.ENOLINK:         ENOLINK,
   253  	errno.EADV:            EADV,
   254  	errno.ESRMNT:          ESRMNT,
   255  	errno.ECOMM:           ECOMM,
   256  	errno.EPROTO:          EPROTO,
   257  	errno.EMULTIHOP:       EMULTIHOP,
   258  	errno.EDOTDOT:         EDOTDOT,
   259  	errno.EBADMSG:         EBADMSG,
   260  	errno.EOVERFLOW:       EOVERFLOW,
   261  	errno.ENOTUNIQ:        ENOTUNIQ,
   262  	errno.EBADFD:          EBADFD,
   263  	errno.EREMCHG:         EREMCHG,
   264  	errno.ELIBACC:         ELIBACC,
   265  	errno.ELIBBAD:         ELIBBAD,
   266  	errno.ELIBSCN:         ELIBSCN,
   267  	errno.ELIBMAX:         ELIBMAX,
   268  	errno.ELIBEXEC:        ELIBEXEC,
   269  	errno.EILSEQ:          EILSEQ,
   270  	errno.ERESTART:        ERESTART,
   271  	errno.ESTRPIPE:        ESTRPIPE,
   272  	errno.EUSERS:          EUSERS,
   273  	errno.ENOTSOCK:        ENOTSOCK,
   274  	errno.EDESTADDRREQ:    EDESTADDRREQ,
   275  	errno.EMSGSIZE:        EMSGSIZE,
   276  	errno.EPROTOTYPE:      EPROTOTYPE,
   277  	errno.ENOPROTOOPT:     ENOPROTOOPT,
   278  	errno.EPROTONOSUPPORT: EPROTONOSUPPORT,
   279  	errno.ESOCKTNOSUPPORT: ESOCKTNOSUPPORT,
   280  	errno.EOPNOTSUPP:      EOPNOTSUPP,
   281  	errno.EPFNOSUPPORT:    EPFNOSUPPORT,
   282  	errno.EAFNOSUPPORT:    EAFNOSUPPORT,
   283  	errno.EADDRINUSE:      EADDRINUSE,
   284  	errno.EADDRNOTAVAIL:   EADDRNOTAVAIL,
   285  	errno.ENETDOWN:        ENETDOWN,
   286  	errno.ENETUNREACH:     ENETUNREACH,
   287  	errno.ENETRESET:       ENETRESET,
   288  	errno.ECONNABORTED:    ECONNABORTED,
   289  	errno.ECONNRESET:      ECONNRESET,
   290  	errno.ENOBUFS:         ENOBUFS,
   291  	errno.EISCONN:         EISCONN,
   292  	errno.ENOTCONN:        ENOTCONN,
   293  	errno.ESHUTDOWN:       ESHUTDOWN,
   294  	errno.ETOOMANYREFS:    ETOOMANYREFS,
   295  	errno.ETIMEDOUT:       ETIMEDOUT,
   296  	errno.ECONNREFUSED:    ECONNREFUSED,
   297  	errno.EHOSTDOWN:       EHOSTDOWN,
   298  	errno.EHOSTUNREACH:    EHOSTUNREACH,
   299  	errno.EALREADY:        EALREADY,
   300  	errno.EINPROGRESS:     EINPROGRESS,
   301  	errno.ESTALE:          ESTALE,
   302  	errno.EUCLEAN:         EUCLEAN,
   303  	errno.ENOTNAM:         ENOTNAM,
   304  	errno.ENAVAIL:         ENAVAIL,
   305  	errno.EISNAM:          EISNAM,
   306  	errno.EREMOTEIO:       EREMOTEIO,
   307  	errno.EDQUOT:          EDQUOT,
   308  	errno.ENOMEDIUM:       ENOMEDIUM,
   309  	errno.EMEDIUMTYPE:     EMEDIUMTYPE,
   310  	errno.ECANCELED:       ECANCELED,
   311  	errno.ENOKEY:          ENOKEY,
   312  	errno.EKEYEXPIRED:     EKEYEXPIRED,
   313  	errno.EKEYREVOKED:     EKEYREVOKED,
   314  	errno.EKEYREJECTED:    EKEYREJECTED,
   315  	errno.EOWNERDEAD:      EOWNERDEAD,
   316  	errno.ENOTRECOVERABLE: ENOTRECOVERABLE,
   317  	errno.ERFKILL:         ERFKILL,
   318  	errno.EHWPOISON:       EHWPOISON,
   319  }
   320  
   321  // ErrorFromErrno gets an error from the list and panics if an invalid entry is requested.
   322  func ErrorFromErrno(e errno.Errno) *errors.Error {
   323  	err := errorSlice[e]
   324  	// Done this way because a single comparison in benchmarks is 2-3 faster
   325  	// than something like ( if err == nil && err > 0 ).
   326  	if err != errNotValidError {
   327  		return err
   328  	}
   329  	panic(fmt.Sprintf("invalid error requested with errno: %d", e))
   330  }
   331  
   332  // Equals compars a linuxerr to a given error
   333  // TODO(b/34162363): Remove when syserror is removed.
   334  func Equals(e *errors.Error, err error) bool {
   335  	if err == nil {
   336  		return e == NOERROR || e == nil
   337  	}
   338  	if e == nil {
   339  		return err == NOERROR || err == unix.Errno(0)
   340  	}
   341  
   342  	switch err.(type) {
   343  	case *errors.Error:
   344  		return e == err
   345  	case unix.Errno, error:
   346  		return unix.Errno(e.Errno()) == err
   347  	}
   348  	return false
   349  }