snapshot: sagernet/gvisor v0.0.0-20250811.0-sing-box-mod.1
Содержимое пина, зафиксированного в go.mod sing-box-lx, одним коммитом без истории. Полная история SagerNet/gvisor — 1.45 ГБ и клонируется в каждой CI-джобе; наша дельта — одна вставка в одну функцию, история для неё не нужна. Module path github.com/sagernet/gvisor сохранён намеренно: на него опирается replace-директива суперпроекта. Патч поверх — отдельным коммитом, чтобы дельта читалась одним git show и переносилась на новый пин копированием. SPECS/TASKS/048-GVISOR_HANDSHAKE_NIL_CRASH
This commit is contained in:
commit
2c4ae3b0a4
712 changed files with 185689 additions and 0 deletions
129
pkg/errors/linuxerr/internal.go
Normal file
129
pkg/errors/linuxerr/internal.go
Normal file
|
|
@ -0,0 +1,129 @@
|
|||
// 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
|
||||
|
||||
import (
|
||||
"github.com/sagernet/gvisor/pkg/abi/linux/errno"
|
||||
"github.com/sagernet/gvisor/pkg/errors"
|
||||
)
|
||||
|
||||
var (
|
||||
// ErrWouldBlock is an internal error used to indicate that an operation
|
||||
// cannot be satisfied immediately, and should be retried at a later
|
||||
// time, possibly when the caller has received a notification that the
|
||||
// operation may be able to complete. It is used by implementations of
|
||||
// the kio.File interface.
|
||||
ErrWouldBlock = errors.New(errno.EWOULDBLOCK, "request would block")
|
||||
|
||||
// ErrInterrupted is returned if a request is interrupted before it can
|
||||
// complete.
|
||||
ErrInterrupted = errors.New(errno.EINTR, "request was interrupted")
|
||||
|
||||
// ErrExceedsFileSizeLimit is returned if a request would exceed the
|
||||
// file's size limit.
|
||||
ErrExceedsFileSizeLimit = errors.New(errno.E2BIG, "exceeds file size limit")
|
||||
)
|
||||
|
||||
var errorMap = map[error]*errors.Error{
|
||||
ErrWouldBlock: EWOULDBLOCK,
|
||||
ErrInterrupted: EINTR,
|
||||
ErrExceedsFileSizeLimit: EFBIG,
|
||||
}
|
||||
|
||||
// errorUnwrappers is an array of unwrap functions to extract typed errors.
|
||||
var errorUnwrappers = []func(error) (*errors.Error, bool){}
|
||||
|
||||
// AddErrorUnwrapper registers an unwrap method that can extract a concrete error
|
||||
// from a typed, but not initialized, error.
|
||||
func AddErrorUnwrapper(unwrap func(e error) (*errors.Error, bool)) {
|
||||
errorUnwrappers = append(errorUnwrappers, unwrap)
|
||||
}
|
||||
|
||||
// TranslateError translates errors to errnos for registered internal errors.
|
||||
// It will return false if the error was not registered.
|
||||
func TranslateError(from error) (*errors.Error, bool) {
|
||||
if err, ok := errorMap[from]; ok {
|
||||
return err, true
|
||||
}
|
||||
// Try to unwrap the error if we couldn't match an error
|
||||
// exactly. This might mean that a package has its own
|
||||
// error type.
|
||||
for _, unwrap := range errorUnwrappers {
|
||||
if err, ok := unwrap(from); ok {
|
||||
return err, true
|
||||
}
|
||||
}
|
||||
return nil, false
|
||||
}
|
||||
|
||||
// These errors are significant because ptrace syscall exit tracing can
|
||||
// observe them.
|
||||
//
|
||||
// For all of the following errors, if the syscall is not interrupted by a
|
||||
// signal delivered to a user handler, the syscall is restarted.
|
||||
var (
|
||||
// ERESTARTSYS is returned by an interrupted syscall to indicate that it
|
||||
// should be converted to EINTR if interrupted by a signal delivered to a
|
||||
// user handler without SA_RESTART set, and restarted otherwise.
|
||||
ERESTARTSYS = errors.New(errno.ERESTARTSYS, "to be restarted if SA_RESTART is set")
|
||||
|
||||
// ERESTARTNOINTR is returned by an interrupted syscall to indicate that it
|
||||
// should always be restarted.
|
||||
ERESTARTNOINTR = errors.New(errno.ERESTARTNOINTR, "to be restarted")
|
||||
|
||||
// ERESTARTNOHAND is returned by an interrupted syscall to indicate that it
|
||||
// should be converted to EINTR if interrupted by a signal delivered to a
|
||||
// user handler, and restarted otherwise.
|
||||
ERESTARTNOHAND = errors.New(errno.ERESTARTNOHAND, "to be restarted if no handler")
|
||||
|
||||
// ERESTART_RESTARTBLOCK is returned by an interrupted syscall to indicate
|
||||
// that it should be restarted using a custom function. The interrupted
|
||||
// syscall must register a custom restart function by calling
|
||||
// Task.SetRestartSyscallFn.
|
||||
ERESTART_RESTARTBLOCK = errors.New(errno.ERESTART_RESTARTBLOCK, "interrupted by signal")
|
||||
)
|
||||
|
||||
var restartMap = map[int]*errors.Error{
|
||||
-int(errno.ERESTARTSYS): ERESTARTSYS,
|
||||
-int(errno.ERESTARTNOINTR): ERESTARTNOINTR,
|
||||
-int(errno.ERESTARTNOHAND): ERESTARTNOHAND,
|
||||
-int(errno.ERESTART_RESTARTBLOCK): ERESTART_RESTARTBLOCK,
|
||||
}
|
||||
|
||||
// IsRestartError checks if a given error is a restart error.
|
||||
func IsRestartError(err error) bool {
|
||||
switch err {
|
||||
case ERESTARTSYS, ERESTARTNOINTR, ERESTARTNOHAND, ERESTART_RESTARTBLOCK:
|
||||
return true
|
||||
default:
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
// SyscallRestartErrorFromReturn returns the SyscallRestartErrno represented by
|
||||
// rv, the value in a syscall return register.
|
||||
func SyscallRestartErrorFromReturn(rv uintptr) (*errors.Error, bool) {
|
||||
err, ok := restartMap[int(rv)]
|
||||
return err, ok
|
||||
}
|
||||
|
||||
// ConvertIntr converts the provided error code (err) to another one (intr) if
|
||||
// the first error corresponds to an interrupted operation.
|
||||
func ConvertIntr(err, intr error) error {
|
||||
if err == ErrInterrupted {
|
||||
return intr
|
||||
}
|
||||
return err
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue