github.com/giovannyortegon/go@v0.0.0-20220115155912-8890063f5bdd/src/pkg/mod/golang.org/x/sys@v0.0.0-20210927094055-39ccf1dd6fa6/unix/linux/mksysnum.go (about)

     1  // Copyright 2018 The Go Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  // +build ignore
     6  
     7  package main
     8  
     9  import (
    10  	"bufio"
    11  	"fmt"
    12  	"os"
    13  	"os/exec"
    14  	"regexp"
    15  	"strconv"
    16  	"strings"
    17  )
    18  
    19  var (
    20  	goos, goarch string
    21  )
    22  
    23  // cmdLine returns this programs's commandline arguments
    24  func cmdLine() string {
    25  	return "go run linux/mksysnum.go " + strings.Join(os.Args[1:], " ")
    26  }
    27  
    28  // goBuildTags returns build tags in the go:build format.
    29  func goBuildTags() string {
    30  	return fmt.Sprintf("%s && %s", goarch, goos)
    31  }
    32  
    33  // plusBuildTags returns build tags in the +build format.
    34  func plusBuildTags() string {
    35  	return fmt.Sprintf("%s,%s", goarch, goos)
    36  }
    37  
    38  func format(name string, num int, offset int) string {
    39  	if num > 999 {
    40  		// ignore deprecated syscalls that are no longer implemented
    41  		// https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/tree/include/uapi/asm-generic/unistd.h?id=refs/heads/master#n716
    42  		return ""
    43  	}
    44  	name = strings.ToUpper(name)
    45  	num = num + offset
    46  	return fmt.Sprintf("	SYS_%s = %d;\n", name, num)
    47  }
    48  
    49  func checkErr(err error) {
    50  	if err != nil {
    51  		fmt.Fprintf(os.Stderr, "%v\n", err)
    52  		os.Exit(1)
    53  	}
    54  }
    55  
    56  // source string and substring slice for regexp
    57  type re struct {
    58  	str string   // source string
    59  	sub []string // matched sub-string
    60  }
    61  
    62  // Match performs regular expression match
    63  func (r *re) Match(exp string) bool {
    64  	r.sub = regexp.MustCompile(exp).FindStringSubmatch(r.str)
    65  	if r.sub != nil {
    66  		return true
    67  	}
    68  	return false
    69  }
    70  
    71  func main() {
    72  	// Get the OS and architecture (using GOARCH_TARGET if it exists)
    73  	goos = os.Getenv("GOOS")
    74  	goarch = os.Getenv("GOARCH_TARGET")
    75  	if goarch == "" {
    76  		goarch = os.Getenv("GOARCH")
    77  	}
    78  	// Check if GOOS and GOARCH environment variables are defined
    79  	if goarch == "" || goos == "" {
    80  		fmt.Fprintf(os.Stderr, "GOARCH or GOOS not defined in environment\n")
    81  		os.Exit(1)
    82  	}
    83  	// Check that we are using the new build system if we should
    84  	if os.Getenv("GOLANG_SYS_BUILD") != "docker" {
    85  		fmt.Fprintf(os.Stderr, "In the new build system, mksysnum should not be called directly.\n")
    86  		fmt.Fprintf(os.Stderr, "See README.md\n")
    87  		os.Exit(1)
    88  	}
    89  
    90  	cc := os.Getenv("CC")
    91  	if cc == "" {
    92  		fmt.Fprintf(os.Stderr, "CC is not defined in environment\n")
    93  		os.Exit(1)
    94  	}
    95  	args := os.Args[1:]
    96  	args = append([]string{"-E", "-dD"}, args...)
    97  	cmd, err := exec.Command(cc, args...).Output() // execute command and capture output
    98  	if err != nil {
    99  		fmt.Fprintf(os.Stderr, "can't run %s", cc)
   100  		os.Exit(1)
   101  	}
   102  	text := ""
   103  	s := bufio.NewScanner(strings.NewReader(string(cmd)))
   104  	var offset, prev int
   105  	for s.Scan() {
   106  		t := re{str: s.Text()}
   107  		if t.Match(`^#define __NR_Linux\s+([0-9]+)`) {
   108  			// mips/mips64: extract offset
   109  			offset, _ = strconv.Atoi(t.sub[1]) // Make offset=0 if empty or non-numeric
   110  		} else if t.Match(`^#define __NR(\w*)_SYSCALL_BASE\s+([0-9]+)`) {
   111  			// arm: extract offset
   112  			offset, _ = strconv.Atoi(t.sub[1]) // Make offset=0 if empty or non-numeric
   113  		} else if t.Match(`^#define __NR_syscalls\s+`) {
   114  			// ignore redefinitions of __NR_syscalls
   115  		} else if t.Match(`^#define __NR_(\w*)Linux_syscalls\s+`) {
   116  			// mips/mips64: ignore definitions about the number of syscalls
   117  		} else if t.Match(`^#define __NR_(\w+)\s+([0-9]+)`) {
   118  			prev, err = strconv.Atoi(t.sub[2])
   119  			checkErr(err)
   120  			text += format(t.sub[1], prev, offset)
   121  		} else if t.Match(`^#define __NR3264_(\w+)\s+([0-9]+)`) {
   122  			prev, err = strconv.Atoi(t.sub[2])
   123  			checkErr(err)
   124  			text += format(t.sub[1], prev, offset)
   125  		} else if t.Match(`^#define __NR_(\w+)\s+\(\w+\+\s*([0-9]+)\)`) {
   126  			r2, err := strconv.Atoi(t.sub[2])
   127  			checkErr(err)
   128  			text += format(t.sub[1], prev+r2, offset)
   129  		} else if t.Match(`^#define __NR_(\w+)\s+\(__NR_(?:SYSCALL_BASE|Linux) \+ ([0-9]+)`) {
   130  			r2, err := strconv.Atoi(t.sub[2])
   131  			checkErr(err)
   132  			text += format(t.sub[1], r2, offset)
   133  		}
   134  	}
   135  	err = s.Err()
   136  	checkErr(err)
   137  	fmt.Printf(template, cmdLine(), goBuildTags(), plusBuildTags(), text)
   138  }
   139  
   140  const template = `// %s
   141  // Code generated by the command above; see README.md. DO NOT EDIT.
   142  
   143  //go:build %s
   144  // +build %s
   145  
   146  package unix
   147  
   148  const(
   149  %s)`