// Package ext provides wrappers around nonportable system interfaces. package ext import ( "encoding/json" "iter" "strconv" ) // checked in container/seccomp type ( // Uint is equivalent to C.uint. Uint = uint32 // Int is equivalent to C.int. Int = int32 ) // SyscallNum represents an architecture-specific, Linux syscall number. type SyscallNum Int // Syscalls returns an iterator over all wired syscalls. func Syscalls() iter.Seq2[string, SyscallNum] { return func(yield func(string, SyscallNum) bool) { for name, num := range syscallNum { if !yield(name, num) { return } } for name, num := range syscallNumExtra { if !yield(name, num) { return } } } } // SyscallResolveName resolves a syscall number from its string representation. func SyscallResolveName(name string) (num SyscallNum, ok bool) { if num, ok = syscallNum[name]; ok { return } num, ok = syscallNumExtra[name] return } // MarshalJSON resolves the name of [Syscall] and encodes it as a [json] string. // If such a name does not exist, the syscall number is encoded instead. func (num *SyscallNum) MarshalJSON() ([]byte, error) { n := *num for name, cur := range Syscalls() { if cur == n { return json.Marshal(name) } } return json.Marshal(n) } // SyscallNameError is returned when trying to unmarshal an invalid syscall name into [ScmpSyscall]. type SyscallNameError string func (e SyscallNameError) Error() string { return "invalid syscall name " + strconv.Quote(string(e)) } // UnmarshalJSON looks up the syscall number corresponding to name encoded in data // by calling [SyscallResolveName]. func (num *SyscallNum) UnmarshalJSON(data []byte) error { var name string if err := json.Unmarshal(data, &name); err != nil { return err } if n, ok := SyscallResolveName(name); !ok { return SyscallNameError(name) } else { *num = n return nil } }