|
Packit Service |
4d2de5 |
// Copyright 2018 The Go Authors. All rights reserved.
|
|
Packit Service |
4d2de5 |
// Use of this source code is governed by a BSD-style
|
|
Packit Service |
4d2de5 |
// license that can be found in the LICENSE file.
|
|
Packit Service |
4d2de5 |
|
|
Packit Service |
4d2de5 |
// +build ignore
|
|
Packit Service |
4d2de5 |
|
|
Packit Service |
4d2de5 |
// Generate system call table for DragonFly, NetBSD,
|
|
Packit Service |
4d2de5 |
// FreeBSD, OpenBSD or Darwin from master list
|
|
Packit Service |
4d2de5 |
// (for example, /usr/src/sys/kern/syscalls.master or
|
|
Packit Service |
4d2de5 |
// sys/syscall.h).
|
|
Packit Service |
4d2de5 |
package main
|
|
Packit Service |
4d2de5 |
|
|
Packit Service |
4d2de5 |
import (
|
|
Packit Service |
4d2de5 |
"bufio"
|
|
Packit Service |
4d2de5 |
"fmt"
|
|
Packit Service |
4d2de5 |
"io"
|
|
Packit Service |
4d2de5 |
"io/ioutil"
|
|
Packit Service |
4d2de5 |
"net/http"
|
|
Packit Service |
4d2de5 |
"os"
|
|
Packit Service |
4d2de5 |
"regexp"
|
|
Packit Service |
4d2de5 |
"strings"
|
|
Packit Service |
4d2de5 |
)
|
|
Packit Service |
4d2de5 |
|
|
Packit Service |
4d2de5 |
var (
|
|
Packit Service |
4d2de5 |
goos, goarch string
|
|
Packit Service |
4d2de5 |
)
|
|
Packit Service |
4d2de5 |
|
|
Packit Service |
4d2de5 |
// cmdLine returns this programs's commandline arguments
|
|
Packit Service |
4d2de5 |
func cmdLine() string {
|
|
Packit Service |
4d2de5 |
return "go run mksysnum.go " + strings.Join(os.Args[1:], " ")
|
|
Packit Service |
4d2de5 |
}
|
|
Packit Service |
4d2de5 |
|
|
Packit Service |
4d2de5 |
// buildTags returns build tags
|
|
Packit Service |
4d2de5 |
func buildTags() string {
|
|
Packit Service |
4d2de5 |
return fmt.Sprintf("%s,%s", goarch, goos)
|
|
Packit Service |
4d2de5 |
}
|
|
Packit Service |
4d2de5 |
|
|
Packit Service |
4d2de5 |
func checkErr(err error) {
|
|
Packit Service |
4d2de5 |
if err != nil {
|
|
Packit Service |
4d2de5 |
fmt.Fprintf(os.Stderr, "%v\n", err)
|
|
Packit Service |
4d2de5 |
os.Exit(1)
|
|
Packit Service |
4d2de5 |
}
|
|
Packit Service |
4d2de5 |
}
|
|
Packit Service |
4d2de5 |
|
|
Packit Service |
4d2de5 |
// source string and substring slice for regexp
|
|
Packit Service |
4d2de5 |
type re struct {
|
|
Packit Service |
4d2de5 |
str string // source string
|
|
Packit Service |
4d2de5 |
sub []string // matched sub-string
|
|
Packit Service |
4d2de5 |
}
|
|
Packit Service |
4d2de5 |
|
|
Packit Service |
4d2de5 |
// Match performs regular expression match
|
|
Packit Service |
4d2de5 |
func (r *re) Match(exp string) bool {
|
|
Packit Service |
4d2de5 |
r.sub = regexp.MustCompile(exp).FindStringSubmatch(r.str)
|
|
Packit Service |
4d2de5 |
if r.sub != nil {
|
|
Packit Service |
4d2de5 |
return true
|
|
Packit Service |
4d2de5 |
}
|
|
Packit Service |
4d2de5 |
return false
|
|
Packit Service |
4d2de5 |
}
|
|
Packit Service |
4d2de5 |
|
|
Packit Service |
4d2de5 |
// fetchFile fetches a text file from URL
|
|
Packit Service |
4d2de5 |
func fetchFile(URL string) io.Reader {
|
|
Packit Service |
4d2de5 |
resp, err := http.Get(URL)
|
|
Packit Service |
4d2de5 |
checkErr(err)
|
|
Packit Service |
4d2de5 |
defer resp.Body.Close()
|
|
Packit Service |
4d2de5 |
body, err := ioutil.ReadAll(resp.Body)
|
|
Packit Service |
4d2de5 |
checkErr(err)
|
|
Packit Service |
4d2de5 |
return strings.NewReader(string(body))
|
|
Packit Service |
4d2de5 |
}
|
|
Packit Service |
4d2de5 |
|
|
Packit Service |
4d2de5 |
// readFile reads a text file from path
|
|
Packit Service |
4d2de5 |
func readFile(path string) io.Reader {
|
|
Packit Service |
4d2de5 |
file, err := os.Open(os.Args[1])
|
|
Packit Service |
4d2de5 |
checkErr(err)
|
|
Packit Service |
4d2de5 |
return file
|
|
Packit Service |
4d2de5 |
}
|
|
Packit Service |
4d2de5 |
|
|
Packit Service |
4d2de5 |
func format(name, num, proto string) string {
|
|
Packit Service |
4d2de5 |
name = strings.ToUpper(name)
|
|
Packit Service |
4d2de5 |
// There are multiple entries for enosys and nosys, so comment them out.
|
|
Packit Service |
4d2de5 |
nm := re{str: name}
|
|
Packit Service |
4d2de5 |
if nm.Match(`^SYS_E?NOSYS$`) {
|
|
Packit Service |
4d2de5 |
name = fmt.Sprintf("// %s", name)
|
|
Packit Service |
4d2de5 |
}
|
|
Packit Service |
4d2de5 |
if name == `SYS_SYS_EXIT` {
|
|
Packit Service |
4d2de5 |
name = `SYS_EXIT`
|
|
Packit Service |
4d2de5 |
}
|
|
Packit Service |
4d2de5 |
return fmt.Sprintf(" %s = %s; // %s\n", name, num, proto)
|
|
Packit Service |
4d2de5 |
}
|
|
Packit Service |
4d2de5 |
|
|
Packit Service |
4d2de5 |
func main() {
|
|
Packit Service |
4d2de5 |
// Get the OS (using GOOS_TARGET if it exist)
|
|
Packit Service |
4d2de5 |
goos = os.Getenv("GOOS_TARGET")
|
|
Packit Service |
4d2de5 |
if goos == "" {
|
|
Packit Service |
4d2de5 |
goos = os.Getenv("GOOS")
|
|
Packit Service |
4d2de5 |
}
|
|
Packit Service |
4d2de5 |
// Get the architecture (using GOARCH_TARGET if it exists)
|
|
Packit Service |
4d2de5 |
goarch = os.Getenv("GOARCH_TARGET")
|
|
Packit Service |
4d2de5 |
if goarch == "" {
|
|
Packit Service |
4d2de5 |
goarch = os.Getenv("GOARCH")
|
|
Packit Service |
4d2de5 |
}
|
|
Packit Service |
4d2de5 |
// Check if GOOS and GOARCH environment variables are defined
|
|
Packit Service |
4d2de5 |
if goarch == "" || goos == "" {
|
|
Packit Service |
4d2de5 |
fmt.Fprintf(os.Stderr, "GOARCH or GOOS not defined in environment\n")
|
|
Packit Service |
4d2de5 |
os.Exit(1)
|
|
Packit Service |
4d2de5 |
}
|
|
Packit Service |
4d2de5 |
|
|
Packit Service |
4d2de5 |
file := strings.TrimSpace(os.Args[1])
|
|
Packit Service |
4d2de5 |
var syscalls io.Reader
|
|
Packit Service |
4d2de5 |
if strings.HasPrefix(file, "https://") || strings.HasPrefix(file, "http://") {
|
|
Packit Service |
4d2de5 |
// Download syscalls.master file
|
|
Packit Service |
4d2de5 |
syscalls = fetchFile(file)
|
|
Packit Service |
4d2de5 |
} else {
|
|
Packit Service |
4d2de5 |
syscalls = readFile(file)
|
|
Packit Service |
4d2de5 |
}
|
|
Packit Service |
4d2de5 |
|
|
Packit Service |
4d2de5 |
var text, line string
|
|
Packit Service |
4d2de5 |
s := bufio.NewScanner(syscalls)
|
|
Packit Service |
4d2de5 |
for s.Scan() {
|
|
Packit Service |
4d2de5 |
t := re{str: line}
|
|
Packit Service |
4d2de5 |
if t.Match(`^(.*)\\$`) {
|
|
Packit Service |
4d2de5 |
// Handle continuation
|
|
Packit Service |
4d2de5 |
line = t.sub[1]
|
|
Packit Service |
4d2de5 |
line += strings.TrimLeft(s.Text(), " \t")
|
|
Packit Service |
4d2de5 |
} else {
|
|
Packit Service |
4d2de5 |
// New line
|
|
Packit Service |
4d2de5 |
line = s.Text()
|
|
Packit Service |
4d2de5 |
}
|
|
Packit Service |
4d2de5 |
t = re{str: line}
|
|
Packit Service |
4d2de5 |
if t.Match(`\\$`) {
|
|
Packit Service |
4d2de5 |
continue
|
|
Packit Service |
4d2de5 |
}
|
|
Packit Service |
4d2de5 |
t = re{str: line}
|
|
Packit Service |
4d2de5 |
|
|
Packit Service |
4d2de5 |
switch goos {
|
|
Packit Service |
4d2de5 |
case "dragonfly":
|
|
Packit Service |
4d2de5 |
if t.Match(`^([0-9]+)\s+STD\s+({ \S+\s+(\w+).*)$`) {
|
|
Packit Service |
4d2de5 |
num, proto := t.sub[1], t.sub[2]
|
|
Packit Service |
4d2de5 |
name := fmt.Sprintf("SYS_%s", t.sub[3])
|
|
Packit Service |
4d2de5 |
text += format(name, num, proto)
|
|
Packit Service |
4d2de5 |
}
|
|
Packit Service |
4d2de5 |
case "freebsd":
|
|
Packit Service |
4d2de5 |
if t.Match(`^([0-9]+)\s+\S+\s+(?:(?:NO)?STD|COMPAT10)\s+({ \S+\s+(\w+).*)$`) {
|
|
Packit Service |
4d2de5 |
num, proto := t.sub[1], t.sub[2]
|
|
Packit Service |
4d2de5 |
name := fmt.Sprintf("SYS_%s", t.sub[3])
|
|
Packit Service |
4d2de5 |
text += format(name, num, proto)
|
|
Packit Service |
4d2de5 |
}
|
|
Packit Service |
4d2de5 |
case "openbsd":
|
|
Packit Service |
4d2de5 |
if t.Match(`^([0-9]+)\s+STD\s+(NOLOCK\s+)?({ \S+\s+\*?(\w+).*)$`) {
|
|
Packit Service |
4d2de5 |
num, proto, name := t.sub[1], t.sub[3], t.sub[4]
|
|
Packit Service |
4d2de5 |
text += format(name, num, proto)
|
|
Packit Service |
4d2de5 |
}
|
|
Packit Service |
4d2de5 |
case "netbsd":
|
|
Packit Service |
4d2de5 |
if t.Match(`^([0-9]+)\s+((STD)|(NOERR))\s+(RUMP\s+)?({\s+\S+\s*\*?\s*\|(\S+)\|(\S*)\|(\w+).*\s+})(\s+(\S+))?$`) {
|
|
Packit Service |
4d2de5 |
num, proto, compat := t.sub[1], t.sub[6], t.sub[8]
|
|
Packit Service |
4d2de5 |
name := t.sub[7] + "_" + t.sub[9]
|
|
Packit Service |
4d2de5 |
if t.sub[11] != "" {
|
|
Packit Service |
4d2de5 |
name = t.sub[7] + "_" + t.sub[11]
|
|
Packit Service |
4d2de5 |
}
|
|
Packit Service |
4d2de5 |
name = strings.ToUpper(name)
|
|
Packit Service |
4d2de5 |
if compat == "" || compat == "13" || compat == "30" || compat == "50" {
|
|
Packit Service |
4d2de5 |
text += fmt.Sprintf(" %s = %s; // %s\n", name, num, proto)
|
|
Packit Service |
4d2de5 |
}
|
|
Packit Service |
4d2de5 |
}
|
|
Packit Service |
4d2de5 |
case "darwin":
|
|
Packit Service |
4d2de5 |
if t.Match(`^#define\s+SYS_(\w+)\s+([0-9]+)`) {
|
|
Packit Service |
4d2de5 |
name, num := t.sub[1], t.sub[2]
|
|
Packit Service |
4d2de5 |
name = strings.ToUpper(name)
|
|
Packit Service |
4d2de5 |
text += fmt.Sprintf(" SYS_%s = %s;\n", name, num)
|
|
Packit Service |
4d2de5 |
}
|
|
Packit Service |
4d2de5 |
default:
|
|
Packit Service |
4d2de5 |
fmt.Fprintf(os.Stderr, "unrecognized GOOS=%s\n", goos)
|
|
Packit Service |
4d2de5 |
os.Exit(1)
|
|
Packit Service |
4d2de5 |
|
|
Packit Service |
4d2de5 |
}
|
|
Packit Service |
4d2de5 |
}
|
|
Packit Service |
4d2de5 |
err := s.Err()
|
|
Packit Service |
4d2de5 |
checkErr(err)
|
|
Packit Service |
4d2de5 |
|
|
Packit Service |
4d2de5 |
fmt.Printf(template, cmdLine(), buildTags(), text)
|
|
Packit Service |
4d2de5 |
}
|
|
Packit Service |
4d2de5 |
|
|
Packit Service |
4d2de5 |
const template = `// %s
|
|
Packit Service |
4d2de5 |
// Code generated by the command above; see README.md. DO NOT EDIT.
|
|
Packit Service |
4d2de5 |
|
|
Packit Service |
4d2de5 |
// +build %s
|
|
Packit Service |
4d2de5 |
|
|
Packit Service |
4d2de5 |
package unix
|
|
Packit Service |
4d2de5 |
|
|
Packit Service |
4d2de5 |
const(
|
|
Packit Service |
4d2de5 |
%s)`
|