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
187
pkg/fspath/fspath.go
Normal file
187
pkg/fspath/fspath.go
Normal file
|
|
@ -0,0 +1,187 @@
|
|||
// Copyright 2019 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 fspath provides efficient tools for working with file paths in
|
||||
// Linux-compatible filesystem implementations.
|
||||
package fspath
|
||||
|
||||
import (
|
||||
"strings"
|
||||
)
|
||||
|
||||
const pathSep = '/'
|
||||
|
||||
// Parse parses a pathname as described by path_resolution(7), except that
|
||||
// empty pathnames will be parsed successfully to a Path for which
|
||||
// Path.Absolute == Path.Dir == Path.HasComponents() == false. (This is
|
||||
// necessary to support AT_EMPTY_PATH.)
|
||||
func Parse(pathname string) Path {
|
||||
if len(pathname) == 0 {
|
||||
return Path{}
|
||||
}
|
||||
// Skip leading path separators.
|
||||
i := 0
|
||||
for pathname[i] == pathSep {
|
||||
i++
|
||||
if i == len(pathname) {
|
||||
// pathname consists entirely of path separators.
|
||||
return Path{
|
||||
Absolute: true,
|
||||
Dir: true,
|
||||
}
|
||||
}
|
||||
}
|
||||
// Skip trailing path separators. This is required by Iterator.Next. This
|
||||
// loop is guaranteed to terminate with j >= 0 because otherwise the
|
||||
// pathname would consist entirely of path separators, so we would have
|
||||
// returned above.
|
||||
j := len(pathname) - 1
|
||||
for pathname[j] == pathSep {
|
||||
j--
|
||||
}
|
||||
// Find the end of the first path component.
|
||||
firstEnd := i + 1
|
||||
for firstEnd != len(pathname) && pathname[firstEnd] != pathSep {
|
||||
firstEnd++
|
||||
}
|
||||
return Path{
|
||||
Begin: Iterator{
|
||||
partialPathname: pathname[i : j+1],
|
||||
end: firstEnd - i,
|
||||
},
|
||||
Absolute: i != 0,
|
||||
Dir: j != len(pathname)-1,
|
||||
}
|
||||
}
|
||||
|
||||
// Path contains the information contained in a pathname string.
|
||||
//
|
||||
// Path is copyable by value. The zero value for Path is equivalent to
|
||||
// fspath.Parse(""), i.e. the empty path.
|
||||
type Path struct {
|
||||
// Begin is an iterator to the first path component in the relative part of
|
||||
// the path.
|
||||
//
|
||||
// Path doesn't store information about path components after the first
|
||||
// since this would require allocation.
|
||||
Begin Iterator
|
||||
|
||||
// If true, the path is absolute, such that lookup should begin at the
|
||||
// filesystem root. If false, the path is relative, such that where lookup
|
||||
// begins is unspecified.
|
||||
Absolute bool
|
||||
|
||||
// If true, the pathname contains trailing path separators, so the last
|
||||
// path component must exist and resolve to a directory.
|
||||
Dir bool
|
||||
}
|
||||
|
||||
// String returns a pathname string equivalent to p. Note that the returned
|
||||
// string is not necessarily equal to the string p was parsed from; in
|
||||
// particular, redundant path separators will not be present.
|
||||
func (p Path) String() string {
|
||||
var b strings.Builder
|
||||
if p.Absolute {
|
||||
b.WriteByte(pathSep)
|
||||
}
|
||||
sep := false
|
||||
for pit := p.Begin; pit.Ok(); pit = pit.Next() {
|
||||
if sep {
|
||||
b.WriteByte(pathSep)
|
||||
}
|
||||
b.WriteString(pit.String())
|
||||
sep = true
|
||||
}
|
||||
// Don't return "//" for Parse("/").
|
||||
if p.Dir && p.Begin.Ok() {
|
||||
b.WriteByte(pathSep)
|
||||
}
|
||||
return b.String()
|
||||
}
|
||||
|
||||
// HasComponents returns true if p contains a non-zero number of path
|
||||
// components.
|
||||
func (p Path) HasComponents() bool {
|
||||
return p.Begin.Ok()
|
||||
}
|
||||
|
||||
// An Iterator represents either a path component in a Path or a terminal
|
||||
// iterator indicating that the end of the path has been reached.
|
||||
//
|
||||
// Iterator is immutable and copyable by value. The zero value of Iterator is
|
||||
// valid, and represents a terminal iterator.
|
||||
type Iterator struct {
|
||||
// partialPathname is a substring of the original pathname beginning at the
|
||||
// start of the represented path component and ending immediately after the
|
||||
// end of the last path component in the pathname. If partialPathname is
|
||||
// empty, the PathnameIterator is terminal.
|
||||
//
|
||||
// See TestParseIteratorPartialPathnames in fspath_test.go for a worked
|
||||
// example.
|
||||
partialPathname string
|
||||
|
||||
// end is the offset into partialPathname of the first byte after the end
|
||||
// of the represented path component.
|
||||
end int
|
||||
}
|
||||
|
||||
// Ok returns true if it is not terminal.
|
||||
func (it Iterator) Ok() bool {
|
||||
return len(it.partialPathname) != 0
|
||||
}
|
||||
|
||||
// String returns the path component represented by it.
|
||||
//
|
||||
// Preconditions: it.Ok().
|
||||
func (it Iterator) String() string {
|
||||
return it.partialPathname[:it.end]
|
||||
}
|
||||
|
||||
// Next returns an iterator to the path component after it. If it is the last
|
||||
// component in the path, Next returns a terminal iterator.
|
||||
//
|
||||
// Preconditions: it.Ok().
|
||||
func (it Iterator) Next() Iterator {
|
||||
if it.end == len(it.partialPathname) {
|
||||
// End of the path.
|
||||
return Iterator{}
|
||||
}
|
||||
// Skip path separators. Since Parse trims trailing path separators, if we
|
||||
// aren't at the end of the path, there is definitely another path
|
||||
// component.
|
||||
i := it.end + 1
|
||||
for {
|
||||
if it.partialPathname[i] != pathSep {
|
||||
break
|
||||
}
|
||||
i++
|
||||
}
|
||||
nextPartialPathname := it.partialPathname[i:]
|
||||
// Find the end of this path component.
|
||||
nextEnd := 1
|
||||
for nextEnd < len(nextPartialPathname) && nextPartialPathname[nextEnd] != pathSep {
|
||||
nextEnd++
|
||||
}
|
||||
return Iterator{
|
||||
partialPathname: nextPartialPathname,
|
||||
end: nextEnd,
|
||||
}
|
||||
}
|
||||
|
||||
// NextOk is equivalent to it.Next().Ok(), but is faster.
|
||||
//
|
||||
// Preconditions: it.Ok().
|
||||
func (it Iterator) NextOk() bool {
|
||||
return it.end != len(it.partialPathname)
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue