summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorZach Koopmans <zkoopmans@google.com>2021-06-16 14:06:01 -0700
committergVisor bot <gvisor-bot@google.com>2021-06-16 14:08:52 -0700
commit63b4f6e296a8f131ec969a685f0e31663be58385 (patch)
tree2bf10bff66a654b1bca5d27598a142fc68ca9430
parent47149b7c4275ddd4404d86eddab6feab4f059ed3 (diff)
[syserror] Refactor linuxerr and error package.
Move Error struct to pkg/errors package for use in multiple places. Move linuxerr static definitions under pkg/errors/linuxerr. Add a lookup list for quick lookup of *errors.Error by errno. This is useful when converting syserror errors and unix.Errno/syscall.Errrno values to *errors.Error. Update benchmarks routines to include conversions. The below benchmarks show *errors.Error usage to be comparable to using unix.Errno. BenchmarkAssignUnix BenchmarkAssignUnix-32 787875022 1.284 ns/op BenchmarkAssignLinuxerr BenchmarkAssignLinuxerr-32 1000000000 1.209 ns/op BenchmarkAssignSyserror BenchmarkAssignSyserror-32 759269229 1.429 ns/op BenchmarkCompareUnix BenchmarkCompareUnix-32 1000000000 1.310 ns/op BenchmarkCompareLinuxerr BenchmarkCompareLinuxerr-32 1000000000 1.241 ns/op BenchmarkCompareSyserror BenchmarkCompareSyserror-32 147196165 8.248 ns/op BenchmarkSwitchUnix BenchmarkSwitchUnix-32 373233556 3.664 ns/op BenchmarkSwitchLinuxerr BenchmarkSwitchLinuxerr-32 476323929 3.294 ns/op BenchmarkSwitchSyserror BenchmarkSwitchSyserror-32 39293408 29.62 ns/op BenchmarkReturnUnix BenchmarkReturnUnix-32 1000000000 0.5042 ns/op BenchmarkReturnLinuxerr BenchmarkReturnLinuxerr-32 1000000000 0.8152 ns/op BenchmarkConvertUnixLinuxerr BenchmarkConvertUnixLinuxerr-32 739948875 1.547 ns/op BenchmarkConvertUnixLinuxerrZero BenchmarkConvertUnixLinuxerrZero-32 977733974 1.489 ns/op PiperOrigin-RevId: 379806801
-rw-r--r--pkg/abi/linux/BUILD1
-rw-r--r--pkg/abi/linux/errno/BUILD9
-rw-r--r--pkg/abi/linux/errno/errno.go (renamed from pkg/abi/linux/errors.go)14
-rw-r--r--pkg/errors/BUILD10
-rw-r--r--pkg/errors/errors.go40
-rw-r--r--pkg/errors/linuxerr/BUILD (renamed from pkg/linuxerr/BUILD)7
-rw-r--r--pkg/errors/linuxerr/linuxerr.go326
-rw-r--r--pkg/errors/linuxerr/linuxerr_test.go (renamed from pkg/linuxerr/linuxerr_test.go)101
-rw-r--r--pkg/linuxerr/linuxerr.go184
-rw-r--r--pkg/sentry/kernel/BUILD1
-rw-r--r--pkg/sentry/kernel/task_image.go4
-rw-r--r--pkg/sentry/loader/BUILD1
-rw-r--r--pkg/sentry/loader/loader.go3
-rw-r--r--pkg/sentry/socket/netlink/BUILD1
-rw-r--r--pkg/sentry/socket/netlink/socket.go3
-rw-r--r--pkg/sentry/socket/netstack/BUILD1
-rw-r--r--pkg/sentry/socket/netstack/netstack.go3
-rw-r--r--pkg/syserr/BUILD2
-rw-r--r--pkg/syserr/netstack.go56
-rw-r--r--pkg/syserr/syserr.go291
20 files changed, 676 insertions, 382 deletions
diff --git a/pkg/abi/linux/BUILD b/pkg/abi/linux/BUILD
index 38288bdb7..eb004a7f6 100644
--- a/pkg/abi/linux/BUILD
+++ b/pkg/abi/linux/BUILD
@@ -21,7 +21,6 @@ go_library(
"epoll.go",
"epoll_amd64.go",
"epoll_arm64.go",
- "errors.go",
"errqueue.go",
"eventfd.go",
"exec.go",
diff --git a/pkg/abi/linux/errno/BUILD b/pkg/abi/linux/errno/BUILD
new file mode 100644
index 000000000..d003342d5
--- /dev/null
+++ b/pkg/abi/linux/errno/BUILD
@@ -0,0 +1,9 @@
+load("//tools:defs.bzl", "go_library")
+
+package(licenses = ["notice"])
+
+go_library(
+ name = "errno",
+ srcs = ["errno.go"],
+ visibility = ["//visibility:public"],
+)
diff --git a/pkg/abi/linux/errors.go b/pkg/abi/linux/errno/errno.go
index b08b2687e..5a09c6605 100644
--- a/pkg/abi/linux/errors.go
+++ b/pkg/abi/linux/errno/errno.go
@@ -12,10 +12,11 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-package linux
+// Package errno holds errno codes for abi/linux.
+package errno
// Errno represents a Linux errno value.
-type Errno int
+type Errno uint32
// Errno values from include/uapi/asm-generic/errno-base.h.
const (
@@ -60,8 +61,8 @@ const (
ENOLCK
ENOSYS
ENOTEMPTY
- ELOOP //40
- _ // Skip for EWOULDBLOCK = EAGAIN
+ ELOOP // 40
+ _ // Skip for EWOULDBLOCK = EAGAIN.
ENOMSG //42
EIDRM
ECHRNG
@@ -78,13 +79,13 @@ const (
ENOANO
EBADRQC
EBADSLT
- _ // Skip for EDEADLOCK = EDEADLK
+ _ // Skip for EDEADLOCK = EDEADLK.
EBFONT
ENOSTR // 60
ENODATA
ETIME
ENOSR
- ENONET
+ _ // Skip for ENOENT = ENONET.
ENOPKG
EREMOTE
ENOLINK
@@ -160,4 +161,5 @@ const (
const (
EWOULDBLOCK = EAGAIN
EDEADLOCK = EDEADLK
+ ENONET = ENOENT
)
diff --git a/pkg/errors/BUILD b/pkg/errors/BUILD
new file mode 100644
index 000000000..36ea5da0c
--- /dev/null
+++ b/pkg/errors/BUILD
@@ -0,0 +1,10 @@
+load("//tools:defs.bzl", "go_library")
+
+package(licenses = ["notice"])
+
+go_library(
+ name = "errors",
+ srcs = ["errors.go"],
+ visibility = ["//:sandbox"],
+ deps = ["//pkg/abi/linux/errno"],
+)
diff --git a/pkg/errors/errors.go b/pkg/errors/errors.go
new file mode 100644
index 000000000..7984a770e
--- /dev/null
+++ b/pkg/errors/errors.go
@@ -0,0 +1,40 @@
+// Copyright 2021 The gVisor Authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Package errors holds the standardized error definition for gVisor.
+package errors
+
+import (
+ "gvisor.dev/gvisor/pkg/abi/linux/errno"
+)
+
+// Error represents a syscall errno with a descriptive message.
+type Error struct {
+ errno errno.Errno
+ message string
+}
+
+// New creates a new *Error.
+func New(err errno.Errno, message string) *Error {
+ return &Error{
+ errno: err,
+ message: message,
+ }
+}
+
+// Error implements error.Error.
+func (e *Error) Error() string { return e.message }
+
+// Errno returns the underlying errno.Errno value.
+func (e *Error) Errno() errno.Errno { return e.errno }
diff --git a/pkg/linuxerr/BUILD b/pkg/errors/linuxerr/BUILD
index c5abbd34f..8afc9688c 100644
--- a/pkg/linuxerr/BUILD
+++ b/pkg/errors/linuxerr/BUILD
@@ -6,7 +6,10 @@ go_library(
name = "linuxerr",
srcs = ["linuxerr.go"],
visibility = ["//visibility:public"],
- deps = ["//pkg/abi/linux"],
+ deps = [
+ "//pkg/abi/linux/errno",
+ "//pkg/errors",
+ ],
)
go_test(
@@ -14,6 +17,8 @@ go_test(
srcs = ["linuxerr_test.go"],
deps = [
":linuxerr",
+ "//pkg/abi/linux/errno",
+ "//pkg/errors",
"//pkg/syserror",
"@org_golang_x_sys//unix:go_default_library",
],
diff --git a/pkg/errors/linuxerr/linuxerr.go b/pkg/errors/linuxerr/linuxerr.go
new file mode 100644
index 000000000..23d9f9f75
--- /dev/null
+++ b/pkg/errors/linuxerr/linuxerr.go
@@ -0,0 +1,326 @@
+// Copyright 2021 The gVisor Authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License"),;
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Package linuxerr contains syscall error codes exported as an error interface
+// pointers. This allows for fast comparison and return operations comperable
+// to unix.Errno constants.
+package linuxerr
+
+import (
+ "fmt"
+
+ "gvisor.dev/gvisor/pkg/abi/linux/errno"
+ "gvisor.dev/gvisor/pkg/errors"
+)
+
+const maxErrno uint32 = errno.EHWPOISON + 1
+
+var (
+ EPERM = errors.New(errno.EPERM, "operation not permitted")
+ ENOENT = errors.New(errno.ENOENT, "no such file or directory")
+ ESRCH = errors.New(errno.ESRCH, "no such process")
+ EINTR = errors.New(errno.EINTR, "interrupted system call")
+ EIO = errors.New(errno.EIO, "I/O error")
+ ENXIO = errors.New(errno.ENXIO, "no such device or address")
+ E2BIG = errors.New(errno.E2BIG, "argument list too long")
+ ENOEXEC = errors.New(errno.ENOEXEC, "exec format error")
+ EBADF = errors.New(errno.EBADF, "bad file number")
+ ECHILD = errors.New(errno.ECHILD, "no child processes")
+ EAGAIN = errors.New(errno.EAGAIN, "try again")
+ ENOMEM = errors.New(errno.ENOMEM, "out of memory")
+ EACCES = errors.New(errno.EACCES, "permission denied")
+ EFAULT = errors.New(errno.EFAULT, "bad address")
+ ENOTBLK = errors.New(errno.ENOTBLK, "block device required")
+ EBUSY = errors.New(errno.EBUSY, "device or resource busy")
+ EEXIST = errors.New(errno.EEXIST, "file exists")
+ EXDEV = errors.New(errno.EXDEV, "cross-device link")
+ ENODEV = errors.New(errno.ENODEV, "no such device")
+ ENOTDIR = errors.New(errno.ENOTDIR, "not a directory")
+ EISDIR = errors.New(errno.EISDIR, "is a directory")
+ EINVAL = errors.New(errno.EINVAL, "invalid argument")
+ ENFILE = errors.New(errno.ENFILE, "file table overflow")
+ EMFILE = errors.New(errno.EMFILE, "too many open files")
+ ENOTTY = errors.New(errno.ENOTTY, "not a typewriter")
+ ETXTBSY = errors.New(errno.ETXTBSY, "text file busy")
+ EFBIG = errors.New(errno.EFBIG, "file too large")
+ ENOSPC = errors.New(errno.ENOSPC, "no space left on device")
+ ESPIPE = errors.New(errno.ESPIPE, "illegal seek")
+ EROFS = errors.New(errno.EROFS, "read-only file system")
+ EMLINK = errors.New(errno.EMLINK, "too many links")
+ EPIPE = errors.New(errno.EPIPE, "broken pipe")
+ EDOM = errors.New(errno.EDOM, "math argument out of domain of func")
+ ERANGE = errors.New(errno.ERANGE, "math result not representable")
+
+ // Errno values from include/uapi/asm-generic/errno.h.
+ EDEADLK = errors.New(errno.EDEADLK, "resource deadlock would occur")
+ ENAMETOOLONG = errors.New(errno.ENAMETOOLONG, "file name too long")
+ ENOLCK = errors.New(errno.ENOLCK, "no record locks available")
+ ENOSYS = errors.New(errno.ENOSYS, "invalid system call number")
+ ENOTEMPTY = errors.New(errno.ENOTEMPTY, "directory not empty")
+ ELOOP = errors.New(errno.ELOOP, "too many symbolic links encountered")
+ ENOMSG = errors.New(errno.ENOMSG, "no message of desired type")
+ EIDRM = errors.New(errno.EIDRM, "identifier removed")
+ ECHRNG = errors.New(errno.ECHRNG, "channel number out of range")
+ EL2NSYNC = errors.New(errno.EL2NSYNC, "level 2 not synchronized")
+ EL3HLT = errors.New(errno.EL3HLT, "level 3 halted")
+ EL3RST = errors.New(errno.EL3RST, "level 3 reset")
+ ELNRNG = errors.New(errno.ELNRNG, "link number out of range")
+ EUNATCH = errors.New(errno.EUNATCH, "protocol driver not attached")
+ ENOCSI = errors.New(errno.ENOCSI, "no CSI structure available")
+ EL2HLT = errors.New(errno.EL2HLT, "level 2 halted")
+ EBADE = errors.New(errno.EBADE, "invalid exchange")
+ EBADR = errors.New(errno.EBADR, "invalid request descriptor")
+ EXFULL = errors.New(errno.EXFULL, "exchange full")
+ ENOANO = errors.New(errno.ENOANO, "no anode")
+ EBADRQC = errors.New(errno.EBADRQC, "invalid request code")
+ EBADSLT = errors.New(errno.EBADSLT, "invalid slot")
+ EBFONT = errors.New(errno.EBFONT, "bad font file format")
+ ENOSTR = errors.New(errno.ENOSTR, "device not a stream")
+ ENODATA = errors.New(errno.ENODATA, "no data available")
+ ETIME = errors.New(errno.ETIME, "timer expired")
+ ENOSR = errors.New(errno.ENOSR, "out of streams resources")
+ ENOPKG = errors.New(errno.ENOPKG, "package not installed")
+ EREMOTE = errors.New(errno.EREMOTE, "object is remote")
+ ENOLINK = errors.New(errno.ENOLINK, "link has been severed")
+ EADV = errors.New(errno.EADV, "advertise error")
+ ESRMNT = errors.New(errno.ESRMNT, "srmount error")
+ ECOMM = errors.New(errno.ECOMM, "communication error on send")
+ EPROTO = errors.New(errno.EPROTO, "protocol error")
+ EMULTIHOP = errors.New(errno.EMULTIHOP, "multihop attempted")
+ EDOTDOT = errors.New(errno.EDOTDOT, "RFS specific error")
+ EBADMSG = errors.New(errno.EBADMSG, "not a data message")
+ EOVERFLOW = errors.New(errno.EOVERFLOW, "value too large for defined data type")
+ ENOTUNIQ = errors.New(errno.ENOTUNIQ, "name not unique on network")
+ EBADFD = errors.New(errno.EBADFD, "file descriptor in bad state")
+ EREMCHG = errors.New(errno.EREMCHG, "remote address changed")
+ ELIBACC = errors.New(errno.ELIBACC, "can not access a needed shared library")
+ ELIBBAD = errors.New(errno.ELIBBAD, "accessing a corrupted shared library")
+ ELIBSCN = errors.New(errno.ELIBSCN, ".lib section in a.out corrupted")
+ ELIBMAX = errors.New(errno.ELIBMAX, "attempting to link in too many shared libraries")
+ ELIBEXEC = errors.New(errno.ELIBEXEC, "cannot exec a shared library directly")
+ EILSEQ = errors.New(errno.EILSEQ, "illegal byte sequence")
+ ERESTART = errors.New(errno.ERESTART, "interrupted system call should be restarted")
+ ESTRPIPE = errors.New(errno.ESTRPIPE, "streams pipe error")
+ EUSERS = errors.New(errno.EUSERS, "too many users")
+ ENOTSOCK = errors.New(errno.ENOTSOCK, "socket operation on non-socket")
+ EDESTADDRREQ = errors.New(errno.EDESTADDRREQ, "destination address required")
+ EMSGSIZE = errors.New(errno.EMSGSIZE, "message too long")
+ EPROTOTYPE = errors.New(errno.EPROTOTYPE, "protocol wrong type for socket")
+ ENOPROTOOPT = errors.New(errno.ENOPROTOOPT, "protocol not available")
+ EPROTONOSUPPORT = errors.New(errno.EPROTONOSUPPORT, "protocol not supported")
+ ESOCKTNOSUPPORT = errors.New(errno.ESOCKTNOSUPPORT, "socket type not supported")
+ EOPNOTSUPP = errors.New(errno.EOPNOTSUPP, "operation not supported on transport endpoint")
+ EPFNOSUPPORT = errors.New(errno.EPFNOSUPPORT, "protocol family not supported")
+ EAFNOSUPPORT = errors.New(errno.EAFNOSUPPORT, "address family not supported by protocol")
+ EADDRINUSE = errors.New(errno.EADDRINUSE, "address already in use")
+ EADDRNOTAVAIL = errors.New(errno.EADDRNOTAVAIL, "cannot assign requested address")
+ ENETDOWN = errors.New(errno.ENETDOWN, "network is down")
+ ENETUNREACH = errors.New(errno.ENETUNREACH, "network is unreachable")
+ ENETRESET = errors.New(errno.ENETRESET, "network dropped connection because of reset")
+ ECONNABORTED = errors.New(errno.ECONNABORTED, "software caused connection abort")
+ ECONNRESET = errors.New(errno.ECONNRESET, "connection reset by peer")
+ ENOBUFS = errors.New(errno.ENOBUFS, "no buffer space available")
+ EISCONN = errors.New(errno.EISCONN, "transport endpoint is already connected")
+ ENOTCONN = errors.New(errno.ENOTCONN, "transport endpoint is not connected")
+ ESHUTDOWN = errors.New(errno.ESHUTDOWN, "cannot send after transport endpoint shutdown")
+ ETOOMANYREFS = errors.New(errno.ETOOMANYREFS, "too many references: cannot splice")
+ ETIMEDOUT = errors.New(errno.ETIMEDOUT, "connection timed out")
+ ECONNREFUSED = errors.New(errno.ECONNREFUSED, "connection refused")
+ EHOSTDOWN = errors.New(errno.EHOSTDOWN, "host is down")
+ EHOSTUNREACH = errors.New(errno.EHOSTUNREACH, "no route to host")
+ EALREADY = errors.New(errno.EALREADY, "operation already in progress")
+ EINPROGRESS = errors.New(errno.EINPROGRESS, "operation now in progress")
+ ESTALE = errors.New(errno.ESTALE, "stale file handle")
+ EUCLEAN = errors.New(errno.EUCLEAN, "structure needs cleaning")
+ ENOTNAM = errors.New(errno.ENOTNAM, "not a XENIX named type file")
+ ENAVAIL = errors.New(errno.ENAVAIL, "no XENIX semaphores available")
+ EISNAM = errors.New(errno.EISNAM, "is a named type file")
+ EREMOTEIO = errors.New(errno.EREMOTEIO, "remote I/O error")
+ EDQUOT = errors.New(errno.EDQUOT, "quota exceeded")
+ ENOMEDIUM = errors.New(errno.ENOMEDIUM, "no medium found")
+ EMEDIUMTYPE = errors.New(errno.EMEDIUMTYPE, "wrong medium type")
+ ECANCELED = errors.New(errno.ECANCELED, "operation Canceled")
+ ENOKEY = errors.New(errno.ENOKEY, "required key not available")
+ EKEYEXPIRED = errors.New(errno.EKEYEXPIRED, "key has expired")
+ EKEYREVOKED = errors.New(errno.EKEYREVOKED, "key has been revoked")
+ EKEYREJECTED = errors.New(errno.EKEYREJECTED, "key was rejected by service")
+ EOWNERDEAD = errors.New(errno.EOWNERDEAD, "owner died")
+ ENOTRECOVERABLE = errors.New(errno.ENOTRECOVERABLE, "state not recoverable")
+ ERFKILL = errors.New(errno.ERFKILL, "operation not possible due to RF-kill")
+ EHWPOISON = errors.New(errno.EHWPOISON, "memory page has hardware error")
+
+ // Errors equivalent to other errors.
+ EWOULDBLOCK = EAGAIN
+ EDEADLOCK = EDEADLK
+ ENONET = ENOENT
+)
+
+// A nil *errors.Error denotes no error and is placed at the 0 index of
+// errorSlice. Thus, any other empty index should not be nil or a valid error.
+// This marks that index as an invalid error so any comparison to nil or a
+// valid linuxerr fails.
+var errNotValidError = errors.New(errno.Errno(maxErrno), "not a valid error")
+
+// The following errorSlice holds errors by errno for fast translation between
+// errnos (especially uint32(sycall.Errno)) and *Error.
+var errorSlice = []*errors.Error{
+ // Errno values from include/uapi/asm-generic/errno-base.h.
+ errno.NOERRNO: nil,
+ errno.EPERM: EPERM,
+ errno.ENOENT: ENOENT,
+ errno.ESRCH: ESRCH,
+ errno.EINTR: EINTR,
+ errno.EIO: EIO,
+ errno.ENXIO: ENXIO,
+ errno.E2BIG: E2BIG,
+ errno.ENOEXEC: ENOEXEC,
+ errno.EBADF: EBADF,
+ errno.ECHILD: ECHILD,
+ errno.EAGAIN: EAGAIN,
+ errno.ENOMEM: ENOMEM,
+ errno.EACCES: EACCES,
+ errno.EFAULT: EFAULT,
+ errno.ENOTBLK: ENOTBLK,
+ errno.EBUSY: EBUSY,
+ errno.EEXIST: EEXIST,
+ errno.EXDEV: EXDEV,
+ errno.ENODEV: ENODEV,
+ errno.ENOTDIR: ENOTDIR,
+ errno.EISDIR: EISDIR,
+ errno.EINVAL: EINVAL,
+ errno.ENFILE: ENFILE,
+ errno.EMFILE: EMFILE,
+ errno.ENOTTY: ENOTTY,
+ errno.ETXTBSY: ETXTBSY,
+ errno.EFBIG: EFBIG,
+ errno.ENOSPC: ENOSPC,
+ errno.ESPIPE: ESPIPE,
+ errno.EROFS: EROFS,
+ errno.EMLINK: EMLINK,
+ errno.EPIPE: EPIPE,
+ errno.EDOM: EDOM,
+ errno.ERANGE: ERANGE,
+
+ // Errno values from include/uapi/asm-generic/errno.h.
+ errno.EDEADLK: EDEADLK,
+ errno.ENAMETOOLONG: ENAMETOOLONG,
+ errno.ENOLCK: ENOLCK,
+ errno.ENOSYS: ENOSYS,
+ errno.ENOTEMPTY: ENOTEMPTY,
+ errno.ELOOP: ELOOP,
+ errno.ELOOP + 1: errNotValidError, // No valid errno between ELOOP and ENOMSG.
+ errno.ENOMSG: ENOMSG,
+ errno.EIDRM: EIDRM,
+ errno.ECHRNG: ECHRNG,
+ errno.EL2NSYNC: EL2NSYNC,
+ errno.EL3HLT: EL3HLT,
+ errno.EL3RST: EL3RST,
+ errno.ELNRNG: ELNRNG,
+ errno.EUNATCH: EUNATCH,
+ errno.ENOCSI: ENOCSI,
+ errno.EL2HLT: EL2HLT,
+ errno.EBADE: EBADE,
+ errno.EBADR: EBADR,
+ errno.EXFULL: EXFULL,
+ errno.ENOANO: ENOANO,
+ errno.EBADRQC: EBADRQC,
+ errno.EBADSLT: EBADSLT,
+ errno.EBADSLT + 1: errNotValidError, // No valid errno between EBADSLT and ENOPKG.
+ errno.EBFONT: EBFONT,
+ errno.ENOSTR: ENOSTR,
+ errno.ENODATA: ENODATA,
+ errno.ETIME: ETIME,
+ errno.ENOSR: ENOSR,
+ errno.ENOSR + 1: errNotValidError, // No valid errno betweeen ENOSR and ENOPKG.
+ errno.ENOPKG: ENOPKG,
+ errno.EREMOTE: EREMOTE,
+ errno.ENOLINK: ENOLINK,
+ errno.EADV: EADV,
+ errno.ESRMNT: ESRMNT,
+ errno.ECOMM: ECOMM,
+ errno.EPROTO: EPROTO,
+ errno.EMULTIHOP: EMULTIHOP,
+ errno.EDOTDOT: EDOTDOT,
+ errno.EBADMSG: EBADMSG,
+ errno.EOVERFLOW: EOVERFLOW,
+ errno.ENOTUNIQ: ENOTUNIQ,
+ errno.EBADFD: EBADFD,
+ errno.EREMCHG: EREMCHG,
+ errno.ELIBACC: ELIBACC,
+ errno.ELIBBAD: ELIBBAD,
+ errno.ELIBSCN: ELIBSCN,
+ errno.ELIBMAX: ELIBMAX,
+ errno.ELIBEXEC: ELIBEXEC,
+ errno.EILSEQ: EILSEQ,
+ errno.ERESTART: ERESTART,
+ errno.ESTRPIPE: ESTRPIPE,
+ errno.EUSERS: EUSERS,
+ errno.ENOTSOCK: ENOTSOCK,
+ errno.EDESTADDRREQ: EDESTADDRREQ,
+ errno.EMSGSIZE: EMSGSIZE,
+ errno.EPROTOTYPE: EPROTOTYPE,
+ errno.ENOPROTOOPT: ENOPROTOOPT,
+ errno.EPROTONOSUPPORT: EPROTONOSUPPORT,
+ errno.ESOCKTNOSUPPORT: ESOCKTNOSUPPORT,
+ errno.EOPNOTSUPP: EOPNOTSUPP,
+ errno.EPFNOSUPPORT: EPFNOSUPPORT,
+ errno.EAFNOSUPPORT: EAFNOSUPPORT,
+ errno.EADDRINUSE: EADDRINUSE,
+ errno.EADDRNOTAVAIL: EADDRNOTAVAIL,
+ errno.ENETDOWN: ENETDOWN,
+ errno.ENETUNREACH: ENETUNREACH,
+ errno.ENETRESET: ENETRESET,
+ errno.ECONNABORTED: ECONNABORTED,
+ errno.ECONNRESET: ECONNRESET,
+ errno.ENOBUFS: ENOBUFS,
+ errno.EISCONN: EISCONN,
+ errno.ENOTCONN: ENOTCONN,
+ errno.ESHUTDOWN: ESHUTDOWN,
+ errno.ETOOMANYREFS: ETOOMANYREFS,
+ errno.ETIMEDOUT: ETIMEDOUT,
+ errno.ECONNREFUSED: ECONNREFUSED,
+ errno.EHOSTDOWN: EHOSTDOWN,
+ errno.EHOSTUNREACH: EHOSTUNREACH,
+ errno.EALREADY: EALREADY,
+ errno.EINPROGRESS: EINPROGRESS,
+ errno.ESTALE: ESTALE,
+ errno.EUCLEAN: EUCLEAN,
+ errno.ENOTNAM: ENOTNAM,
+ errno.ENAVAIL: ENAVAIL,
+ errno.EISNAM: EISNAM,
+ errno.EREMOTEIO: EREMOTEIO,
+ errno.EDQUOT: EDQUOT,
+ errno.ENOMEDIUM: ENOMEDIUM,
+ errno.EMEDIUMTYPE: EMEDIUMTYPE,
+ errno.ECANCELED: ECANCELED,
+ errno.ENOKEY: ENOKEY,
+ errno.EKEYEXPIRED: EKEYEXPIRED,
+ errno.EKEYREVOKED: EKEYREVOKED,
+ errno.EKEYREJECTED: EKEYREJECTED,
+ errno.EOWNERDEAD: EOWNERDEAD,
+ errno.ENOTRECOVERABLE: ENOTRECOVERABLE,
+ errno.ERFKILL: ERFKILL,
+ errno.EHWPOISON: EHWPOISON,
+}
+
+// ErrorFromErrno gets an error from the list and panics if an invalid entry is requested.
+func ErrorFromErrno(e errno.Errno) *errors.Error {
+ err := errorSlice[e]
+ // Done this way because a single comparison in benchmarks is 2-3 faster
+ // than something like ( if err == nil && err > 0 ).
+ if err != errNotValidError {
+ return err
+ }
+ panic(fmt.Sprintf("invalid error requested with errno: %d", e))
+}
diff --git a/pkg/linuxerr/linuxerr_test.go b/pkg/errors/linuxerr/linuxerr_test.go
index d34937e93..a81dd9560 100644
--- a/pkg/linuxerr/linuxerr_test.go
+++ b/pkg/errors/linuxerr/linuxerr_test.go
@@ -16,34 +16,37 @@ package syserror_test
import (
"errors"
+ "syscall"
"testing"
"golang.org/x/sys/unix"
- "gvisor.dev/gvisor/pkg/linuxerr"
+ "gvisor.dev/gvisor/pkg/abi/linux/errno"
+ gErrors "gvisor.dev/gvisor/pkg/errors"
+ "gvisor.dev/gvisor/pkg/errors/linuxerr"
"gvisor.dev/gvisor/pkg/syserror"
)
var globalError error
-func BenchmarkAssignErrno(b *testing.B) {
+func BenchmarkAssignUnix(b *testing.B) {
for i := b.N; i > 0; i-- {
globalError = unix.EINVAL
}
}
-func BenchmarkLinuxerrAssignError(b *testing.B) {
+func BenchmarkAssignLinuxerr(b *testing.B) {
for i := b.N; i > 0; i-- {
globalError = linuxerr.EINVAL
}
}
-func BenchmarkAssignSyserrorError(b *testing.B) {
+func BenchmarkAssignSyserror(b *testing.B) {
for i := b.N; i > 0; i-- {
globalError = syserror.EINVAL
}
}
-func BenchmarkCompareErrno(b *testing.B) {
+func BenchmarkCompareUnix(b *testing.B) {
globalError = unix.EAGAIN
j := 0
for i := b.N; i > 0; i-- {
@@ -53,7 +56,7 @@ func BenchmarkCompareErrno(b *testing.B) {
}
}
-func BenchmarkCompareLinuxerrError(b *testing.B) {
+func BenchmarkCompareLinuxerr(b *testing.B) {
globalError = linuxerr.E2BIG
j := 0
for i := b.N; i > 0; i-- {
@@ -63,7 +66,7 @@ func BenchmarkCompareLinuxerrError(b *testing.B) {
}
}
-func BenchmarkCompareSyserrorError(b *testing.B) {
+func BenchmarkCompareSyserror(b *testing.B) {
globalError = syserror.EAGAIN
j := 0
for i := b.N; i > 0; i-- {
@@ -73,7 +76,7 @@ func BenchmarkCompareSyserrorError(b *testing.B) {
}
}
-func BenchmarkSwitchErrno(b *testing.B) {
+func BenchmarkSwitchUnix(b *testing.B) {
globalError = unix.EPERM
j := 0
for i := b.N; i > 0; i-- {
@@ -88,7 +91,7 @@ func BenchmarkSwitchErrno(b *testing.B) {
}
}
-func BenchmarkSwitchLinuxerrError(b *testing.B) {
+func BenchmarkSwitchLinuxerr(b *testing.B) {
globalError = linuxerr.EPERM
j := 0
for i := b.N; i > 0; i-- {
@@ -103,7 +106,7 @@ func BenchmarkSwitchLinuxerrError(b *testing.B) {
}
}
-func BenchmarkSwitchSyserrorError(b *testing.B) {
+func BenchmarkSwitchSyserror(b *testing.B) {
globalError = syserror.EPERM
j := 0
for i := b.N; i > 0; i-- {
@@ -118,6 +121,52 @@ func BenchmarkSwitchSyserrorError(b *testing.B) {
}
}
+func BenchmarkReturnUnix(b *testing.B) {
+ var localError error
+ f := func() error {
+ return unix.EINVAL
+ }
+ for i := b.N; i > 0; i-- {
+ localError = f()
+ }
+ if localError != nil {
+ return
+ }
+}
+
+func BenchmarkReturnLinuxerr(b *testing.B) {
+ var localError error
+ f := func() error {
+ return linuxerr.EINVAL
+ }
+ for i := b.N; i > 0; i-- {
+ localError = f()
+ }
+ if localError != nil {
+ return
+ }
+}
+
+func BenchmarkConvertUnixLinuxerr(b *testing.B) {
+ var localError error
+ for i := b.N; i > 0; i-- {
+ localError = linuxerr.ErrorFromErrno(errno.Errno(unix.EINVAL))
+ }
+ if localError != nil {
+ return
+ }
+}
+
+func BenchmarkConvertUnixLinuxerrZero(b *testing.B) {
+ var localError error
+ for i := b.N; i > 0; i-- {
+ localError = linuxerr.ErrorFromErrno(errno.Errno(0))
+ }
+ if localError != nil {
+ return
+ }
+}
+
type translationTestTable struct {
fn string
errIn error
@@ -162,3 +211,35 @@ func TestErrorTranslation(t *testing.T) {
}
}
}
+
+func TestSyscallErrnoToErrors(t *testing.T) {
+ for _, tc := range []struct {
+ errno syscall.Errno
+ err *gErrors.Error
+ }{
+ {errno: syscall.EACCES, err: linuxerr.EACCES},
+ {errno: syscall.EAGAIN, err: linuxerr.EAGAIN},
+ {errno: syscall.EBADF, err: linuxerr.EBADF},
+ {errno: syscall.EBUSY, err: linuxerr.EBUSY},
+ {errno: syscall.EDOM, err: linuxerr.EDOM},
+ {errno: syscall.EEXIST, err: linuxerr.EEXIST},
+ {errno: syscall.EFAULT, err: linuxerr.EFAULT},
+ {errno: syscall.EFBIG, err: linuxerr.EFBIG},
+ {errno: syscall.EINTR, err: linuxerr.EINTR},
+ {errno: syscall.EINVAL, err: linuxerr.EINVAL},
+ {errno: syscall.EIO, err: linuxerr.EIO},
+ {errno: syscall.ENOTDIR, err: linuxerr.ENOTDIR},
+ {errno: syscall.ENOTTY, err: linuxerr.ENOTTY},
+ {errno: syscall.EPERM, err: linuxerr.EPERM},
+ {errno: syscall.EPIPE, err: linuxerr.EPIPE},
+ {errno: syscall.ESPIPE, err: linuxerr.ESPIPE},
+ {errno: syscall.EWOULDBLOCK, err: linuxerr.EAGAIN},
+ } {
+ t.Run(tc.errno.Error(), func(t *testing.T) {
+ e := linuxerr.ErrorFromErrno(errno.Errno(tc.errno))
+ if e != tc.err {
+ t.Fatalf("Mismatch errors: want: %+v (%d) got: %+v %d", tc.err, tc.err.Errno(), e, e.Errno())
+ }
+ })
+ }
+}
diff --git a/pkg/linuxerr/linuxerr.go b/pkg/linuxerr/linuxerr.go
deleted file mode 100644
index f45caaadf..000000000
--- a/pkg/linuxerr/linuxerr.go
+++ /dev/null
@@ -1,184 +0,0 @@
-// Copyright 2021 The gVisor Authors.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-// Package linuxerr contains syscall error codes exported as an error interface
-// pointers. This allows for fast comparison and return operations comperable
-// to unix.Errno constants.
-package linuxerr
-
-import (
- "gvisor.dev/gvisor/pkg/abi/linux"
-)
-
-// Error represents a syscall errno with a descriptive message.
-type Error struct {
- errno linux.Errno
- message string
-}
-
-func new(err linux.Errno, message string) *Error {
- return &Error{
- errno: err,
- message: message,
- }
-}
-
-// Error implements error.Error.
-func (e *Error) Error() string { return e.message }
-
-// Errno returns the underlying linux.Errno value.
-func (e *Error) Errno() linux.Errno { return e.errno }
-
-// The following varables have the same meaning as their errno equivalent.
-
-// Errno values from include/uapi/asm-generic/errno-base.h.
-var (
- EPERM = new(linux.EPERM, "operation not permitted")
- ENOENT = new(linux.ENOENT, "no such file or directory")
- ESRCH = new(linux.ESRCH, "no such process")
- EINTR = new(linux.EINTR, "interrupted system call")
- EIO = new(linux.EIO, "I/O error")
- ENXIO = new(linux.ENXIO, "no such device or address")
- E2BIG = new(linux.E2BIG, "argument list too long")
- ENOEXEC = new(linux.ENOEXEC, "exec format error")
- EBADF = new(linux.EBADF, "bad file number")
- ECHILD = new(linux.ECHILD, "no child processes")
- EAGAIN = new(linux.EAGAIN, "try again")
- ENOMEM = new(linux.ENOMEM, "out of memory")
- EACCES = new(linux.EACCES, "permission denied")
- EFAULT = new(linux.EFAULT, "bad address")
- ENOTBLK = new(linux.ENOTBLK, "block device required")
- EBUSY = new(linux.EBUSY, "device or resource busy")
- EEXIST = new(linux.EEXIST, "file exists")
- EXDEV = new(linux.EXDEV, "cross-device link")
- ENODEV = new(linux.ENODEV, "no such device")
- ENOTDIR = new(linux.ENOTDIR, "not a directory")
- EISDIR = new(linux.EISDIR, "is a directory")
- EINVAL = new(linux.EINVAL, "invalid argument")
- ENFILE = new(linux.ENFILE, "file table overflow")
- EMFILE = new(linux.EMFILE, "too many open files")
- ENOTTY = new(linux.ENOTTY, "not a typewriter")
- ETXTBSY = new(linux.ETXTBSY, "text file busy")
- EFBIG = new(linux.EFBIG, "file too large")
- ENOSPC = new(linux.ENOSPC, "no space left on device")
- ESPIPE = new(linux.ESPIPE, "illegal seek")
- EROFS = new(linux.EROFS, "read-only file system")
- EMLINK = new(linux.EMLINK, "too many links")
- EPIPE = new(linux.EPIPE, "broken pipe")
- EDOM = new(linux.EDOM, "math argument out of domain of func")
- ERANGE = new(linux.ERANGE, "math result not representable")
-)
-
-// Errno values from include/uapi/asm-generic/errno.h.
-var (
- EDEADLK = new(linux.EDEADLK, "resource deadlock would occur")
- ENAMETOOLONG = new(linux.ENAMETOOLONG, "file name too long")
- ENOLCK = new(linux.ENOLCK, "no record locks available")
- ENOSYS = new(linux.ENOSYS, "invalid system call number")
- ENOTEMPTY = new(linux.ENOTEMPTY, "directory not empty")
- ELOOP = new(linux.ELOOP, "too many symbolic links encountered")
- EWOULDBLOCK = new(linux.EWOULDBLOCK, "operation would block")
- ENOMSG = new(linux.ENOMSG, "no message of desired type")
- EIDRM = new(linux.EIDRM, "identifier removed")
- ECHRNG = new(linux.ECHRNG, "channel number out of range")
- EL2NSYNC = new(linux.EL2NSYNC, "level 2 not synchronized")
- EL3HLT = new(linux.EL3HLT, "level 3 halted")
- EL3RST = new(linux.EL3RST, "level 3 reset")
- ELNRNG = new(linux.ELNRNG, "link number out of range")
- EUNATCH = new(linux.EUNATCH, "protocol driver not attached")
- ENOCSI = new(linux.ENOCSI, "no CSI structure available")
- EL2HLT = new(linux.EL2HLT, "level 2 halted")
- EBADE = new(linux.EBADE, "invalid exchange")
- EBADR = new(linux.EBADR, "invalid request descriptor")
- EXFULL = new(linux.EXFULL, "exchange full")
- ENOANO = new(linux.ENOANO, "no anode")
- EBADRQC = new(linux.EBADRQC, "invalid request code")
- EBADSLT = new(linux.EBADSLT, "invalid slot")
- EDEADLOCK = new(linux.EDEADLOCK, EDEADLK.message)
- EBFONT = new(linux.EBFONT, "bad font file format")
- ENOSTR = new(linux.ENOSTR, "device not a stream")
- ENODATA = new(linux.ENODATA, "no data available")
- ETIME = new(linux.ETIME, "timer expired")
- ENOSR = new(linux.ENOSR, "out of streams resources")
- ENONET = new(linux.ENOENT, "machine is not on the network")
- ENOPKG = new(linux.ENOPKG, "package not installed")
- EREMOTE = new(linux.EREMOTE, "object is remote")
- ENOLINK = new(linux.ENOLINK, "link has been severed")
- EADV = new(linux.EADV, "advertise error")
- ESRMNT = new(linux.ESRMNT, "srmount error")
- ECOMM = new(linux.ECOMM, "communication error on send")
- EPROTO = new(linux.EPROTO, "protocol error")
- EMULTIHOP = new(linux.EMULTIHOP, "multihop attempted")
- EDOTDOT = new(linux.EDOTDOT, "RFS specific error")
- EBADMSG = new(linux.EBADMSG, "not a data message")
- EOVERFLOW = new(linux.EOVERFLOW, "value too large for defined data type")
- ENOTUNIQ = new(linux.ENOTUNIQ, "name not unique on network")
- EBADFD = new(linux.EBADFD, "file descriptor in bad state")
- EREMCHG = new(linux.EREMCHG, "remote address changed")
- ELIBACC = new(linux.ELIBACC, "can not access a needed shared library")
- ELIBBAD = new(linux.ELIBBAD, "accessing a corrupted shared library")
- ELIBSCN = new(linux.ELIBSCN, ".lib section in a.out corrupted")
- ELIBMAX = new(linux.ELIBMAX, "attempting to link in too many shared libraries")
- ELIBEXEC = new(linux.ELIBEXEC, "cannot exec a shared library directly")
- EILSEQ = new(linux.EILSEQ, "illegal byte sequence")
- ERESTART = new(linux.ERESTART, "interrupted system call should be restarted")
- ESTRPIPE = new(linux.ESTRPIPE, "streams pipe error")
- EUSERS = new(linux.EUSERS, "too many users")
- ENOTSOCK = new(linux.ENOTSOCK, "socket operation on non-socket")
- EDESTADDRREQ = new(linux.EDESTADDRREQ, "destination address required")
- EMSGSIZE = new(linux.EMSGSIZE, "message too long")
- EPROTOTYPE = new(linux.EPROTOTYPE, "protocol wrong type for socket")
- ENOPROTOOPT = new(linux.ENOPROTOOPT, "protocol not available")
- EPROTONOSUPPORT = new(linux.EPROTONOSUPPORT, "protocol not supported")
- ESOCKTNOSUPPORT = new(linux.ESOCKTNOSUPPORT, "socket type not supported")
- EOPNOTSUPP = new(linux.EOPNOTSUPP, "operation not supported on transport endpoint")
- EPFNOSUPPORT = new(linux.EPFNOSUPPORT, "protocol family not supported")
- EAFNOSUPPORT = new(linux.EAFNOSUPPORT, "address family not supported by protocol")
- EADDRINUSE = new(linux.EADDRINUSE, "address already in use")
- EADDRNOTAVAIL = new(linux.EADDRNOTAVAIL, "cannot assign requested address")
- ENETDOWN = new(linux.ENETDOWN, "network is down")
- ENETUNREACH = new(linux.ENETUNREACH, "network is unreachable")
- ENETRESET = new(linux.ENETRESET, "network dropped connection because of reset")
- ECONNABORTED = new(linux.ECONNABORTED, "software caused connection abort")
- ECONNRESET = new(linux.ECONNRESET, "connection reset by peer")
- ENOBUFS = new(linux.ENOBUFS, "no buffer space available")
- EISCONN = new(linux.EISCONN, "transport endpoint is already connected")
- ENOTCONN = new(linux.ENOTCONN, "transport endpoint is not connected")
- ESHUTDOWN = new(linux.ESHUTDOWN, "cannot send after transport endpoint shutdown")
- ETOOMANYREFS = new(linux.ETOOMANYREFS, "too many references: cannot splice")
- ETIMEDOUT = new(linux.ETIMEDOUT, "connection timed out")
- ECONNREFUSED = new(linux.ECONNREFUSED, "connection refused")
- EHOSTDOWN = new(linux.EHOSTDOWN, "host is down")
- EHOSTUNREACH = new(linux.EHOSTUNREACH, "no route to host")
- EALREADY = new(linux.EALREADY, "operation already in progress")
- EINPROGRESS = new(linux.EINPROGRESS, "operation now in progress")
- ESTALE = new(linux.ESTALE, "stale file handle")
- EUCLEAN = new(linux.EUCLEAN, "structure needs cleaning")
- ENOTNAM = new(linux.ENOTNAM, "not a XENIX named type file")
- ENAVAIL = new(linux.ENAVAIL, "no XENIX semaphores available")
- EISNAM = new(linux.EISNAM, "is a named type file")
- EREMOTEIO = new(linux.EREMOTEIO, "remote I/O error")
- EDQUOT = new(linux.EDQUOT, "quota exceeded")
- ENOMEDIUM = new(linux.ENOMEDIUM, "no medium found")
- EMEDIUMTYPE = new(linux.EMEDIUMTYPE, "wrong medium type")
- ECANCELED = new(linux.ECANCELED, "operation Canceled")
- ENOKEY = new(linux.ENOKEY, "required key not available")
- EKEYEXPIRED = new(linux.EKEYEXPIRED, "key has expired")
- EKEYREVOKED = new(linux.EKEYREVOKED, "key has been revoked")
- EKEYREJECTED = new(linux.EKEYREJECTED, "key was rejected by service")
- EOWNERDEAD = new(linux.EOWNERDEAD, "owner died")
- ENOTRECOVERABLE = new(linux.ENOTRECOVERABLE, "state not recoverable")
- ERFKILL = new(linux.ERFKILL, "operation not possible due to RF-kill")
- EHWPOISON = new(linux.EHWPOISON, "memory page has hardware error")
-)
diff --git a/pkg/sentry/kernel/BUILD b/pkg/sentry/kernel/BUILD
index 188c0ebff..a82d641da 100644
--- a/pkg/sentry/kernel/BUILD
+++ b/pkg/sentry/kernel/BUILD
@@ -218,6 +218,7 @@ go_library(
":uncaught_signal_go_proto",
"//pkg/abi",
"//pkg/abi/linux",
+ "//pkg/abi/linux/errno",
"//pkg/amutex",
"//pkg/bits",
"//pkg/bpf",
diff --git a/pkg/sentry/kernel/task_image.go b/pkg/sentry/kernel/task_image.go
index bd5543d4e..c132c27ef 100644
--- a/pkg/sentry/kernel/task_image.go
+++ b/pkg/sentry/kernel/task_image.go
@@ -17,7 +17,7 @@ package kernel
import (
"fmt"
- "gvisor.dev/gvisor/pkg/abi/linux"
+ "gvisor.dev/gvisor/pkg/abi/linux/errno"
"gvisor.dev/gvisor/pkg/context"
"gvisor.dev/gvisor/pkg/hostarch"
"gvisor.dev/gvisor/pkg/sentry/arch"
@@ -27,7 +27,7 @@ import (
"gvisor.dev/gvisor/pkg/syserr"
)
-var errNoSyscalls = syserr.New("no syscall table found", linux.ENOEXEC)
+var errNoSyscalls = syserr.New("no syscall table found", errno.ENOEXEC)
// Auxmap contains miscellaneous data for the task.
type Auxmap map[string]interface{}
diff --git a/pkg/sentry/loader/BUILD b/pkg/sentry/loader/BUILD
index 4c65215fa..80f862628 100644
--- a/pkg/sentry/loader/BUILD
+++ b/pkg/sentry/loader/BUILD
@@ -17,6 +17,7 @@ go_library(
deps = [
"//pkg/abi",
"//pkg/abi/linux",
+ "//pkg/abi/linux/errno",
"//pkg/context",
"//pkg/cpuid",
"//pkg/hostarch",
diff --git a/pkg/sentry/loader/loader.go b/pkg/sentry/loader/loader.go
index 47e3775a3..8240173ae 100644
--- a/pkg/sentry/loader/loader.go
+++ b/pkg/sentry/loader/loader.go
@@ -23,6 +23,7 @@ import (
"gvisor.dev/gvisor/pkg/abi"
"gvisor.dev/gvisor/pkg/abi/linux"
+ "gvisor.dev/gvisor/pkg/abi/linux/errno"
"gvisor.dev/gvisor/pkg/context"
"gvisor.dev/gvisor/pkg/cpuid"
"gvisor.dev/gvisor/pkg/hostarch"
@@ -237,7 +238,7 @@ func Load(ctx context.Context, args LoadArgs, extraAuxv []arch.AuxEntry, vdso *V
// loaded.end is available for its use.
e, ok := loaded.end.RoundUp()
if !ok {
- return 0, nil, "", syserr.NewDynamic(fmt.Sprintf("brk overflows: %#x", loaded.end), linux.ENOEXEC)
+ return 0, nil, "", syserr.NewDynamic(fmt.Sprintf("brk overflows: %#x", loaded.end), errno.ENOEXEC)
}
args.MemoryManager.BrkSetup(ctx, e)
diff --git a/pkg/sentry/socket/netlink/BUILD b/pkg/sentry/socket/netlink/BUILD
index 64cd263da..6b83698ad 100644
--- a/pkg/sentry/socket/netlink/BUILD
+++ b/pkg/sentry/socket/netlink/BUILD
@@ -14,6 +14,7 @@ go_library(
visibility = ["//pkg/sentry:internal"],
deps = [
"//pkg/abi/linux",
+ "//pkg/abi/linux/errno",
"//pkg/bits",
"//pkg/context",
"//pkg/hostarch",
diff --git a/pkg/sentry/socket/netlink/socket.go b/pkg/sentry/socket/netlink/socket.go
index 280563d09..c9f784cf4 100644
--- a/pkg/sentry/socket/netlink/socket.go
+++ b/pkg/sentry/socket/netlink/socket.go
@@ -20,6 +20,7 @@ import (
"math"
"gvisor.dev/gvisor/pkg/abi/linux"
+ "gvisor.dev/gvisor/pkg/abi/linux/errno"
"gvisor.dev/gvisor/pkg/context"
"gvisor.dev/gvisor/pkg/hostarch"
"gvisor.dev/gvisor/pkg/marshal"
@@ -56,7 +57,7 @@ const (
maxSendBufferSize = 4 << 20 // 4MB
)
-var errNoFilter = syserr.New("no filter attached", linux.ENOENT)
+var errNoFilter = syserr.New("no filter attached", errno.ENOENT)
// netlinkSocketDevice is the netlink socket virtual device.
var netlinkSocketDevice = device.NewAnonDevice()
diff --git a/pkg/sentry/socket/netstack/BUILD b/pkg/sentry/socket/netstack/BUILD
index 9561b7c25..96c425619 100644
--- a/pkg/sentry/socket/netstack/BUILD
+++ b/pkg/sentry/socket/netstack/BUILD
@@ -19,6 +19,7 @@ go_library(
],
deps = [
"//pkg/abi/linux",
+ "//pkg/abi/linux/errno",
"//pkg/context",
"//pkg/hostarch",
"//pkg/log",
diff --git a/pkg/sentry/socket/netstack/netstack.go b/pkg/sentry/socket/netstack/netstack.go
index 11ba80497..66d0fcb47 100644
--- a/pkg/sentry/socket/netstack/netstack.go
+++ b/pkg/sentry/socket/netstack/netstack.go
@@ -36,6 +36,7 @@ import (
"golang.org/x/sys/unix"
"gvisor.dev/gvisor/pkg/abi/linux"
+ "gvisor.dev/gvisor/pkg/abi/linux/errno"
"gvisor.dev/gvisor/pkg/context"
"gvisor.dev/gvisor/pkg/hostarch"
"gvisor.dev/gvisor/pkg/log"
@@ -289,7 +290,7 @@ const DefaultTTL = 64
const sizeOfInt32 int = 4
-var errStackType = syserr.New("expected but did not receive a netstack.Stack", linux.EINVAL)
+var errStackType = syserr.New("expected but did not receive a netstack.Stack", errno.EINVAL)
// commonEndpoint represents the intersection of a tcpip.Endpoint and a
// transport.Endpoint.
diff --git a/pkg/syserr/BUILD b/pkg/syserr/BUILD
index 9cc9e3bf2..7b3160309 100644
--- a/pkg/syserr/BUILD
+++ b/pkg/syserr/BUILD
@@ -11,7 +11,7 @@ go_library(
],
visibility = ["//visibility:public"],
deps = [
- "//pkg/abi/linux",
+ "//pkg/abi/linux/errno",
"//pkg/syserror",
"//pkg/tcpip",
"@org_golang_x_sys//unix:go_default_library",
diff --git a/pkg/syserr/netstack.go b/pkg/syserr/netstack.go
index 90be24e15..eb44f1254 100644
--- a/pkg/syserr/netstack.go
+++ b/pkg/syserr/netstack.go
@@ -17,7 +17,7 @@ package syserr
import (
"fmt"
- "gvisor.dev/gvisor/pkg/abi/linux"
+ "gvisor.dev/gvisor/pkg/abi/linux/errno"
"gvisor.dev/gvisor/pkg/tcpip"
)
@@ -25,33 +25,33 @@ import (
// Mapping for tcpip.Error types.
var (
- ErrUnknownProtocol = New((&tcpip.ErrUnknownProtocol{}).String(), linux.EINVAL)
- ErrUnknownNICID = New((&tcpip.ErrUnknownNICID{}).String(), linux.ENODEV)
- ErrUnknownDevice = New((&tcpip.ErrUnknownDevice{}).String(), linux.ENODEV)
- ErrUnknownProtocolOption = New((&tcpip.ErrUnknownProtocolOption{}).String(), linux.ENOPROTOOPT)
- ErrDuplicateNICID = New((&tcpip.ErrDuplicateNICID{}).String(), linux.EEXIST)
- ErrDuplicateAddress = New((&tcpip.ErrDuplicateAddress{}).String(), linux.EEXIST)
- ErrAlreadyBound = New((&tcpip.ErrAlreadyBound{}).String(), linux.EINVAL)
- ErrInvalidEndpointState = New((&tcpip.ErrInvalidEndpointState{}).String(), linux.EINVAL)
- ErrAlreadyConnecting = New((&tcpip.ErrAlreadyConnecting{}).String(), linux.EALREADY)
- ErrNoPortAvailable = New((&tcpip.ErrNoPortAvailable{}).String(), linux.EAGAIN)
- ErrPortInUse = New((&tcpip.ErrPortInUse{}).String(), linux.EADDRINUSE)
- ErrBadLocalAddress = New((&tcpip.ErrBadLocalAddress{}).String(), linux.EADDRNOTAVAIL)
- ErrClosedForSend = New((&tcpip.ErrClosedForSend{}).String(), linux.EPIPE)
- ErrClosedForReceive = New((&tcpip.ErrClosedForReceive{}).String(), linux.NOERRNO)
- ErrTimeout = New((&tcpip.ErrTimeout{}).String(), linux.ETIMEDOUT)
- ErrAborted = New((&tcpip.ErrAborted{}).String(), linux.EPIPE)
- ErrConnectStarted = New((&tcpip.ErrConnectStarted{}).String(), linux.EINPROGRESS)
- ErrDestinationRequired = New((&tcpip.ErrDestinationRequired{}).String(), linux.EDESTADDRREQ)
- ErrNotSupported = New((&tcpip.ErrNotSupported{}).String(), linux.EOPNOTSUPP)
- ErrQueueSizeNotSupported = New((&tcpip.ErrQueueSizeNotSupported{}).String(), linux.ENOTTY)
- ErrNoSuchFile = New((&tcpip.ErrNoSuchFile{}).String(), linux.ENOENT)
- ErrInvalidOptionValue = New((&tcpip.ErrInvalidOptionValue{}).String(), linux.EINVAL)
- ErrBroadcastDisabled = New((&tcpip.ErrBroadcastDisabled{}).String(), linux.EACCES)
- ErrNotPermittedNet = New((&tcpip.ErrNotPermitted{}).String(), linux.EPERM)
- ErrBadBuffer = New((&tcpip.ErrBadBuffer{}).String(), linux.EFAULT)
- ErrMalformedHeader = New((&tcpip.ErrMalformedHeader{}).String(), linux.EINVAL)
- ErrInvalidPortRange = New((&tcpip.ErrInvalidPortRange{}).String(), linux.EINVAL)
+ ErrUnknownProtocol = New((&tcpip.ErrUnknownProtocol{}).String(), errno.EINVAL)
+ ErrUnknownNICID = New((&tcpip.ErrUnknownNICID{}).String(), errno.ENODEV)
+ ErrUnknownDevice = New((&tcpip.ErrUnknownDevice{}).String(), errno.ENODEV)
+ ErrUnknownProtocolOption = New((&tcpip.ErrUnknownProtocolOption{}).String(), errno.ENOPROTOOPT)
+ ErrDuplicateNICID = New((&tcpip.ErrDuplicateNICID{}).String(), errno.EEXIST)
+ ErrDuplicateAddress = New((&tcpip.ErrDuplicateAddress{}).String(), errno.EEXIST)
+ ErrAlreadyBound = New((&tcpip.ErrAlreadyBound{}).String(), errno.EINVAL)
+ ErrInvalidEndpointState = New((&tcpip.ErrInvalidEndpointState{}).String(), errno.EINVAL)
+ ErrAlreadyConnecting = New((&tcpip.ErrAlreadyConnecting{}).String(), errno.EALREADY)
+ ErrNoPortAvailable = New((&tcpip.ErrNoPortAvailable{}).String(), errno.EAGAIN)
+ ErrPortInUse = New((&tcpip.ErrPortInUse{}).String(), errno.EADDRINUSE)
+ ErrBadLocalAddress = New((&tcpip.ErrBadLocalAddress{}).String(), errno.EADDRNOTAVAIL)
+ ErrClosedForSend = New((&tcpip.ErrClosedForSend{}).String(), errno.EPIPE)
+ ErrClosedForReceive = New((&tcpip.ErrClosedForReceive{}).String(), errno.NOERRNO)
+ ErrTimeout = New((&tcpip.ErrTimeout{}).String(), errno.ETIMEDOUT)
+ ErrAborted = New((&tcpip.ErrAborted{}).String(), errno.EPIPE)
+ ErrConnectStarted = New((&tcpip.ErrConnectStarted{}).String(), errno.EINPROGRESS)
+ ErrDestinationRequired = New((&tcpip.ErrDestinationRequired{}).String(), errno.EDESTADDRREQ)
+ ErrNotSupported = New((&tcpip.ErrNotSupported{}).String(), errno.EOPNOTSUPP)
+ ErrQueueSizeNotSupported = New((&tcpip.ErrQueueSizeNotSupported{}).String(), errno.ENOTTY)
+ ErrNoSuchFile = New((&tcpip.ErrNoSuchFile{}).String(), errno.ENOENT)
+ ErrInvalidOptionValue = New((&tcpip.ErrInvalidOptionValue{}).String(), errno.EINVAL)
+ ErrBroadcastDisabled = New((&tcpip.ErrBroadcastDisabled{}).String(), errno.EACCES)
+ ErrNotPermittedNet = New((&tcpip.ErrNotPermitted{}).String(), errno.EPERM)
+ ErrBadBuffer = New((&tcpip.ErrBadBuffer{}).String(), errno.EFAULT)
+ ErrMalformedHeader = New((&tcpip.ErrMalformedHeader{}).String(), errno.EINVAL)
+ ErrInvalidPortRange = New((&tcpip.ErrInvalidPortRange{}).String(), errno.EINVAL)
)
// TranslateNetstackError converts an error from the tcpip package to a sentry
diff --git a/pkg/syserr/syserr.go b/pkg/syserr/syserr.go
index d70521f32..fb77ac8bd 100644
--- a/pkg/syserr/syserr.go
+++ b/pkg/syserr/syserr.go
@@ -21,7 +21,7 @@ import (
"fmt"
"golang.org/x/sys/unix"
- "gvisor.dev/gvisor/pkg/abi/linux"
+ "gvisor.dev/gvisor/pkg/abi/linux/errno"
"gvisor.dev/gvisor/pkg/syserror"
)
@@ -31,26 +31,25 @@ type Error struct {
message string
// noTranslation indicates that this Error cannot be translated to a
- // linux.Errno.
+ // errno.Errno.
noTranslation bool
- // errno is the linux.Errno this Error should be translated to.
- errno linux.Errno
+ // errno is the errno.Errno this Error should be translated to.
+ errno errno.Errno
}
// New creates a new Error and adds a translation for it.
//
// New must only be called at init.
-func New(message string, linuxTranslation linux.Errno) *Error {
+func New(message string, linuxTranslation errno.Errno) *Error {
err := &Error{message: message, errno: linuxTranslation}
// TODO(b/34162363): Remove this.
- errno := linuxTranslation
- if errno < 0 || int(errno) >= len(linuxBackwardsTranslations) {
- panic(fmt.Sprint("invalid errno: ", errno))
+ if int(err.errno) >= len(linuxBackwardsTranslations) {
+ panic(fmt.Sprint("invalid errno: ", err.errno))
}
- e := error(unix.Errno(errno))
+ e := error(unix.Errno(err.errno))
// syserror.ErrWouldBlock gets translated to syserror.EWOULDBLOCK and
// enables proper blocking semantics. This should temporary address the
// class of blocking bugs that keep popping up with the current state of
@@ -58,7 +57,7 @@ func New(message string, linuxTranslation linux.Errno) *Error {
if e == syserror.EWOULDBLOCK {
e = syserror.ErrWouldBlock
}
- linuxBackwardsTranslations[errno] = linuxBackwardsTranslation{err: e, ok: true}
+ linuxBackwardsTranslations[err.errno] = linuxBackwardsTranslation{err: e, ok: true}
return err
}
@@ -69,7 +68,7 @@ func New(message string, linuxTranslation linux.Errno) *Error {
// NewDynamic should only be used sparingly and not be used for static error
// messages. Errors with static error messages should be declared with New as
// global variables.
-func NewDynamic(message string, linuxTranslation linux.Errno) *Error {
+func NewDynamic(message string, linuxTranslation errno.Errno) *Error {
return &Error{message: message, errno: linuxTranslation}
}
@@ -82,7 +81,7 @@ func NewWithoutTranslation(message string) *Error {
return &Error{message: message, noTranslation: true}
}
-func newWithHost(message string, linuxTranslation linux.Errno, hostErrno unix.Errno) *Error {
+func newWithHost(message string, linuxTranslation errno.Errno, hostErrno unix.Errno) *Error {
e := New(message, linuxTranslation)
addLinuxHostTranslation(hostErrno, e)
return e
@@ -114,19 +113,19 @@ func (e *Error) ToError() error {
if e.noTranslation {
panic(fmt.Sprintf("error %q does not support translation", e.message))
}
- errno := int(e.errno)
- if errno == linux.NOERRNO {
+ err := int(e.errno)
+ if err == errno.NOERRNO {
return nil
}
- if errno <= 0 || errno >= len(linuxBackwardsTranslations) || !linuxBackwardsTranslations[errno].ok {
- panic(fmt.Sprintf("unknown error %q (%d)", e.message, errno))
+ if err >= len(linuxBackwardsTranslations) || !linuxBackwardsTranslations[err].ok {
+ panic(fmt.Sprintf("unknown error %q (%d)", e.message, err))
}
- return linuxBackwardsTranslations[errno].err
+ return linuxBackwardsTranslations[err].err
}
// ToLinux converts the Error to a Linux ABI error that can be returned to the
// application.
-func (e *Error) ToLinux() linux.Errno {
+func (e *Error) ToLinux() errno.Errno {
if e.noTranslation {
panic(fmt.Sprintf("No Linux ABI translation available for %q", e.message))
}
@@ -138,137 +137,137 @@ func (e *Error) ToLinux() linux.Errno {
// Some of the errors should be replaced with package specific errors and
// others should be removed entirely.
var (
- ErrNotPermitted = newWithHost("operation not permitted", linux.EPERM, unix.EPERM)
- ErrNoFileOrDir = newWithHost("no such file or directory", linux.ENOENT, unix.ENOENT)
- ErrNoProcess = newWithHost("no such process", linux.ESRCH, unix.ESRCH)
- ErrInterrupted = newWithHost("interrupted system call", linux.EINTR, unix.EINTR)
- ErrIO = newWithHost("I/O error", linux.EIO, unix.EIO)
- ErrDeviceOrAddress = newWithHost("no such device or address", linux.ENXIO, unix.ENXIO)
- ErrTooManyArgs = newWithHost("argument list too long", linux.E2BIG, unix.E2BIG)
- ErrEcec = newWithHost("exec format error", linux.ENOEXEC, unix.ENOEXEC)
- ErrBadFD = newWithHost("bad file number", linux.EBADF, unix.EBADF)
- ErrNoChild = newWithHost("no child processes", linux.ECHILD, unix.ECHILD)
- ErrTryAgain = newWithHost("try again", linux.EAGAIN, unix.EAGAIN)
- ErrNoMemory = newWithHost("out of memory", linux.ENOMEM, unix.ENOMEM)
- ErrPermissionDenied = newWithHost("permission denied", linux.EACCES, unix.EACCES)
- ErrBadAddress = newWithHost("bad address", linux.EFAULT, unix.EFAULT)
- ErrNotBlockDevice = newWithHost("block device required", linux.ENOTBLK, unix.ENOTBLK)
- ErrBusy = newWithHost("device or resource busy", linux.EBUSY, unix.EBUSY)
- ErrExists = newWithHost("file exists", linux.EEXIST, unix.EEXIST)
- ErrCrossDeviceLink = newWithHost("cross-device link", linux.EXDEV, unix.EXDEV)
- ErrNoDevice = newWithHost("no such device", linux.ENODEV, unix.ENODEV)
- ErrNotDir = newWithHost("not a directory", linux.ENOTDIR, unix.ENOTDIR)
- ErrIsDir = newWithHost("is a directory", linux.EISDIR, unix.EISDIR)
- ErrInvalidArgument = newWithHost("invalid argument", linux.EINVAL, unix.EINVAL)
- ErrFileTableOverflow = newWithHost("file table overflow", linux.ENFILE, unix.ENFILE)
- ErrTooManyOpenFiles = newWithHost("too many open files", linux.EMFILE, unix.EMFILE)
- ErrNotTTY = newWithHost("not a typewriter", linux.ENOTTY, unix.ENOTTY)
- ErrTestFileBusy = newWithHost("text file busy", linux.ETXTBSY, unix.ETXTBSY)
- ErrFileTooBig = newWithHost("file too large", linux.EFBIG, unix.EFBIG)
- ErrNoSpace = newWithHost("no space left on device", linux.ENOSPC, unix.ENOSPC)
- ErrIllegalSeek = newWithHost("illegal seek", linux.ESPIPE, unix.ESPIPE)
- ErrReadOnlyFS = newWithHost("read-only file system", linux.EROFS, unix.EROFS)
- ErrTooManyLinks = newWithHost("too many links", linux.EMLINK, unix.EMLINK)
- ErrBrokenPipe = newWithHost("broken pipe", linux.EPIPE, unix.EPIPE)
- ErrDomain = newWithHost("math argument out of domain of func", linux.EDOM, unix.EDOM)
- ErrRange = newWithHost("math result not representable", linux.ERANGE, unix.ERANGE)
- ErrDeadlock = newWithHost("resource deadlock would occur", linux.EDEADLOCK, unix.EDEADLOCK)
- ErrNameTooLong = newWithHost("file name too long", linux.ENAMETOOLONG, unix.ENAMETOOLONG)
- ErrNoLocksAvailable = newWithHost("no record locks available", linux.ENOLCK, unix.ENOLCK)
- ErrInvalidSyscall = newWithHost("invalid system call number", linux.ENOSYS, unix.ENOSYS)
- ErrDirNotEmpty = newWithHost("directory not empty", linux.ENOTEMPTY, unix.ENOTEMPTY)
- ErrLinkLoop = newWithHost("too many symbolic links encountered", linux.ELOOP, unix.ELOOP)
- ErrNoMessage = newWithHost("no message of desired type", linux.ENOMSG, unix.ENOMSG)
- ErrIdentifierRemoved = newWithHost("identifier removed", linux.EIDRM, unix.EIDRM)
- ErrChannelOutOfRange = newWithHost("channel number out of range", linux.ECHRNG, unix.ECHRNG)
- ErrLevelTwoNotSynced = newWithHost("level 2 not synchronized", linux.EL2NSYNC, unix.EL2NSYNC)
- ErrLevelThreeHalted = newWithHost("level 3 halted", linux.EL3HLT, unix.EL3HLT)
- ErrLevelThreeReset = newWithHost("level 3 reset", linux.EL3RST, unix.EL3RST)
- ErrLinkNumberOutOfRange = newWithHost("link number out of range", linux.ELNRNG, unix.ELNRNG)
- ErrProtocolDriverNotAttached = newWithHost("protocol driver not attached", linux.EUNATCH, unix.EUNATCH)
- ErrNoCSIAvailable = newWithHost("no CSI structure available", linux.ENOCSI, unix.ENOCSI)
- ErrLevelTwoHalted = newWithHost("level 2 halted", linux.EL2HLT, unix.EL2HLT)
- ErrInvalidExchange = newWithHost("invalid exchange", linux.EBADE, unix.EBADE)
- ErrInvalidRequestDescriptor = newWithHost("invalid request descriptor", linux.EBADR, unix.EBADR)
- ErrExchangeFull = newWithHost("exchange full", linux.EXFULL, unix.EXFULL)
- ErrNoAnode = newWithHost("no anode", linux.ENOANO, unix.ENOANO)
- ErrInvalidRequestCode = newWithHost("invalid request code", linux.EBADRQC, unix.EBADRQC)
- ErrInvalidSlot = newWithHost("invalid slot", linux.EBADSLT, unix.EBADSLT)
- ErrBadFontFile = newWithHost("bad font file format", linux.EBFONT, unix.EBFONT)
- ErrNotStream = newWithHost("device not a stream", linux.ENOSTR, unix.ENOSTR)
- ErrNoDataAvailable = newWithHost("no data available", linux.ENODATA, unix.ENODATA)
- ErrTimerExpired = newWithHost("timer expired", linux.ETIME, unix.ETIME)
- ErrStreamsResourceDepleted = newWithHost("out of streams resources", linux.ENOSR, unix.ENOSR)
- ErrMachineNotOnNetwork = newWithHost("machine is not on the network", linux.ENONET, unix.ENONET)
- ErrPackageNotInstalled = newWithHost("package not installed", linux.ENOPKG, unix.ENOPKG)
- ErrIsRemote = newWithHost("object is remote", linux.EREMOTE, unix.EREMOTE)
- ErrNoLink = newWithHost("link has been severed", linux.ENOLINK, unix.ENOLINK)
- ErrAdvertise = newWithHost("advertise error", linux.EADV, unix.EADV)
- ErrSRMount = newWithHost("srmount error", linux.ESRMNT, unix.ESRMNT)
- ErrSendCommunication = newWithHost("communication error on send", linux.ECOMM, unix.ECOMM)
- ErrProtocol = newWithHost("protocol error", linux.EPROTO, unix.EPROTO)
- ErrMultihopAttempted = newWithHost("multihop attempted", linux.EMULTIHOP, unix.EMULTIHOP)
- ErrRFS = newWithHost("RFS specific error", linux.EDOTDOT, unix.EDOTDOT)
- ErrInvalidDataMessage = newWithHost("not a data message", linux.EBADMSG, unix.EBADMSG)
- ErrOverflow = newWithHost("value too large for defined data type", linux.EOVERFLOW, unix.EOVERFLOW)
- ErrNetworkNameNotUnique = newWithHost("name not unique on network", linux.ENOTUNIQ, unix.ENOTUNIQ)
- ErrFDInBadState = newWithHost("file descriptor in bad state", linux.EBADFD, unix.EBADFD)
- ErrRemoteAddressChanged = newWithHost("remote address changed", linux.EREMCHG, unix.EREMCHG)
- ErrSharedLibraryInaccessible = newWithHost("can not access a needed shared library", linux.ELIBACC, unix.ELIBACC)
- ErrCorruptedSharedLibrary = newWithHost("accessing a corrupted shared library", linux.ELIBBAD, unix.ELIBBAD)
- ErrLibSectionCorrupted = newWithHost(".lib section in a.out corrupted", linux.ELIBSCN, unix.ELIBSCN)
- ErrTooManySharedLibraries = newWithHost("attempting to link in too many shared libraries", linux.ELIBMAX, unix.ELIBMAX)
- ErrSharedLibraryExeced = newWithHost("cannot exec a shared library directly", linux.ELIBEXEC, unix.ELIBEXEC)
- ErrIllegalByteSequence = newWithHost("illegal byte sequence", linux.EILSEQ, unix.EILSEQ)
- ErrShouldRestart = newWithHost("interrupted system call should be restarted", linux.ERESTART, unix.ERESTART)
- ErrStreamPipe = newWithHost("streams pipe error", linux.ESTRPIPE, unix.ESTRPIPE)
- ErrTooManyUsers = newWithHost("too many users", linux.EUSERS, unix.EUSERS)
- ErrNotASocket = newWithHost("socket operation on non-socket", linux.ENOTSOCK, unix.ENOTSOCK)
- ErrDestinationAddressRequired = newWithHost("destination address required", linux.EDESTADDRREQ, unix.EDESTADDRREQ)
- ErrMessageTooLong = newWithHost("message too long", linux.EMSGSIZE, unix.EMSGSIZE)
- ErrWrongProtocolForSocket = newWithHost("protocol wrong type for socket", linux.EPROTOTYPE, unix.EPROTOTYPE)
- ErrProtocolNotAvailable = newWithHost("protocol not available", linux.ENOPROTOOPT, unix.ENOPROTOOPT)
- ErrProtocolNotSupported = newWithHost("protocol not supported", linux.EPROTONOSUPPORT, unix.EPROTONOSUPPORT)
- ErrSocketNotSupported = newWithHost("socket type not supported", linux.ESOCKTNOSUPPORT, unix.ESOCKTNOSUPPORT)
- ErrEndpointOperation = newWithHost("operation not supported on transport endpoint", linux.EOPNOTSUPP, unix.EOPNOTSUPP)
- ErrProtocolFamilyNotSupported = newWithHost("protocol family not supported", linux.EPFNOSUPPORT, unix.EPFNOSUPPORT)
- ErrAddressFamilyNotSupported = newWithHost("address family not supported by protocol", linux.EAFNOSUPPORT, unix.EAFNOSUPPORT)
- ErrAddressInUse = newWithHost("address already in use", linux.EADDRINUSE, unix.EADDRINUSE)
- ErrAddressNotAvailable = newWithHost("cannot assign requested address", linux.EADDRNOTAVAIL, unix.EADDRNOTAVAIL)
- ErrNetworkDown = newWithHost("network is down", linux.ENETDOWN, unix.ENETDOWN)
- ErrNetworkUnreachable = newWithHost("network is unreachable", linux.ENETUNREACH, unix.ENETUNREACH)
- ErrNetworkReset = newWithHost("network dropped connection because of reset", linux.ENETRESET, unix.ENETRESET)
- ErrConnectionAborted = newWithHost("software caused connection abort", linux.ECONNABORTED, unix.ECONNABORTED)
- ErrConnectionReset = newWithHost("connection reset by peer", linux.ECONNRESET, unix.ECONNRESET)
- ErrNoBufferSpace = newWithHost("no buffer space available", linux.ENOBUFS, unix.ENOBUFS)
- ErrAlreadyConnected = newWithHost("transport endpoint is already connected", linux.EISCONN, unix.EISCONN)
- ErrNotConnected = newWithHost("transport endpoint is not connected", linux.ENOTCONN, unix.ENOTCONN)
- ErrShutdown = newWithHost("cannot send after transport endpoint shutdown", linux.ESHUTDOWN, unix.ESHUTDOWN)
- ErrTooManyRefs = newWithHost("too many references: cannot splice", linux.ETOOMANYREFS, unix.ETOOMANYREFS)
- ErrTimedOut = newWithHost("connection timed out", linux.ETIMEDOUT, unix.ETIMEDOUT)
- ErrConnectionRefused = newWithHost("connection refused", linux.ECONNREFUSED, unix.ECONNREFUSED)
- ErrHostDown = newWithHost("host is down", linux.EHOSTDOWN, unix.EHOSTDOWN)
- ErrNoRoute = newWithHost("no route to host", linux.EHOSTUNREACH, unix.EHOSTUNREACH)
- ErrAlreadyInProgress = newWithHost("operation already in progress", linux.EALREADY, unix.EALREADY)
- ErrInProgress = newWithHost("operation now in progress", linux.EINPROGRESS, unix.EINPROGRESS)
- ErrStaleFileHandle = newWithHost("stale file handle", linux.ESTALE, unix.ESTALE)
- ErrStructureNeedsCleaning = newWithHost("structure needs cleaning", linux.EUCLEAN, unix.EUCLEAN)
- ErrIsNamedFile = newWithHost("is a named type file", linux.ENOTNAM, unix.ENOTNAM)
- ErrRemoteIO = newWithHost("remote I/O error", linux.EREMOTEIO, unix.EREMOTEIO)
- ErrQuotaExceeded = newWithHost("quota exceeded", linux.EDQUOT, unix.EDQUOT)
- ErrNoMedium = newWithHost("no medium found", linux.ENOMEDIUM, unix.ENOMEDIUM)
- ErrWrongMediumType = newWithHost("wrong medium type", linux.EMEDIUMTYPE, unix.EMEDIUMTYPE)
- ErrCanceled = newWithHost("operation canceled", linux.ECANCELED, unix.ECANCELED)
- ErrNoKey = newWithHost("required key not available", linux.ENOKEY, unix.ENOKEY)
- ErrKeyExpired = newWithHost("key has expired", linux.EKEYEXPIRED, unix.EKEYEXPIRED)
- ErrKeyRevoked = newWithHost("key has been revoked", linux.EKEYREVOKED, unix.EKEYREVOKED)
- ErrKeyRejected = newWithHost("key was rejected by service", linux.EKEYREJECTED, unix.EKEYREJECTED)
- ErrOwnerDied = newWithHost("owner died", linux.EOWNERDEAD, unix.EOWNERDEAD)
- ErrNotRecoverable = newWithHost("state not recoverable", linux.ENOTRECOVERABLE, unix.ENOTRECOVERABLE)
+ ErrNotPermitted = newWithHost("operation not permitted", errno.EPERM, unix.EPERM)
+ ErrNoFileOrDir = newWithHost("no such file or directory", errno.ENOENT, unix.ENOENT)
+ ErrNoProcess = newWithHost("no such process", errno.ESRCH, unix.ESRCH)
+ ErrInterrupted = newWithHost("interrupted system call", errno.EINTR, unix.EINTR)
+ ErrIO = newWithHost("I/O error", errno.EIO, unix.EIO)
+ ErrDeviceOrAddress = newWithHost("no such device or address", errno.ENXIO, unix.ENXIO)
+ ErrTooManyArgs = newWithHost("argument list too long", errno.E2BIG, unix.E2BIG)
+ ErrEcec = newWithHost("exec format error", errno.ENOEXEC, unix.ENOEXEC)
+ ErrBadFD = newWithHost("bad file number", errno.EBADF, unix.EBADF)
+ ErrNoChild = newWithHost("no child processes", errno.ECHILD, unix.ECHILD)
+ ErrTryAgain = newWithHost("try again", errno.EAGAIN, unix.EAGAIN)
+ ErrNoMemory = newWithHost("out of memory", errno.ENOMEM, unix.ENOMEM)
+ ErrPermissionDenied = newWithHost("permission denied", errno.EACCES, unix.EACCES)
+ ErrBadAddress = newWithHost("bad address", errno.EFAULT, unix.EFAULT)
+ ErrNotBlockDevice = newWithHost("block device required", errno.ENOTBLK, unix.ENOTBLK)
+ ErrBusy = newWithHost("device or resource busy", errno.EBUSY, unix.EBUSY)
+ ErrExists = newWithHost("file exists", errno.EEXIST, unix.EEXIST)
+ ErrCrossDeviceLink = newWithHost("cross-device link", errno.EXDEV, unix.EXDEV)
+ ErrNoDevice = newWithHost("no such device", errno.ENODEV, unix.ENODEV)
+ ErrNotDir = newWithHost("not a directory", errno.ENOTDIR, unix.ENOTDIR)
+ ErrIsDir = newWithHost("is a directory", errno.EISDIR, unix.EISDIR)
+ ErrInvalidArgument = newWithHost("invalid argument", errno.EINVAL, unix.EINVAL)
+ ErrFileTableOverflow = newWithHost("file table overflow", errno.ENFILE, unix.ENFILE)
+ ErrTooManyOpenFiles = newWithHost("too many open files", errno.EMFILE, unix.EMFILE)
+ ErrNotTTY = newWithHost("not a typewriter", errno.ENOTTY, unix.ENOTTY)
+ ErrTestFileBusy = newWithHost("text file busy", errno.ETXTBSY, unix.ETXTBSY)
+ ErrFileTooBig = newWithHost("file too large", errno.EFBIG, unix.EFBIG)
+ ErrNoSpace = newWithHost("no space left on device", errno.ENOSPC, unix.ENOSPC)
+ ErrIllegalSeek = newWithHost("illegal seek", errno.ESPIPE, unix.ESPIPE)
+ ErrReadOnlyFS = newWithHost("read-only file system", errno.EROFS, unix.EROFS)
+ ErrTooManyLinks = newWithHost("too many links", errno.EMLINK, unix.EMLINK)
+ ErrBrokenPipe = newWithHost("broken pipe", errno.EPIPE, unix.EPIPE)
+ ErrDomain = newWithHost("math argument out of domain of func", errno.EDOM, unix.EDOM)
+ ErrRange = newWithHost("math result not representable", errno.ERANGE, unix.ERANGE)
+ ErrDeadlock = newWithHost("resource deadlock would occur", errno.EDEADLOCK, unix.EDEADLOCK)
+ ErrNameTooLong = newWithHost("file name too long", errno.ENAMETOOLONG, unix.ENAMETOOLONG)
+ ErrNoLocksAvailable = newWithHost("no record locks available", errno.ENOLCK, unix.ENOLCK)
+ ErrInvalidSyscall = newWithHost("invalid system call number", errno.ENOSYS, unix.ENOSYS)
+ ErrDirNotEmpty = newWithHost("directory not empty", errno.ENOTEMPTY, unix.ENOTEMPTY)
+ ErrLinkLoop = newWithHost("too many symbolic links encountered", errno.ELOOP, unix.ELOOP)
+ ErrNoMessage = newWithHost("no message of desired type", errno.ENOMSG, unix.ENOMSG)
+ ErrIdentifierRemoved = newWithHost("identifier removed", errno.EIDRM, unix.EIDRM)
+ ErrChannelOutOfRange = newWithHost("channel number out of range", errno.ECHRNG, unix.ECHRNG)
+ ErrLevelTwoNotSynced = newWithHost("level 2 not synchronized", errno.EL2NSYNC, unix.EL2NSYNC)
+ ErrLevelThreeHalted = newWithHost("level 3 halted", errno.EL3HLT, unix.EL3HLT)
+ ErrLevelThreeReset = newWithHost("level 3 reset", errno.EL3RST, unix.EL3RST)
+ ErrLinkNumberOutOfRange = newWithHost("link number out of range", errno.ELNRNG, unix.ELNRNG)
+ ErrProtocolDriverNotAttached = newWithHost("protocol driver not attached", errno.EUNATCH, unix.EUNATCH)
+ ErrNoCSIAvailable = newWithHost("no CSI structure available", errno.ENOCSI, unix.ENOCSI)
+ ErrLevelTwoHalted = newWithHost("level 2 halted", errno.EL2HLT, unix.EL2HLT)
+ ErrInvalidExchange = newWithHost("invalid exchange", errno.EBADE, unix.EBADE)
+ ErrInvalidRequestDescriptor = newWithHost("invalid request descriptor", errno.EBADR, unix.EBADR)
+ ErrExchangeFull = newWithHost("exchange full", errno.EXFULL, unix.EXFULL)
+ ErrNoAnode = newWithHost("no anode", errno.ENOANO, unix.ENOANO)
+ ErrInvalidRequestCode = newWithHost("invalid request code", errno.EBADRQC, unix.EBADRQC)
+ ErrInvalidSlot = newWithHost("invalid slot", errno.EBADSLT, unix.EBADSLT)
+ ErrBadFontFile = newWithHost("bad font file format", errno.EBFONT, unix.EBFONT)
+ ErrNotStream = newWithHost("device not a stream", errno.ENOSTR, unix.ENOSTR)
+ ErrNoDataAvailable = newWithHost("no data available", errno.ENODATA, unix.ENODATA)
+ ErrTimerExpired = newWithHost("timer expired", errno.ETIME, unix.ETIME)
+ ErrStreamsResourceDepleted = newWithHost("out of streams resources", errno.ENOSR, unix.ENOSR)
+ ErrMachineNotOnNetwork = newWithHost("machine is not on the network", errno.ENONET, unix.ENONET)
+ ErrPackageNotInstalled = newWithHost("package not installed", errno.ENOPKG, unix.ENOPKG)
+ ErrIsRemote = newWithHost("object is remote", errno.EREMOTE, unix.EREMOTE)
+ ErrNoLink = newWithHost("link has been severed", errno.ENOLINK, unix.ENOLINK)
+ ErrAdvertise = newWithHost("advertise error", errno.EADV, unix.EADV)
+ ErrSRMount = newWithHost("srmount error", errno.ESRMNT, unix.ESRMNT)
+ ErrSendCommunication = newWithHost("communication error on send", errno.ECOMM, unix.ECOMM)
+ ErrProtocol = newWithHost("protocol error", errno.EPROTO, unix.EPROTO)
+ ErrMultihopAttempted = newWithHost("multihop attempted", errno.EMULTIHOP, unix.EMULTIHOP)
+ ErrRFS = newWithHost("RFS specific error", errno.EDOTDOT, unix.EDOTDOT)
+ ErrInvalidDataMessage = newWithHost("not a data message", errno.EBADMSG, unix.EBADMSG)
+ ErrOverflow = newWithHost("value too large for defined data type", errno.EOVERFLOW, unix.EOVERFLOW)
+ ErrNetworkNameNotUnique = newWithHost("name not unique on network", errno.ENOTUNIQ, unix.ENOTUNIQ)
+ ErrFDInBadState = newWithHost("file descriptor in bad state", errno.EBADFD, unix.EBADFD)
+ ErrRemoteAddressChanged = newWithHost("remote address changed", errno.EREMCHG, unix.EREMCHG)
+ ErrSharedLibraryInaccessible = newWithHost("can not access a needed shared library", errno.ELIBACC, unix.ELIBACC)
+ ErrCorruptedSharedLibrary = newWithHost("accessing a corrupted shared library", errno.ELIBBAD, unix.ELIBBAD)
+ ErrLibSectionCorrupted = newWithHost(".lib section in a.out corrupted", errno.ELIBSCN, unix.ELIBSCN)
+ ErrTooManySharedLibraries = newWithHost("attempting to link in too many shared libraries", errno.ELIBMAX, unix.ELIBMAX)
+ ErrSharedLibraryExeced = newWithHost("cannot exec a shared library directly", errno.ELIBEXEC, unix.ELIBEXEC)
+ ErrIllegalByteSequence = newWithHost("illegal byte sequence", errno.EILSEQ, unix.EILSEQ)
+ ErrShouldRestart = newWithHost("interrupted system call should be restarted", errno.ERESTART, unix.ERESTART)
+ ErrStreamPipe = newWithHost("streams pipe error", errno.ESTRPIPE, unix.ESTRPIPE)
+ ErrTooManyUsers = newWithHost("too many users", errno.EUSERS, unix.EUSERS)
+ ErrNotASocket = newWithHost("socket operation on non-socket", errno.ENOTSOCK, unix.ENOTSOCK)
+ ErrDestinationAddressRequired = newWithHost("destination address required", errno.EDESTADDRREQ, unix.EDESTADDRREQ)
+ ErrMessageTooLong = newWithHost("message too long", errno.EMSGSIZE, unix.EMSGSIZE)
+ ErrWrongProtocolForSocket = newWithHost("protocol wrong type for socket", errno.EPROTOTYPE, unix.EPROTOTYPE)
+ ErrProtocolNotAvailable = newWithHost("protocol not available", errno.ENOPROTOOPT, unix.ENOPROTOOPT)
+ ErrProtocolNotSupported = newWithHost("protocol not supported", errno.EPROTONOSUPPORT, unix.EPROTONOSUPPORT)
+ ErrSocketNotSupported = newWithHost("socket type not supported", errno.ESOCKTNOSUPPORT, unix.ESOCKTNOSUPPORT)
+ ErrEndpointOperation = newWithHost("operation not supported on transport endpoint", errno.EOPNOTSUPP, unix.EOPNOTSUPP)
+ ErrProtocolFamilyNotSupported = newWithHost("protocol family not supported", errno.EPFNOSUPPORT, unix.EPFNOSUPPORT)
+ ErrAddressFamilyNotSupported = newWithHost("address family not supported by protocol", errno.EAFNOSUPPORT, unix.EAFNOSUPPORT)
+ ErrAddressInUse = newWithHost("address already in use", errno.EADDRINUSE, unix.EADDRINUSE)
+ ErrAddressNotAvailable = newWithHost("cannot assign requested address", errno.EADDRNOTAVAIL, unix.EADDRNOTAVAIL)
+ ErrNetworkDown = newWithHost("network is down", errno.ENETDOWN, unix.ENETDOWN)
+ ErrNetworkUnreachable = newWithHost("network is unreachable", errno.ENETUNREACH, unix.ENETUNREACH)
+ ErrNetworkReset = newWithHost("network dropped connection because of reset", errno.ENETRESET, unix.ENETRESET)
+ ErrConnectionAborted = newWithHost("software caused connection abort", errno.ECONNABORTED, unix.ECONNABORTED)
+ ErrConnectionReset = newWithHost("connection reset by peer", errno.ECONNRESET, unix.ECONNRESET)
+ ErrNoBufferSpace = newWithHost("no buffer space available", errno.ENOBUFS, unix.ENOBUFS)
+ ErrAlreadyConnected = newWithHost("transport endpoint is already connected", errno.EISCONN, unix.EISCONN)
+ ErrNotConnected = newWithHost("transport endpoint is not connected", errno.ENOTCONN, unix.ENOTCONN)
+ ErrShutdown = newWithHost("cannot send after transport endpoint shutdown", errno.ESHUTDOWN, unix.ESHUTDOWN)
+ ErrTooManyRefs = newWithHost("too many references: cannot splice", errno.ETOOMANYREFS, unix.ETOOMANYREFS)
+ ErrTimedOut = newWithHost("connection timed out", errno.ETIMEDOUT, unix.ETIMEDOUT)
+ ErrConnectionRefused = newWithHost("connection refused", errno.ECONNREFUSED, unix.ECONNREFUSED)
+ ErrHostDown = newWithHost("host is down", errno.EHOSTDOWN, unix.EHOSTDOWN)
+ ErrNoRoute = newWithHost("no route to host", errno.EHOSTUNREACH, unix.EHOSTUNREACH)
+ ErrAlreadyInProgress = newWithHost("operation already in progress", errno.EALREADY, unix.EALREADY)
+ ErrInProgress = newWithHost("operation now in progress", errno.EINPROGRESS, unix.EINPROGRESS)
+ ErrStaleFileHandle = newWithHost("stale file handle", errno.ESTALE, unix.ESTALE)
+ ErrStructureNeedsCleaning = newWithHost("structure needs cleaning", errno.EUCLEAN, unix.EUCLEAN)
+ ErrIsNamedFile = newWithHost("is a named type file", errno.ENOTNAM, unix.ENOTNAM)
+ ErrRemoteIO = newWithHost("remote I/O error", errno.EREMOTEIO, unix.EREMOTEIO)
+ ErrQuotaExceeded = newWithHost("quota exceeded", errno.EDQUOT, unix.EDQUOT)
+ ErrNoMedium = newWithHost("no medium found", errno.ENOMEDIUM, unix.ENOMEDIUM)
+ ErrWrongMediumType = newWithHost("wrong medium type", errno.EMEDIUMTYPE, unix.EMEDIUMTYPE)
+ ErrCanceled = newWithHost("operation canceled", errno.ECANCELED, unix.ECANCELED)
+ ErrNoKey = newWithHost("required key not available", errno.ENOKEY, unix.ENOKEY)
+ ErrKeyExpired = newWithHost("key has expired", errno.EKEYEXPIRED, unix.EKEYEXPIRED)
+ ErrKeyRevoked = newWithHost("key has been revoked", errno.EKEYREVOKED, unix.EKEYREVOKED)
+ ErrKeyRejected = newWithHost("key was rejected by service", errno.EKEYREJECTED, unix.EKEYREJECTED)
+ ErrOwnerDied = newWithHost("owner died", errno.EOWNERDEAD, unix.EOWNERDEAD)
+ ErrNotRecoverable = newWithHost("state not recoverable", errno.ENOTRECOVERABLE, unix.ENOTRECOVERABLE)
// ErrWouldBlock translates to EWOULDBLOCK which is the same as EAGAIN
// on Linux.
- ErrWouldBlock = New("operation would block", linux.EWOULDBLOCK)
+ ErrWouldBlock = New("operation would block", errno.EWOULDBLOCK)
)
// FromError converts a generic error to an *Error.