From 57398862261d576ab90fb231996cfe5999ef2c59 Mon Sep 17 00:00:00 2001 From: Matt Layher Date: Mon, 7 Feb 2022 10:15:45 -0500 Subject: [PATCH] unix: implement alarm(2) on Linux on all GOARCH except arm* and riscv. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit SYS_ALARM is not defined for arm* or riscv, but is available for all other Linux GOARCH values. Ian suggested I create a new file with build tags matching these constraints. In order to handle special case files such as this one (which don't match the existing syscall_linux_goarch.go scheme), I've added logic to the Linux build system which can evaluate the build constraints in a given file to determine whether that file should be appended to the arguments for a given target. Change-Id: I0136534522a26a0ce495308f63953546ea6bb8e5 Reviewed-on: https://go-review.googlesource.com/c/sys/+/383734 TryBot-Result: Gopher Robot Reviewed-by: Ian Lance Taylor Trust: Daniel Martí --- unix/linux/mkall.go | 85 +++++++++++++++++++++++++++++++++- unix/syscall_linux.go | 1 - unix/syscall_linux_alarm.go | 14 ++++++ unix/zsyscall_linux_386.go | 13 +++++- unix/zsyscall_linux_amd64.go | 13 +++++- unix/zsyscall_linux_mips.go | 13 +++++- unix/zsyscall_linux_mips64.go | 13 +++++- unix/zsyscall_linux_mipsle.go | 13 +++++- unix/zsyscall_linux_ppc.go | 13 +++++- unix/zsyscall_linux_ppc64.go | 13 +++++- unix/zsyscall_linux_ppc64le.go | 13 +++++- unix/zsyscall_linux_s390x.go | 13 +++++- unix/zsyscall_linux_sparc64.go | 13 +++++- 13 files changed, 218 insertions(+), 12 deletions(-) create mode 100644 unix/syscall_linux_alarm.go diff --git a/unix/linux/mkall.go b/unix/linux/mkall.go index 7ea4de8d..fb015b12 100644 --- a/unix/linux/mkall.go +++ b/unix/linux/mkall.go @@ -22,6 +22,7 @@ import ( "encoding/binary" "errors" "fmt" + "go/build/constraint" "io" "io/ioutil" "os" @@ -510,10 +511,92 @@ func (t *target) makeZSyscallFile() error { } args := append(t.mksyscallFlags(), "-tags", "linux,"+t.GoArch, - "syscall_linux.go", archSyscallFile) + "syscall_linux.go", + archSyscallFile, + ) + + files, err := t.archMksyscallFiles() + if err != nil { + return fmt.Errorf("failed to check GOARCH-specific mksyscall files: %v", err) + } + args = append(args, files...) + return t.commandFormatOutput("gofmt", zsyscallFile, "mksyscall", args...) } +// archMksyscallFiles produces additional file arguments to mksyscall if the +// build constraints in those files match those defined for target. +func (t *target) archMksyscallFiles() ([]string, error) { + // These input files don't fit the typical GOOS/GOARCH file name conventions + // but are included conditionally in the arguments to mksyscall based on + // whether or not the target matches the build constraints defined in each + // file. + // + // TODO(mdlayher): it should be possible to generalize this approach to work + // over all of syscall_linux_* rather than hard-coding a few special files. + // Investigate this. + inputs := []string{ + // GOARCH: all except arm* and riscv. + "syscall_linux_alarm.go", + } + + var outputs []string + for _, in := range inputs { + ok, err := t.matchesMksyscallFile(in) + if err != nil { + return nil, fmt.Errorf("failed to parse file %q: %v", in, err) + } + if ok { + // Constraints match, use for this target's code generation. + outputs = append(outputs, in) + } + } + + return outputs, nil +} + +// matchesMksyscallFile reports whether the input file contains constraints +// which match those defined for target. +func (t *target) matchesMksyscallFile(file string) (bool, error) { + f, err := os.Open(file) + if err != nil { + return false, err + } + defer f.Close() + + var ( + expr constraint.Expr + found bool + ) + + s := bufio.NewScanner(f) + for s.Scan() { + // Keep scanning until a valid constraint is found or we hit EOF. + // + // This only supports single-line constraints such as the //go:build + // convention used in Go 1.17+. Because the old //+build convention + // (which may have multiple lines of build tags) is being deprecated, + // we don't bother looking for multi-line constraints. + if expr, err = constraint.Parse(s.Text()); err == nil { + found = true + break + } + } + if err := s.Err(); err != nil { + return false, err + } + if !found { + return false, errors.New("no build constraints found") + } + + // Do the defined constraints match target's GOOS/GOARCH? + ok := expr.Eval(func(tag string) bool { + return tag == GOOS || tag == t.GoArch + }) + + return ok, nil +} + // makes the zerrors_linux_$GOARCH.go file func (t *target) makeZErrorsFile() error { zerrorsFile := fmt.Sprintf("zerrors_linux_%s.go", t.GoArch) diff --git a/unix/syscall_linux.go b/unix/syscall_linux.go index f432b068..e52e8b9e 100644 --- a/unix/syscall_linux.go +++ b/unix/syscall_linux.go @@ -2318,7 +2318,6 @@ type RemoteIovec struct { * Unimplemented */ // AfsSyscall -// Alarm // ArchPrctl // Brk // ClockNanosleep diff --git a/unix/syscall_linux_alarm.go b/unix/syscall_linux_alarm.go new file mode 100644 index 00000000..08086ac6 --- /dev/null +++ b/unix/syscall_linux_alarm.go @@ -0,0 +1,14 @@ +// Copyright 2022 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +//go:build linux && (386 || amd64 || mips || mipsle || mips64 || mipsle || ppc64 || ppc64le || ppc || s390x || sparc64) +// +build linux +// +build 386 amd64 mips mipsle mips64 mipsle ppc64 ppc64le ppc s390x sparc64 + +package unix + +// SYS_ALARM is not defined on arm or riscv, but is available for other GOARCH +// values. + +//sys Alarm(seconds uint) (remaining uint, err error) diff --git a/unix/zsyscall_linux_386.go b/unix/zsyscall_linux_386.go index ff90c81e..2fc6271f 100644 --- a/unix/zsyscall_linux_386.go +++ b/unix/zsyscall_linux_386.go @@ -1,4 +1,4 @@ -// go run mksyscall.go -l32 -tags linux,386 syscall_linux.go syscall_linux_386.go +// go run mksyscall.go -l32 -tags linux,386 syscall_linux.go syscall_linux_386.go syscall_linux_alarm.go // Code generated by the command above; see README.md. DO NOT EDIT. //go:build linux && 386 @@ -524,3 +524,14 @@ func utimes(path string, times *[2]Timeval) (err error) { } return } + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Alarm(seconds uint) (remaining uint, err error) { + r0, _, e1 := Syscall(SYS_ALARM, uintptr(seconds), 0, 0) + remaining = uint(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} diff --git a/unix/zsyscall_linux_amd64.go b/unix/zsyscall_linux_amd64.go index fa7d3dbe..21fb8507 100644 --- a/unix/zsyscall_linux_amd64.go +++ b/unix/zsyscall_linux_amd64.go @@ -1,4 +1,4 @@ -// go run mksyscall.go -tags linux,amd64 syscall_linux.go syscall_linux_amd64.go +// go run mksyscall.go -tags linux,amd64 syscall_linux.go syscall_linux_amd64.go syscall_linux_alarm.go // Code generated by the command above; see README.md. DO NOT EDIT. //go:build linux && amd64 @@ -691,3 +691,14 @@ func kexecFileLoad(kernelFd int, initrdFd int, cmdlineLen int, cmdline string, f } return } + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Alarm(seconds uint) (remaining uint, err error) { + r0, _, e1 := Syscall(SYS_ALARM, uintptr(seconds), 0, 0) + remaining = uint(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} diff --git a/unix/zsyscall_linux_mips.go b/unix/zsyscall_linux_mips.go index 6d155288..eab7ab9a 100644 --- a/unix/zsyscall_linux_mips.go +++ b/unix/zsyscall_linux_mips.go @@ -1,4 +1,4 @@ -// go run mksyscall.go -b32 -arm -tags linux,mips syscall_linux.go syscall_linux_mipsx.go +// go run mksyscall.go -b32 -arm -tags linux,mips syscall_linux.go syscall_linux_mipsx.go syscall_linux_alarm.go // Code generated by the command above; see README.md. DO NOT EDIT. //go:build linux && mips @@ -702,3 +702,14 @@ func setrlimit(resource int, rlim *rlimit32) (err error) { } return } + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Alarm(seconds uint) (remaining uint, err error) { + r0, _, e1 := Syscall(SYS_ALARM, uintptr(seconds), 0, 0) + remaining = uint(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} diff --git a/unix/zsyscall_linux_mips64.go b/unix/zsyscall_linux_mips64.go index 1e20d72d..dc3f47f1 100644 --- a/unix/zsyscall_linux_mips64.go +++ b/unix/zsyscall_linux_mips64.go @@ -1,4 +1,4 @@ -// go run mksyscall.go -tags linux,mips64 syscall_linux.go syscall_linux_mips64x.go +// go run mksyscall.go -tags linux,mips64 syscall_linux.go syscall_linux_mips64x.go syscall_linux_alarm.go // Code generated by the command above; see README.md. DO NOT EDIT. //go:build linux && mips64 @@ -696,3 +696,14 @@ func stat(path string, st *stat_t) (err error) { } return } + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Alarm(seconds uint) (remaining uint, err error) { + r0, _, e1 := Syscall(SYS_ALARM, uintptr(seconds), 0, 0) + remaining = uint(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} diff --git a/unix/zsyscall_linux_mipsle.go b/unix/zsyscall_linux_mipsle.go index a0440c1d..691f3de4 100644 --- a/unix/zsyscall_linux_mipsle.go +++ b/unix/zsyscall_linux_mipsle.go @@ -1,4 +1,4 @@ -// go run mksyscall.go -l32 -arm -tags linux,mipsle syscall_linux.go syscall_linux_mipsx.go +// go run mksyscall.go -l32 -arm -tags linux,mipsle syscall_linux.go syscall_linux_mipsx.go syscall_linux_alarm.go // Code generated by the command above; see README.md. DO NOT EDIT. //go:build linux && mipsle @@ -702,3 +702,14 @@ func setrlimit(resource int, rlim *rlimit32) (err error) { } return } + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Alarm(seconds uint) (remaining uint, err error) { + r0, _, e1 := Syscall(SYS_ALARM, uintptr(seconds), 0, 0) + remaining = uint(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} diff --git a/unix/zsyscall_linux_ppc.go b/unix/zsyscall_linux_ppc.go index 5864b9ca..5ce957c5 100644 --- a/unix/zsyscall_linux_ppc.go +++ b/unix/zsyscall_linux_ppc.go @@ -1,4 +1,4 @@ -// go run mksyscall.go -b32 -tags linux,ppc syscall_linux.go syscall_linux_ppc.go +// go run mksyscall.go -b32 -tags linux,ppc syscall_linux.go syscall_linux_ppc.go syscall_linux_alarm.go // Code generated by the command above; see README.md. DO NOT EDIT. //go:build linux && ppc @@ -707,3 +707,14 @@ func kexecFileLoad(kernelFd int, initrdFd int, cmdlineLen int, cmdline string, f } return } + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Alarm(seconds uint) (remaining uint, err error) { + r0, _, e1 := Syscall(SYS_ALARM, uintptr(seconds), 0, 0) + remaining = uint(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} diff --git a/unix/zsyscall_linux_ppc64.go b/unix/zsyscall_linux_ppc64.go index beeb49e3..82c5b633 100644 --- a/unix/zsyscall_linux_ppc64.go +++ b/unix/zsyscall_linux_ppc64.go @@ -1,4 +1,4 @@ -// go run mksyscall.go -tags linux,ppc64 syscall_linux.go syscall_linux_ppc64x.go +// go run mksyscall.go -tags linux,ppc64 syscall_linux.go syscall_linux_ppc64x.go syscall_linux_alarm.go // Code generated by the command above; see README.md. DO NOT EDIT. //go:build linux && ppc64 @@ -753,3 +753,14 @@ func kexecFileLoad(kernelFd int, initrdFd int, cmdlineLen int, cmdline string, f } return } + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Alarm(seconds uint) (remaining uint, err error) { + r0, _, e1 := Syscall(SYS_ALARM, uintptr(seconds), 0, 0) + remaining = uint(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} diff --git a/unix/zsyscall_linux_ppc64le.go b/unix/zsyscall_linux_ppc64le.go index 53139b82..178847e3 100644 --- a/unix/zsyscall_linux_ppc64le.go +++ b/unix/zsyscall_linux_ppc64le.go @@ -1,4 +1,4 @@ -// go run mksyscall.go -tags linux,ppc64le syscall_linux.go syscall_linux_ppc64x.go +// go run mksyscall.go -tags linux,ppc64le syscall_linux.go syscall_linux_ppc64x.go syscall_linux_alarm.go // Code generated by the command above; see README.md. DO NOT EDIT. //go:build linux && ppc64le @@ -753,3 +753,14 @@ func kexecFileLoad(kernelFd int, initrdFd int, cmdlineLen int, cmdline string, f } return } + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Alarm(seconds uint) (remaining uint, err error) { + r0, _, e1 := Syscall(SYS_ALARM, uintptr(seconds), 0, 0) + remaining = uint(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} diff --git a/unix/zsyscall_linux_s390x.go b/unix/zsyscall_linux_s390x.go index 202add37..9e462a96 100644 --- a/unix/zsyscall_linux_s390x.go +++ b/unix/zsyscall_linux_s390x.go @@ -1,4 +1,4 @@ -// go run mksyscall.go -tags linux,s390x syscall_linux.go syscall_linux_s390x.go +// go run mksyscall.go -tags linux,s390x syscall_linux.go syscall_linux_s390x.go syscall_linux_alarm.go // Code generated by the command above; see README.md. DO NOT EDIT. //go:build linux && s390x @@ -533,3 +533,14 @@ func kexecFileLoad(kernelFd int, initrdFd int, cmdlineLen int, cmdline string, f } return } + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Alarm(seconds uint) (remaining uint, err error) { + r0, _, e1 := Syscall(SYS_ALARM, uintptr(seconds), 0, 0) + remaining = uint(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} diff --git a/unix/zsyscall_linux_sparc64.go b/unix/zsyscall_linux_sparc64.go index 2ab268c3..ea7d7c29 100644 --- a/unix/zsyscall_linux_sparc64.go +++ b/unix/zsyscall_linux_sparc64.go @@ -1,4 +1,4 @@ -// go run mksyscall.go -tags linux,sparc64 syscall_linux.go syscall_linux_sparc64.go +// go run mksyscall.go -tags linux,sparc64 syscall_linux.go syscall_linux_sparc64.go syscall_linux_alarm.go // Code generated by the command above; see README.md. DO NOT EDIT. //go:build linux && sparc64 @@ -697,3 +697,14 @@ func utimes(path string, times *[2]Timeval) (err error) { } return } + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Alarm(seconds uint) (remaining uint, err error) { + r0, _, e1 := Syscall(SYS_ALARM, uintptr(seconds), 0, 0) + remaining = uint(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +}