all: apply modernisers
Test / Create distribution (push) Successful in 58s
Test / Sandbox (push) Successful in 2m48s
Test / ShareFS (push) Successful in 3m53s
Test / Hakurei (push) Successful in 4m0s
Test / Sandbox (race detector) (push) Successful in 5m37s
Test / Hakurei (race detector) (push) Successful in 6m40s
Test / Flake checks (push) Successful in 1m12s
Test / Create distribution (push) Successful in 58s
Test / Sandbox (push) Successful in 2m48s
Test / ShareFS (push) Successful in 3m53s
Test / Hakurei (push) Successful in 4m0s
Test / Sandbox (race detector) (push) Successful in 5m37s
Test / Hakurei (race detector) (push) Successful in 6m40s
Test / Flake checks (push) Successful in 1m12s
Signed-off-by: Ophestra <cat@gensokyo.uk>
This commit is contained in:
+2
-2
@@ -20,8 +20,8 @@ func (e AbsoluteError) Error() string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (e AbsoluteError) Is(target error) bool {
|
func (e AbsoluteError) Is(target error) bool {
|
||||||
var ce AbsoluteError
|
ce, ok := errors.AsType[AbsoluteError](target)
|
||||||
if !errors.As(target, &ce) {
|
if !ok {
|
||||||
return errors.Is(target, syscall.EINVAL)
|
return errors.Is(target, syscall.EINVAL)
|
||||||
}
|
}
|
||||||
return e == ce
|
return e == ce
|
||||||
|
|||||||
@@ -57,8 +57,8 @@ func dispatchModprobe(
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
var exitError *exec.ExitError
|
exitError, ok := errors.AsType[*exec.ExitError](err)
|
||||||
if !errors.As(err, &exitError) || exitError == nil {
|
if !ok || exitError == nil {
|
||||||
r.Dispatch(report.Degraded, "invoke modprobe", err)
|
r.Dispatch(report.Degraded, "invoke modprobe", err)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|||||||
+6
-5
@@ -7,7 +7,8 @@ import (
|
|||||||
"strconv"
|
"strconv"
|
||||||
)
|
)
|
||||||
|
|
||||||
// decodeJSON decodes json from r and stores it in v. A non-nil error results in a call to fatal.
|
// decodeJSON decodes json from r and stores it in v. A non-nil error results in
|
||||||
|
// a call to fatal.
|
||||||
func decodeJSON(fatal func(v ...any), op string, r io.Reader, v any) {
|
func decodeJSON(fatal func(v ...any), op string, r io.Reader, v any) {
|
||||||
err := json.NewDecoder(r).Decode(v)
|
err := json.NewDecoder(r).Decode(v)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
@@ -47,14 +48,14 @@ func encodeJSON(fatal func(v ...any), output io.Writer, short bool, v any) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if err := encoder.Encode(v); err != nil {
|
if err := encoder.Encode(v); err != nil {
|
||||||
var marshalerError *json.MarshalerError
|
if e, ok := errors.AsType[*json.MarshalerError](err); ok && e != nil {
|
||||||
if errors.As(err, &marshalerError) && marshalerError != nil {
|
|
||||||
// this likely indicates an implementation error in hst
|
// this likely indicates an implementation error in hst
|
||||||
fatal("cannot encode json for " + marshalerError.Type.String() + ": " + marshalerError.Err.Error())
|
fatal("cannot encode json for " + e.Type.String() + ": " + e.Err.Error())
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// UnsupportedTypeError, UnsupportedValueError: incorrect usage, does not need to be handled
|
// UnsupportedTypeError, UnsupportedValueError: incorrect usage, does
|
||||||
|
// not need to be handled
|
||||||
fatal("cannot write json: " + err.Error())
|
fatal("cannot write json: " + err.Error())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -74,7 +74,7 @@ func (s *searchCache) clean() {
|
|||||||
}
|
}
|
||||||
func indexsum(in [][]int) int {
|
func indexsum(in [][]int) int {
|
||||||
sum := 0
|
sum := 0
|
||||||
for i := 0; i < len(in); i++ {
|
for i := range in {
|
||||||
sum += in[i][1] - in[i][0]
|
sum += in[i][1] - in[i][0]
|
||||||
}
|
}
|
||||||
return sum
|
return sum
|
||||||
|
|||||||
+2
-2
@@ -508,8 +508,8 @@ func _main(s ...string) (exitCode int) {
|
|||||||
|
|
||||||
if !z.AllowOrphan {
|
if !z.AllowOrphan {
|
||||||
if err := z.Wait(); err != nil {
|
if err := z.Wait(); err != nil {
|
||||||
var exitError *exec.ExitError
|
exitError, ok := errors.AsType[*exec.ExitError](err)
|
||||||
if !errors.As(err, &exitError) || exitError == nil {
|
if !ok || exitError == nil {
|
||||||
log.Println(err)
|
log.Println(err)
|
||||||
return 5
|
return 5
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-2
@@ -91,8 +91,8 @@ func (n *node) MustParse(arguments []string, handleError func(error)) {
|
|||||||
case ErrEmptyTree:
|
case ErrEmptyTree:
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
default:
|
default:
|
||||||
var flagError FlagError
|
flagError, ok := errors.AsType[FlagError](err)
|
||||||
if !errors.As(err, &flagError) { // returned by HandlerFunc
|
if !ok { // returned by HandlerFunc
|
||||||
handleError(err)
|
handleError(err)
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -154,11 +154,8 @@ func (e *StartError) Error() string {
|
|||||||
return e.Step
|
return e.Step
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
if se, ok := errors.AsType[*os.SyscallError](e.Err); ok && se != nil {
|
||||||
var syscallError *os.SyscallError
|
return e.Step + " " + se.Error()
|
||||||
if errors.As(e.Err, &syscallError) && syscallError != nil {
|
|
||||||
return e.Step + " " + syscallError.Error()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return e.Step + ": " + e.Err.Error()
|
return e.Step + ": " + e.Err.Error()
|
||||||
|
|||||||
@@ -235,8 +235,6 @@ func checkOpBehaviour(t *testing.T, testCases []opBehaviourTestCase) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func sliceAddr[S any](s []S) *[]S { return &s }
|
|
||||||
|
|
||||||
func newCheckedFile(t *testing.T, name, wantData string, closeErr error) osFile {
|
func newCheckedFile(t *testing.T, name, wantData string, closeErr error) osFile {
|
||||||
f := &checkedOsFile{t: t, name: name, want: wantData, closeErr: closeErr}
|
f := &checkedOsFile{t: t, name: name, want: wantData, closeErr: closeErr}
|
||||||
// check happens in Close, and cleanup is not guaranteed to run, so relying
|
// check happens in Close, and cleanup is not guaranteed to run, so relying
|
||||||
|
|||||||
+6
-8
@@ -46,9 +46,8 @@ func messageFromError(err error) (m string, ok bool) {
|
|||||||
// While this is usable for pointer errors, such use should be avoided as nil
|
// While this is usable for pointer errors, such use should be avoided as nil
|
||||||
// check is omitted.
|
// check is omitted.
|
||||||
func messagePrefix[T error](prefix string, err error) (string, bool) {
|
func messagePrefix[T error](prefix string, err error) (string, bool) {
|
||||||
var targetError T
|
if e, ok := errors.AsType[T](err); ok {
|
||||||
if errors.As(err, &targetError) {
|
return prefix + e.Error(), true
|
||||||
return prefix + targetError.Error(), true
|
|
||||||
}
|
}
|
||||||
return zeroString, false
|
return zeroString, false
|
||||||
}
|
}
|
||||||
@@ -58,9 +57,8 @@ func messagePrefixP[V any, T interface {
|
|||||||
*V
|
*V
|
||||||
error
|
error
|
||||||
}](prefix string, err error) (string, bool) {
|
}](prefix string, err error) (string, bool) {
|
||||||
var targetError T
|
if e, ok := errors.AsType[T](err); ok && e != nil {
|
||||||
if errors.As(err, &targetError) && targetError != nil {
|
return prefix + e.Error(), true
|
||||||
return prefix + targetError.Error(), true
|
|
||||||
}
|
}
|
||||||
return zeroString, false
|
return zeroString, false
|
||||||
}
|
}
|
||||||
@@ -109,8 +107,8 @@ func optionalErrorUnwrap(err error) error {
|
|||||||
|
|
||||||
// errnoFallback returns the concrete errno from an error, or a [os.PathError] fallback.
|
// errnoFallback returns the concrete errno from an error, or a [os.PathError] fallback.
|
||||||
func errnoFallback(op, path string, err error) (syscall.Errno, *os.PathError) {
|
func errnoFallback(op, path string, err error) (syscall.Errno, *os.PathError) {
|
||||||
var errno syscall.Errno
|
errno, ok := errors.AsType[syscall.Errno](err)
|
||||||
if !errors.As(err, &errno) {
|
if !ok {
|
||||||
return 0, &os.PathError{Op: op, Path: path, Err: err}
|
return 0, &os.PathError{Op: op, Path: path, Err: err}
|
||||||
}
|
}
|
||||||
return errno, nil
|
return errno, nil
|
||||||
|
|||||||
@@ -95,7 +95,7 @@ func TestInitEntrypoint(t *testing.T) {
|
|||||||
Uid: 1 << 16,
|
Uid: 1 << 16,
|
||||||
Gid: 1 << 15,
|
Gid: 1 << 15,
|
||||||
Hostname: "hakurei-check",
|
Hostname: "hakurei-check",
|
||||||
Ops: (*Ops)(sliceAddr(make(Ops, 1))),
|
Ops: new(make(Ops, 1)),
|
||||||
SeccompRules: make([]std.NativeRule, 0),
|
SeccompRules: make([]std.NativeRule, 0),
|
||||||
SeccompPresets: std.PresetStrict,
|
SeccompPresets: std.PresetStrict,
|
||||||
RetainSession: true,
|
RetainSession: true,
|
||||||
@@ -123,7 +123,7 @@ func TestInitEntrypoint(t *testing.T) {
|
|||||||
Uid: 1 << 16,
|
Uid: 1 << 16,
|
||||||
Gid: 1 << 15,
|
Gid: 1 << 15,
|
||||||
Hostname: "hakurei-check",
|
Hostname: "hakurei-check",
|
||||||
Ops: (*Ops)(sliceAddr(make(Ops, 1))),
|
Ops: new(make(Ops, 1)),
|
||||||
SeccompRules: make([]std.NativeRule, 0),
|
SeccompRules: make([]std.NativeRule, 0),
|
||||||
SeccompPresets: std.PresetStrict,
|
SeccompPresets: std.PresetStrict,
|
||||||
RetainSession: true,
|
RetainSession: true,
|
||||||
@@ -152,7 +152,7 @@ func TestInitEntrypoint(t *testing.T) {
|
|||||||
Uid: 1 << 16,
|
Uid: 1 << 16,
|
||||||
Gid: 1 << 15,
|
Gid: 1 << 15,
|
||||||
Hostname: "hakurei-check",
|
Hostname: "hakurei-check",
|
||||||
Ops: (*Ops)(sliceAddr(make(Ops, 1))),
|
Ops: new(make(Ops, 1)),
|
||||||
SeccompRules: make([]std.NativeRule, 0),
|
SeccompRules: make([]std.NativeRule, 0),
|
||||||
SeccompPresets: std.PresetStrict,
|
SeccompPresets: std.PresetStrict,
|
||||||
RetainSession: true,
|
RetainSession: true,
|
||||||
@@ -182,7 +182,7 @@ func TestInitEntrypoint(t *testing.T) {
|
|||||||
Uid: 1 << 16,
|
Uid: 1 << 16,
|
||||||
Gid: 1 << 15,
|
Gid: 1 << 15,
|
||||||
Hostname: "hakurei-check",
|
Hostname: "hakurei-check",
|
||||||
Ops: (*Ops)(sliceAddr(make(Ops, 1))),
|
Ops: new(make(Ops, 1)),
|
||||||
SeccompRules: make([]std.NativeRule, 0),
|
SeccompRules: make([]std.NativeRule, 0),
|
||||||
SeccompPresets: std.PresetStrict,
|
SeccompPresets: std.PresetStrict,
|
||||||
RetainSession: true,
|
RetainSession: true,
|
||||||
@@ -213,7 +213,7 @@ func TestInitEntrypoint(t *testing.T) {
|
|||||||
Uid: 1 << 16,
|
Uid: 1 << 16,
|
||||||
Gid: 1 << 15,
|
Gid: 1 << 15,
|
||||||
Hostname: "hakurei-check",
|
Hostname: "hakurei-check",
|
||||||
Ops: (*Ops)(sliceAddr(make(Ops, 1))),
|
Ops: new(make(Ops, 1)),
|
||||||
SeccompRules: make([]std.NativeRule, 0),
|
SeccompRules: make([]std.NativeRule, 0),
|
||||||
SeccompPresets: std.PresetStrict,
|
SeccompPresets: std.PresetStrict,
|
||||||
RetainSession: true,
|
RetainSession: true,
|
||||||
@@ -245,7 +245,7 @@ func TestInitEntrypoint(t *testing.T) {
|
|||||||
Uid: 1 << 16,
|
Uid: 1 << 16,
|
||||||
Gid: 1 << 15,
|
Gid: 1 << 15,
|
||||||
Hostname: "hakurei-check",
|
Hostname: "hakurei-check",
|
||||||
Ops: (*Ops)(sliceAddr(make(Ops, 1))),
|
Ops: new(make(Ops, 1)),
|
||||||
SeccompRules: make([]std.NativeRule, 0),
|
SeccompRules: make([]std.NativeRule, 0),
|
||||||
SeccompPresets: std.PresetStrict,
|
SeccompPresets: std.PresetStrict,
|
||||||
RetainSession: true,
|
RetainSession: true,
|
||||||
@@ -279,7 +279,7 @@ func TestInitEntrypoint(t *testing.T) {
|
|||||||
Uid: 1 << 16,
|
Uid: 1 << 16,
|
||||||
Gid: 1 << 15,
|
Gid: 1 << 15,
|
||||||
Hostname: "hakurei-check",
|
Hostname: "hakurei-check",
|
||||||
Ops: (*Ops)(sliceAddr(make(Ops, 1))),
|
Ops: new(make(Ops, 1)),
|
||||||
SeccompRules: make([]std.NativeRule, 0),
|
SeccompRules: make([]std.NativeRule, 0),
|
||||||
SeccompPresets: std.PresetStrict,
|
SeccompPresets: std.PresetStrict,
|
||||||
RetainSession: true,
|
RetainSession: true,
|
||||||
@@ -315,7 +315,7 @@ func TestInitEntrypoint(t *testing.T) {
|
|||||||
Uid: 1 << 16,
|
Uid: 1 << 16,
|
||||||
Gid: 1 << 15,
|
Gid: 1 << 15,
|
||||||
Hostname: "hakurei-check",
|
Hostname: "hakurei-check",
|
||||||
Ops: (*Ops)(sliceAddr(make(Ops, 1))),
|
Ops: new(make(Ops, 1)),
|
||||||
SeccompRules: make([]std.NativeRule, 0),
|
SeccompRules: make([]std.NativeRule, 0),
|
||||||
SeccompPresets: std.PresetStrict,
|
SeccompPresets: std.PresetStrict,
|
||||||
RetainSession: true,
|
RetainSession: true,
|
||||||
|
|||||||
+1
-1
@@ -39,7 +39,7 @@ func TestSyscall(t *testing.T) {
|
|||||||
t.Errorf("Unmarshal: %v, want %v", got, tc.want)
|
t.Errorf("Unmarshal: %v, want %v", got, tc.want)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
if errors.As(tc.err, new(ext.SyscallNameError)) {
|
if _, ok := errors.AsType[ext.SyscallNameError](tc.err); ok {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
"reflect"
|
"reflect"
|
||||||
|
"strings"
|
||||||
|
|
||||||
"hakurei.app/check"
|
"hakurei.app/check"
|
||||||
)
|
)
|
||||||
@@ -78,17 +79,17 @@ type FSImplError struct{ Value FilesystemConfig }
|
|||||||
|
|
||||||
func (f FSImplError) Error() string {
|
func (f FSImplError) Error() string {
|
||||||
implType := reflect.TypeOf(f.Value)
|
implType := reflect.TypeOf(f.Value)
|
||||||
var name string
|
var buf strings.Builder
|
||||||
for implType != nil && implType.Kind() == reflect.Ptr {
|
for implType != nil && implType.Kind() == reflect.Pointer {
|
||||||
name += "*"
|
buf.WriteByte('*')
|
||||||
implType = implType.Elem()
|
implType = implType.Elem()
|
||||||
}
|
}
|
||||||
if implType != nil {
|
if implType != nil {
|
||||||
name += implType.Name()
|
buf.WriteString(implType.Name())
|
||||||
} else {
|
} else {
|
||||||
name += "nil"
|
buf.WriteString("nil")
|
||||||
}
|
}
|
||||||
return fmt.Sprintf("implementation %s not supported", name)
|
return "implementation " + buf.String() + " not supported"
|
||||||
}
|
}
|
||||||
|
|
||||||
// FilesystemConfigJSON is the [json] adapter for [FilesystemConfig].
|
// FilesystemConfigJSON is the [json] adapter for [FilesystemConfig].
|
||||||
|
|||||||
+2
-2
@@ -103,7 +103,7 @@ func TestFilesystemConfigJSON(t *testing.T) {
|
|||||||
t.Run("marshal", func(t *testing.T) {
|
t.Run("marshal", func(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
wantErr := tc.wantErr
|
wantErr := tc.wantErr
|
||||||
if errors.As(wantErr, new(hst.FSTypeError)) {
|
if _, ok := errors.AsType[hst.FSTypeError](wantErr); ok {
|
||||||
// for unsupported implementation tc
|
// for unsupported implementation tc
|
||||||
wantErr = hst.FSImplError{Value: stubFS{"cat"}}
|
wantErr = hst.FSImplError{Value: stubFS{"cat"}}
|
||||||
}
|
}
|
||||||
@@ -139,7 +139,7 @@ func TestFilesystemConfigJSON(t *testing.T) {
|
|||||||
t.Run("unmarshal", func(t *testing.T) {
|
t.Run("unmarshal", func(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
if tc.data == "\x00" && tc.sData == "\x00" {
|
if tc.data == "\x00" && tc.sData == "\x00" {
|
||||||
if errors.As(tc.wantErr, new(hst.FSImplError)) {
|
if _, ok := errors.AsType[hst.FSImplError](tc.wantErr); ok {
|
||||||
// this error is only returned on marshal
|
// this error is only returned on marshal
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-6
@@ -43,18 +43,13 @@ func (e *FSEphemeral) Apply(z *ApplyState) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
size := e.Size
|
|
||||||
if size < 0 {
|
|
||||||
size = 0
|
|
||||||
}
|
|
||||||
|
|
||||||
perm := e.Perm
|
perm := e.Perm
|
||||||
if perm == 0 {
|
if perm == 0 {
|
||||||
perm = fsEphemeralDefaultPerm
|
perm = fsEphemeralDefaultPerm
|
||||||
}
|
}
|
||||||
|
|
||||||
if e.Write {
|
if e.Write {
|
||||||
z.Tmpfs(e.Target, size, perm)
|
z.Tmpfs(e.Target, max(e.Size, 0), perm)
|
||||||
} else {
|
} else {
|
||||||
z.Readonly(e.Target, perm)
|
z.Readonly(e.Target, perm)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -80,7 +80,7 @@ func unescapeValue(v []byte) (val []byte, errno ParseError) {
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
if ib := bytes.IndexByte([]byte("-_/.\\*"), b); ib != -1 { // - // _/.\*
|
if found := bytes.Contains([]byte("-_/.\\*"), []byte{b}); found { // - // _/.\*
|
||||||
goto opt
|
goto opt
|
||||||
} else if b >= '0' && b <= '9' { // 0-9
|
} else if b >= '0' && b <= '9' { // 0-9
|
||||||
goto opt
|
goto opt
|
||||||
@@ -101,7 +101,7 @@ func unescapeValue(v []byte) (val []byte, errno ParseError) {
|
|||||||
break
|
break
|
||||||
}
|
}
|
||||||
if c, err := hex.Decode(val[i:i+1], v[iu+1:iu+3]); err != nil {
|
if c, err := hex.Decode(val[i:i+1], v[iu+1:iu+3]); err != nil {
|
||||||
if errors.As(err, new(hex.InvalidByteError)) {
|
if _, ok := errors.AsType[hex.InvalidByteError](err); ok {
|
||||||
errno = ErrBadValHexByte
|
errno = ErrBadValHexByte
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -40,7 +40,7 @@ func TestTransform(t *testing.T) {
|
|||||||
|
|
||||||
const maxChunkWords = 8 << 10
|
const maxChunkWords = 8 << 10
|
||||||
buf := make([]byte, 2*maxChunkWords*8)
|
buf := make([]byte, 2*maxChunkWords*8)
|
||||||
for i := uint64(0); i < 2*maxChunkWords; i++ {
|
for i := range uint64(2 * maxChunkWords) {
|
||||||
binary.LittleEndian.PutUint64(buf[i*8:], i)
|
binary.LittleEndian.PutUint64(buf[i*8:], i)
|
||||||
}
|
}
|
||||||
if err := lockedfile.Write(path, bytes.NewReader(buf[:8]), 0666); err != nil {
|
if err := lockedfile.Write(path, bytes.NewReader(buf[:8]), 0666); err != nil {
|
||||||
|
|||||||
@@ -58,8 +58,7 @@ func (k *outcome) finalise(
|
|||||||
supp := make([]string, len(config.Groups))
|
supp := make([]string, len(config.Groups))
|
||||||
for i, name := range config.Groups {
|
for i, name := range config.Groups {
|
||||||
if gid, err := k.lookupGroupId(name); err != nil {
|
if gid, err := k.lookupGroupId(name); err != nil {
|
||||||
var unknownGroupError user.UnknownGroupError
|
if unknownGroupError, ok := errors.AsType[user.UnknownGroupError](err); ok {
|
||||||
if errors.As(err, &unknownGroupError) {
|
|
||||||
return newWithMessageError(fmt.Sprintf("unknown group %q", name), unknownGroupError)
|
return newWithMessageError(fmt.Sprintf("unknown group %q", name), unknownGroupError)
|
||||||
} else {
|
} else {
|
||||||
return &hst.AppError{Step: "look up group by name", Err: err, Msg: err.Error()}
|
return &hst.AppError{Step: "look up group by name", Err: err, Msg: err.Error()}
|
||||||
|
|||||||
@@ -51,18 +51,16 @@ func (h *Hsu) ID() (int, error) {
|
|||||||
cmd.Stderr = os.Stderr // pass through fatal messages
|
cmd.Stderr = os.Stderr // pass through fatal messages
|
||||||
cmd.Env = make([]string, 0)
|
cmd.Env = make([]string, 0)
|
||||||
cmd.Dir = fhs.Root
|
cmd.Dir = fhs.Root
|
||||||
var (
|
var p []byte
|
||||||
p []byte
|
|
||||||
exitError *exec.ExitError
|
|
||||||
)
|
|
||||||
|
|
||||||
const step = "obtain uid from hsu"
|
const step = "obtain uid from hsu"
|
||||||
if p, h.idErr = h.k.cmdOutput(cmd); h.idErr == nil {
|
if p, h.idErr = h.k.cmdOutput(cmd); h.idErr == nil {
|
||||||
h.id, h.idErr = strconv.Atoi(string(p))
|
h.id, h.idErr = strconv.Atoi(string(p))
|
||||||
if h.idErr != nil {
|
if h.idErr != nil {
|
||||||
h.idErr = &hst.AppError{Step: step, Err: h.idErr, Msg: "invalid uid string from hsu"}
|
h.idErr = &hst.AppError{Step: step, Err: h.idErr, Msg: "invalid uid string from hsu"}
|
||||||
}
|
}
|
||||||
} else if errors.As(h.idErr, &exitError) && exitError != nil && exitError.ExitCode() == 1 {
|
} else if exitError, ok := errors.AsType[*exec.ExitError](h.idErr); ok &&
|
||||||
|
exitError != nil &&
|
||||||
|
exitError.ExitCode() == 1 {
|
||||||
// hsu prints an error message in this case
|
// hsu prints an error message in this case
|
||||||
h.idErr = &hst.AppError{Step: step, Err: ErrHsuAccess}
|
h.idErr = &hst.AppError{Step: step, Err: ErrHsuAccess}
|
||||||
} else if errors.Is(h.idErr, os.ErrNotExist) {
|
} else if errors.Is(h.idErr, os.ErrNotExist) {
|
||||||
|
|||||||
@@ -328,11 +328,11 @@ func (k *outcome) main(msg message.Msg, identifierFd int) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if err := k.sys.Revert((*system.Criteria)(&ec)); err != nil {
|
if err := k.sys.Revert((*system.Criteria)(&ec)); err != nil {
|
||||||
var joinError interface {
|
joinError, ok := errors.AsType[interface {
|
||||||
Unwrap() []error
|
Unwrap() []error
|
||||||
error
|
error
|
||||||
}
|
}](err)
|
||||||
if !errors.As(err, &joinError) || joinError == nil {
|
if !ok || joinError == nil {
|
||||||
perror(err, "revert system setup")
|
perror(err, "revert system setup")
|
||||||
} else {
|
} else {
|
||||||
for _, v := range joinError.Unwrap() {
|
for _, v := range joinError.Unwrap() {
|
||||||
|
|||||||
@@ -390,8 +390,8 @@ func shimEntrypoint(k syscallDispatcher) {
|
|||||||
if err := k.containerWait(z); err != nil {
|
if err := k.containerWait(z); err != nil {
|
||||||
sp.destroy()
|
sp.destroy()
|
||||||
|
|
||||||
var exitError *exec.ExitError
|
exitError, ok := errors.AsType[*exec.ExitError](err)
|
||||||
if !errors.As(err, &exitError) {
|
if !ok {
|
||||||
if errors.Is(err, context.Canceled) {
|
if errors.Is(err, context.Canceled) {
|
||||||
k.exit(hst.ExitCancel)
|
k.exit(hst.ExitCancel)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -176,8 +176,8 @@ func marshalValueAppendRaw(data []byte, v reflect.Value) ([]byte, error) {
|
|||||||
case reflect.Struct:
|
case reflect.Struct:
|
||||||
data = SPA_TYPE_Struct.append(data)
|
data = SPA_TYPE_Struct.append(data)
|
||||||
var err error
|
var err error
|
||||||
for i := 0; i < v.NumField(); i++ {
|
for _, field := range v.Fields() {
|
||||||
data, err = marshalValueAppend(data, v.Field(i))
|
data, err = marshalValueAppend(data, field)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return data, err
|
return data, err
|
||||||
}
|
}
|
||||||
@@ -370,8 +370,8 @@ func unmarshalValue(data []byte, v reflect.Value, wireSizeP *Word) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var fieldWireSize Word
|
var fieldWireSize Word
|
||||||
for i := 0; i < v.NumField(); i++ {
|
for _, field := range v.Fields() {
|
||||||
if err := unmarshalValue(data, v.Field(i), &fieldWireSize); err != nil {
|
if err := unmarshalValue(data, field, &fieldWireSize); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
// bounds check completed in successful call to unmarshalValue
|
// bounds check completed in successful call to unmarshalValue
|
||||||
|
|||||||
+21
-15
@@ -238,8 +238,8 @@ func (t *TContext) destroy(errP *error) {
|
|||||||
if chmodErr != nil || removeErr != nil {
|
if chmodErr != nil || removeErr != nil {
|
||||||
*errP = errors.Join(*errP, chmodErr, removeErr)
|
*errP = errors.Join(*errP, chmodErr, removeErr)
|
||||||
} else if errors.Is(*errP, os.ErrExist) {
|
} else if errors.Is(*errP, os.ErrExist) {
|
||||||
var linkError *os.LinkError
|
if linkError, ok := errors.AsType[*os.LinkError](*errP); ok &&
|
||||||
if errors.As(*errP, &linkError) && linkError != nil &&
|
linkError != nil &&
|
||||||
linkError.Op == "rename" {
|
linkError.Op == "rename" {
|
||||||
// two artifacts may be backed by the same file
|
// two artifacts may be backed by the same file
|
||||||
*errP = nil
|
*errP = nil
|
||||||
@@ -974,36 +974,42 @@ func (e *ScrubError) Unwrap() []error {
|
|||||||
// Error returns a multi-line representation of [ScrubError].
|
// Error returns a multi-line representation of [ScrubError].
|
||||||
func (e *ScrubError) Error() string {
|
func (e *ScrubError) Error() string {
|
||||||
var segments []string
|
var segments []string
|
||||||
|
var buf strings.Builder
|
||||||
|
|
||||||
if len(e.ChecksumMismatches) > 0 {
|
if len(e.ChecksumMismatches) > 0 {
|
||||||
s := "checksum mismatches:\n"
|
buf.Reset()
|
||||||
|
buf.WriteString("checksum mismatches:\n")
|
||||||
for _, m := range e.ChecksumMismatches {
|
for _, m := range e.ChecksumMismatches {
|
||||||
s += m.Error() + "\n"
|
buf.WriteString(m.Error() + "\n")
|
||||||
}
|
}
|
||||||
segments = append(segments, s)
|
segments = append(segments, buf.String())
|
||||||
}
|
}
|
||||||
if len(e.DanglingIdentifiers) > 0 {
|
if len(e.DanglingIdentifiers) > 0 {
|
||||||
s := "dangling identifiers:\n"
|
buf.Reset()
|
||||||
|
buf.WriteString("dangling identifiers:\n")
|
||||||
for _, id := range e.DanglingIdentifiers {
|
for _, id := range e.DanglingIdentifiers {
|
||||||
s += Encode(id) + "\n"
|
buf.WriteString(Encode(id) + "\n")
|
||||||
}
|
}
|
||||||
segments = append(segments, s)
|
segments = append(segments, buf.String())
|
||||||
}
|
}
|
||||||
if len(e.DanglingStatus) > 0 {
|
if len(e.DanglingStatus) > 0 {
|
||||||
s := "dangling status:\n"
|
buf.Reset()
|
||||||
|
buf.WriteString("dangling status:\n")
|
||||||
for _, id := range e.DanglingStatus {
|
for _, id := range e.DanglingStatus {
|
||||||
s += Encode(id) + "\n"
|
buf.WriteString(Encode(id) + "\n")
|
||||||
}
|
}
|
||||||
segments = append(segments, s)
|
segments = append(segments, buf.String())
|
||||||
}
|
}
|
||||||
if len(e.Errs) > 0 {
|
if len(e.Errs) > 0 {
|
||||||
s := "errors during scrub:\n"
|
buf.Reset()
|
||||||
|
buf.WriteString("errors during scrub:\n")
|
||||||
for pathname, errs := range e.errs {
|
for pathname, errs := range e.errs {
|
||||||
s += " " + pathname.Value() + ":\n"
|
buf.WriteString(" " + pathname.Value() + ":\n")
|
||||||
for _, err := range errs {
|
for _, err := range errs {
|
||||||
s += " " + err.Error() + "\n"
|
buf.WriteString(" " + err.Error() + "\n")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
segments = append(segments, s)
|
segments = append(segments, buf.String())
|
||||||
}
|
}
|
||||||
return strings.Join(segments, "\n")
|
return strings.Join(segments, "\n")
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -102,8 +102,7 @@ func (e Error) MarshalJSON() (data []byte, err error) {
|
|||||||
v.Severity = e.Severity
|
v.Severity = e.Severity
|
||||||
}
|
}
|
||||||
|
|
||||||
var re RepresentableError
|
if re, ok := errors.AsType[RepresentableError](e.Err); ok {
|
||||||
if errors.As(e.Err, &re) {
|
|
||||||
v.Err, err = json.Marshal(re)
|
v.Err, err = json.Marshal(re)
|
||||||
} else {
|
} else {
|
||||||
v.Err, err = json.Marshal(e.Err.Error())
|
v.Err, err = json.Marshal(e.Err.Error())
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import (
|
|||||||
"maps"
|
"maps"
|
||||||
"reflect"
|
"reflect"
|
||||||
"slices"
|
"slices"
|
||||||
|
"strings"
|
||||||
"unique"
|
"unique"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -107,8 +108,8 @@ func (e TypeError) Error() string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (e TypeError) Is(err error) bool {
|
func (e TypeError) Is(err error) bool {
|
||||||
var v TypeError
|
v, ok := errors.AsType[TypeError](err)
|
||||||
return errors.As(err, &v) &&
|
return ok &&
|
||||||
e.Asserted == v.Asserted &&
|
e.Asserted == v.Asserted &&
|
||||||
e.Concrete == v.Concrete
|
e.Concrete == v.Concrete
|
||||||
}
|
}
|
||||||
@@ -233,14 +234,14 @@ func evaluateAny(d PF, s []Frame, expr, rp any) bool {
|
|||||||
return evaluateAny(d, s, e[0], rp)
|
return evaluateAny(d, s, e[0], rp)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
var v string
|
var v strings.Builder
|
||||||
for i := range e {
|
for i := range e {
|
||||||
var _r string
|
var _r string
|
||||||
if evaluate(d, s, e[i], &_r) {
|
if evaluate(d, s, e[i], &_r) {
|
||||||
v += _r
|
v.WriteString(_r)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
store(rp, v)
|
store(rp, v.String())
|
||||||
return true
|
return true
|
||||||
|
|
||||||
case Array:
|
case Array:
|
||||||
|
|||||||
@@ -214,7 +214,7 @@ func TestEvaluate(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var errEquals bool
|
var errEquals bool
|
||||||
if errors.As(err, new(TypeError)) {
|
if _, ok := errors.AsType[TypeError](err); ok {
|
||||||
errEquals = errors.Is(err, tc.err)
|
errEquals = errors.Is(err, tc.err)
|
||||||
} else {
|
} else {
|
||||||
errEquals = reflect.DeepEqual(err, tc.err)
|
errEquals = reflect.DeepEqual(err, tc.err)
|
||||||
|
|||||||
@@ -212,11 +212,10 @@ func (r *Report) HandleAccess(errP *error) func() {
|
|||||||
*errP = err
|
*errP = err
|
||||||
}
|
}
|
||||||
|
|
||||||
var runtimeError interface {
|
if runtimeError, ok := errors.AsType[interface {
|
||||||
Addr() uintptr
|
Addr() uintptr
|
||||||
runtime.Error
|
runtime.Error
|
||||||
}
|
}](*errP); ok {
|
||||||
if errors.As(*errP, &runtimeError) {
|
|
||||||
offset := int(runtimeError.Addr() - uintptr(unsafe.Pointer(unsafe.SliceData(r.data))))
|
offset := int(runtimeError.Addr() - uintptr(unsafe.Pointer(unsafe.SliceData(r.data))))
|
||||||
// best effort for fragile uintptr
|
// best effort for fragile uintptr
|
||||||
if offset >= 0 {
|
if offset >= 0 {
|
||||||
|
|||||||
@@ -1063,7 +1063,7 @@ func (ctx *evalContext) pf(
|
|||||||
checksum, ok := kc.(string)
|
checksum, ok := kc.(string)
|
||||||
if !ok {
|
if !ok {
|
||||||
err = azalea.TypeError{
|
err = azalea.TypeError{
|
||||||
Concrete: reflect.TypeOf(checksum),
|
Concrete: reflect.TypeOf(kc),
|
||||||
Asserted: reflect.TypeFor[string](),
|
Asserted: reflect.TypeFor[string](),
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ func TestStoreBigLock(t *testing.T) {
|
|||||||
|
|
||||||
{
|
{
|
||||||
s := store.New(check.MustAbs(t.TempDir()).Append("state"))
|
s := store.New(check.MustAbs(t.TempDir()).Append("state"))
|
||||||
for i := 0; i < 2; i++ { // check once behaviour
|
for range 2 { // check once behaviour
|
||||||
if unlock, err := bigLock(s); err != nil {
|
if unlock, err := bigLock(s); err != nil {
|
||||||
t.Fatalf("bigLock: error = %v", err)
|
t.Fatalf("bigLock: error = %v", err)
|
||||||
} else {
|
} else {
|
||||||
@@ -43,7 +43,7 @@ func TestStoreBigLock(t *testing.T) {
|
|||||||
|
|
||||||
wantErr := &hst.AppError{Step: "create state store directory",
|
wantErr := &hst.AppError{Step: "create state store directory",
|
||||||
Err: &os.PathError{Op: "mkdir", Path: "/proc/nonexistent", Err: syscall.ENOENT}}
|
Err: &os.PathError{Op: "mkdir", Path: "/proc/nonexistent", Err: syscall.ENOENT}}
|
||||||
for i := 0; i < 2; i++ { // check once behaviour
|
for range 2 { // check once behaviour
|
||||||
if _, err := bigLock(store.New(check.MustAbs("/proc/nonexistent"))); !reflect.DeepEqual(err, wantErr) {
|
if _, err := bigLock(store.New(check.MustAbs("/proc/nonexistent"))); !reflect.DeepEqual(err, wantErr) {
|
||||||
t.Errorf("bigLock: error = %#v, want %#v", err, wantErr)
|
t.Errorf("bigLock: error = %#v, want %#v", err, wantErr)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,9 +20,6 @@ func (e UniqueError) Error() string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (e UniqueError) Is(target error) bool {
|
func (e UniqueError) Is(target error) bool {
|
||||||
var u UniqueError
|
u, ok := errors.AsType[UniqueError](target)
|
||||||
if !errors.As(target, &u) {
|
return ok && e == u
|
||||||
return false
|
|
||||||
}
|
|
||||||
return e == u
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -172,12 +172,12 @@ func (s *linePrefixWriter) write(p []byte, a int) (int, error) {
|
|||||||
return a, syscall.ENOMEM
|
return a, syscall.ENOMEM
|
||||||
}
|
}
|
||||||
|
|
||||||
if i := bytes.IndexByte(p, '\n'); i == -1 {
|
if before, after, ok := bytes.Cut(p, []byte{'\n'}); !ok {
|
||||||
n, _ := s.buf.Write(p)
|
n, _ := s.buf.Write(p)
|
||||||
s.n += n
|
s.n += n
|
||||||
return a + n, nil
|
return a + n, nil
|
||||||
} else {
|
} else {
|
||||||
n, _ := s.buf.Write(p[:i])
|
n, _ := s.buf.Write(before)
|
||||||
s.n += n + 1
|
s.n += n + 1
|
||||||
|
|
||||||
v := s.buf.String()
|
v := s.buf.String()
|
||||||
@@ -190,7 +190,7 @@ func (s *linePrefixWriter) write(p []byte, a int) (int, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
s.buf.Reset()
|
s.buf.Reset()
|
||||||
return s.write(p[i+1:], a+n+1)
|
return s.write(after, a+n+1)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -130,13 +130,11 @@ func (e *Error) Error() string {
|
|||||||
return e.withPrefix("cannot connect to " + e.Host)
|
return e.withPrefix("cannot connect to " + e.Host)
|
||||||
|
|
||||||
case RCleanup:
|
case RCleanup:
|
||||||
var pathError *os.PathError
|
if pathError, ok := errors.AsType[*os.PathError](e.Errno); ok && pathError != nil {
|
||||||
if errors.As(e.Errno, &pathError) && pathError != nil {
|
|
||||||
return pathError.Error()
|
return pathError.Error()
|
||||||
}
|
}
|
||||||
|
|
||||||
var errno syscall.Errno
|
if errno, ok := errors.AsType[syscall.Errno](e.Errno); ok && errno != 0 {
|
||||||
if errors.As(e.Errno, &errno) && errno != 0 {
|
|
||||||
return "cannot close wayland close_fd pipe: " + errno.Error()
|
return "cannot close wayland close_fd pipe: " + errno.Error()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+2
-2
@@ -20,8 +20,8 @@ func TestExec(t *testing.T) {
|
|||||||
|
|
||||||
_, err := ldd.Resolve(t.Context(), nil, check.MustAbs("/proc/nonexistent"))
|
_, err := ldd.Resolve(t.Context(), nil, check.MustAbs("/proc/nonexistent"))
|
||||||
|
|
||||||
var exitError *exec.ExitError
|
exitError, ok := errors.AsType[*exec.ExitError](err)
|
||||||
if !errors.As(err, &exitError) {
|
if !ok {
|
||||||
t.Fatalf("Exec: error has incorrect concrete type: %#v", err)
|
t.Fatalf("Exec: error has incorrect concrete type: %#v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+35
-17
@@ -1,4 +1,5 @@
|
|||||||
// Package message provides interfaces and a base implementation for extended reporting on top of [log.Logger]
|
// Package message provides interfaces and a base implementation for extended
|
||||||
|
// reporting on top of [log.Logger]
|
||||||
package message
|
package message
|
||||||
|
|
||||||
import (
|
import (
|
||||||
@@ -15,10 +16,11 @@ type Error interface {
|
|||||||
error
|
error
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetMessage returns whether an error implements [Error], and the message if it does.
|
// GetMessage returns whether an error implements [Error], and the message if
|
||||||
|
// it does.
|
||||||
func GetMessage(err error) (string, bool) {
|
func GetMessage(err error) (string, bool) {
|
||||||
var e Error
|
e, ok := errors.AsType[Error](err)
|
||||||
if !errors.As(err, &e) || e == nil {
|
if !ok || e == nil {
|
||||||
return "", false
|
return "", false
|
||||||
}
|
}
|
||||||
return e.Message(), true
|
return e.Message(), true
|
||||||
@@ -29,30 +31,43 @@ type Msg interface {
|
|||||||
// GetLogger returns the address of the underlying [log.Logger].
|
// GetLogger returns the address of the underlying [log.Logger].
|
||||||
GetLogger() *log.Logger
|
GetLogger() *log.Logger
|
||||||
|
|
||||||
// IsVerbose atomically loads and returns whether [Msg] has verbose logging enabled.
|
// IsVerbose atomically loads and returns whether [Msg] has verbose logging
|
||||||
|
// enabled.
|
||||||
IsVerbose() bool
|
IsVerbose() bool
|
||||||
// SwapVerbose atomically stores a new verbose state and returns the previous value held by [Msg].
|
// SwapVerbose atomically stores a new verbose state and returns the
|
||||||
|
// previous value held by [Msg].
|
||||||
SwapVerbose(verbose bool) bool
|
SwapVerbose(verbose bool) bool
|
||||||
// Verbose passes its argument to the Println method of the underlying [log.Logger] if IsVerbose returns true.
|
// Verbose passes its argument to the Println method of the underlying
|
||||||
|
// [log.Logger] if IsVerbose returns true.
|
||||||
Verbose(v ...any)
|
Verbose(v ...any)
|
||||||
// Verbosef passes its argument to the Printf method of the underlying [log.Logger] if IsVerbose returns true.
|
// Verbosef passes its argument to the Printf method of the underlying
|
||||||
|
// [log.Logger] if IsVerbose returns true.
|
||||||
Verbosef(format string, v ...any)
|
Verbosef(format string, v ...any)
|
||||||
|
|
||||||
// Suspend causes the embedded [Suspendable] to withhold writes to its downstream [io.Writer].
|
// Suspend causes the embedded [Suspendable] to withhold writes to its
|
||||||
// Suspend returns false and is a noop if called between calls to Suspend and Resume.
|
// downstream [io.Writer].
|
||||||
|
//
|
||||||
|
// Suspend returns false and is a noop if called between calls to Suspend
|
||||||
|
// and Resume.
|
||||||
Suspend() bool
|
Suspend() bool
|
||||||
|
|
||||||
// Resume dumps the entire buffer held by the embedded [Suspendable] and stops withholding future writes.
|
// Resume dumps the entire buffer held by the embedded [Suspendable] and
|
||||||
|
// stops withholding future writes.
|
||||||
|
//
|
||||||
// Resume returns false and is a noop if a call to Suspend does not precede it.
|
// Resume returns false and is a noop if a call to Suspend does not precede it.
|
||||||
Resume() bool
|
Resume() bool
|
||||||
|
|
||||||
// BeforeExit runs implementation-specific cleanup code, and optionally prints warnings.
|
// BeforeExit runs implementation-specific cleanup code, and optionally
|
||||||
|
// prints warnings.
|
||||||
|
//
|
||||||
// BeforeExit is called before [os.Exit].
|
// BeforeExit is called before [os.Exit].
|
||||||
BeforeExit()
|
BeforeExit()
|
||||||
}
|
}
|
||||||
|
|
||||||
// defaultMsg is the default implementation of the [Msg] interface.
|
// defaultMsg is the default implementation of the [Msg] interface.
|
||||||
// The zero value is not safe for use. Callers should use the [New] function instead.
|
//
|
||||||
|
// The zero value is not safe for use. Callers should use the [New] function
|
||||||
|
// instead.
|
||||||
type defaultMsg struct {
|
type defaultMsg struct {
|
||||||
verbose atomic.Bool
|
verbose atomic.Bool
|
||||||
|
|
||||||
@@ -61,8 +76,9 @@ type defaultMsg struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// New initialises a downstream [log.Logger] for a new [Msg].
|
// New initialises a downstream [log.Logger] for a new [Msg].
|
||||||
// The [log.Logger] should no longer be configured after [New] returns.
|
//
|
||||||
// If downstream is nil, a new logger is initialised in its place.
|
// The [log.Logger] should no longer be configured after [New] returns. If
|
||||||
|
// downstream is nil, a new logger is initialised in its place.
|
||||||
func New(downstream *log.Logger) Msg {
|
func New(downstream *log.Logger) Msg {
|
||||||
if downstream == nil {
|
if downstream == nil {
|
||||||
downstream = log.New(log.Writer(), "container: ", 0)
|
downstream = log.New(log.Writer(), "container: ", 0)
|
||||||
@@ -94,7 +110,8 @@ func (msg *defaultMsg) Verbosef(format string, v ...any) {
|
|||||||
func (msg *defaultMsg) Resume() bool {
|
func (msg *defaultMsg) Resume() bool {
|
||||||
resumed, dropped, _, err := msg.Suspendable.Resume()
|
resumed, dropped, _, err := msg.Suspendable.Resume()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
// probably going to result in an error as well, so this message is as good as unreachable
|
// probably going to result in an error as well, so this message is as
|
||||||
|
// good as unreachable
|
||||||
msg.logger.Printf("cannot dump buffer on resume: %v", err)
|
msg.logger.Printf("cannot dump buffer on resume: %v", err)
|
||||||
}
|
}
|
||||||
if resumed && dropped > 0 {
|
if resumed && dropped > 0 {
|
||||||
@@ -103,7 +120,8 @@ func (msg *defaultMsg) Resume() bool {
|
|||||||
return resumed
|
return resumed
|
||||||
}
|
}
|
||||||
|
|
||||||
// BeforeExit prints a message if called between calls to [Suspendable.Suspend] and Resume.
|
// BeforeExit prints a message if called between calls to [Suspendable.Suspend]
|
||||||
|
// and Resume.
|
||||||
func (msg *defaultMsg) BeforeExit() {
|
func (msg *defaultMsg) BeforeExit() {
|
||||||
if msg.Resume() {
|
if msg.Resume() {
|
||||||
msg.logger.Printf("beforeExit reached on suspended output")
|
msg.logger.Printf("beforeExit reached on suspended output")
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
//go:build testtool
|
//go:build testtool
|
||||||
|
|
||||||
/*
|
// Package sandbox provides utilities for checking sandbox outcome.
|
||||||
Package sandbox provides utilities for checking sandbox outcome.
|
//
|
||||||
|
// This package must never be used outside integration tests, there is a much
|
||||||
This package must never be used outside integration tests, there is a much better native implementation of mountinfo
|
// better native implementation of mountinfo in the public sandbox/vfs package.
|
||||||
in the public sandbox/vfs package. Files in this package are excluded by the build system to prevent accidental misuse.
|
// Files in this package are excluded by the build system to prevent accidental
|
||||||
*/
|
// misuse.
|
||||||
package sandbox
|
package sandbox
|
||||||
|
|
||||||
import (
|
import (
|
||||||
@@ -204,8 +204,8 @@ func MustCheckFilter(pid int, want string) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
var perr *ptraceError
|
perr, ok := errors.AsType[*ptraceError](err)
|
||||||
if !errors.As(err, &perr) {
|
if !ok {
|
||||||
fatalf("%s", err)
|
fatalf("%s", err)
|
||||||
}
|
}
|
||||||
switch perr.op {
|
switch perr.op {
|
||||||
|
|||||||
+1
-1
@@ -103,7 +103,7 @@ type (
|
|||||||
|
|
||||||
// Flags interprets VfsOptstr and returns the resulting flags and unmatched options.
|
// Flags interprets VfsOptstr and returns the resulting flags and unmatched options.
|
||||||
func (e *MountInfoEntry) Flags() (flags uintptr, unmatched []string) {
|
func (e *MountInfoEntry) Flags() (flags uintptr, unmatched []string) {
|
||||||
for _, s := range strings.Split(e.VfsOptstr, ",") {
|
for s := range strings.SplitSeq(e.VfsOptstr, ",") {
|
||||||
switch s {
|
switch s {
|
||||||
case "rw":
|
case "rw":
|
||||||
case "ro":
|
case "ro":
|
||||||
|
|||||||
Reference in New Issue
Block a user