mirror of
https://github.com/rwinkhart/sys.git
synced 2026-08-28 04:46:44 -04:00
unix: implement alarm(2) on Linux on all GOARCH except arm* and riscv.
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 <gobot@golang.org> Reviewed-by: Ian Lance Taylor <iant@golang.org> Trust: Daniel Martí <mvdan@mvdan.cc>
This commit is contained in:
committed by
Ian Lance Taylor
parent
1c1b9b1eba
commit
5739886226
+84
-1
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user