2
1
mirror of https://github.com/therootcompany/serviceman.git synced 2025-02-09 17:25:38 +00:00

update build and dependencies

This commit is contained in:
AJ ONeal 2020-12-02 16:18:34 -07:00
parent 32c71bd698
commit f3ab5471dd
45 changed files with 230 additions and 4741 deletions

5
.gitignore vendored
View File

@ -1,3 +1,8 @@
/serviceman
/manager/static/ab0x.go
dist
xversion.go
*~
.*~
# ---> Go

36
.goreleaser.yml Normal file
View File

@ -0,0 +1,36 @@
before:
hooks:
- go mod download
- go generate ./...
builds:
- env:
- CGO_ENABLED=0
goos:
- linux
- windows
- darwin
goarch:
- 386
- amd64
- arm
- arm64
goarm:
- 6
- 7
archives:
- replacements:
386: i386
amd64: x86_64
format_overrides:
- goos: windows
format: zip
checksum:
name_template: 'checksums.txt'
snapshot:
name_template: '{{ .Tag }}-next'
changelog:
sort: asc
filters:
exclude:
- '^docs:'
- '^test:'

4
go.mod
View File

@ -1,9 +1,9 @@
module git.rootprojects.org/root/go-serviceman
module git.rootprojects.org/root/serviceman
go 1.12
require (
git.rootprojects.org/root/go-gitver v1.1.2
git.rootprojects.org/root/go-gitver/v2 v2.0.2
github.com/UnnoTed/fileb0x v1.1.3
github.com/mitchellh/go-ps v0.0.0-20170309133038-4fdf99ab2936
golang.org/x/net v0.0.0-20180921000356-2f5d2388922f

4
go.sum
View File

@ -1,5 +1,5 @@
git.rootprojects.org/root/go-gitver v1.1.2 h1:AQhr8ktJyP+X+jFbtLavCi/FQLSmB6xvdG2Nfp+J2JA=
git.rootprojects.org/root/go-gitver v1.1.2/go.mod h1:Rj1v3TBhvdaSphFEqMynUYwAz/4f+wY/+syBTvRrmlI=
git.rootprojects.org/root/go-gitver/v2 v2.0.2 h1:T+Je13wrY1jz4OPJF98HnuCNp6n2Xe2uK6/NNF6a4+0=
git.rootprojects.org/root/go-gitver/v2 v2.0.2/go.mod h1:ur82M/jZcvr1WWihyVtNEgDBqIjo22o56wcVHeVJFh8=
github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ=
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
github.com/UnnoTed/fileb0x v1.1.3 h1:TUfJRey+psXuivBqasgp7Du3iXB4hzjI5UXDl+BCrzE=

View File

@ -9,7 +9,7 @@ import (
"path/filepath"
"strings"
"git.rootprojects.org/root/go-serviceman/service"
"git.rootprojects.org/root/serviceman/service"
)
// Install will do a best-effort attempt to install a start-on-startup

View File

@ -8,8 +8,8 @@ import (
"path/filepath"
"text/template"
"git.rootprojects.org/root/go-serviceman/manager/static"
"git.rootprojects.org/root/go-serviceman/service"
"git.rootprojects.org/root/serviceman/manager/static"
"git.rootprojects.org/root/serviceman/service"
)
const (

View File

@ -8,8 +8,8 @@ import (
"path/filepath"
"text/template"
"git.rootprojects.org/root/go-serviceman/manager/static"
"git.rootprojects.org/root/go-serviceman/service"
"git.rootprojects.org/root/serviceman/manager/static"
"git.rootprojects.org/root/serviceman/service"
)
var (

View File

@ -9,7 +9,7 @@ import (
"path/filepath"
"strings"
"git.rootprojects.org/root/go-serviceman/service"
"git.rootprojects.org/root/serviceman/service"
)
// this code is shared between Mac and Linux, but may diverge in the future

View File

@ -3,7 +3,7 @@
package manager
import (
"git.rootprojects.org/root/go-serviceman/service"
"git.rootprojects.org/root/serviceman/service"
)
func Render(c *service.Service) ([]byte, error) {

View File

@ -10,8 +10,8 @@ import (
"path/filepath"
"strings"
"git.rootprojects.org/root/go-serviceman/runner"
"git.rootprojects.org/root/go-serviceman/service"
"git.rootprojects.org/root/serviceman/runner"
"git.rootprojects.org/root/serviceman/service"
"golang.org/x/sys/windows/registry"
)

View File

@ -1,5 +1,5 @@
// Code generated by fileb0x at "2019-08-05 10:09:44.205977 -0600 MDT m=+0.003863161" from config file "b0x.toml" DO NOT EDIT.
// modification hash(25df1985b6a67dc5b8f5c9281219965c.acdb557394f98d3c09c0bb4d4b9142f8)
// Code generated by fileb0x at "2020-12-02 16:04:18.643924 -0700 MST m=+0.006447308" from config file "b0x.toml" DO NOT EDIT.
// modification hash(9da9f7fe309e1c91778a98db0f1f7c61.acdb557394f98d3c09c0bb4d4b9142f8)
package static

View File

@ -10,7 +10,7 @@ import (
"strings"
"time"
"git.rootprojects.org/root/go-serviceman/service"
"git.rootprojects.org/root/serviceman/service"
ps "github.com/mitchellh/go-ps"
)

View File

@ -1,4 +1,4 @@
//go:generate go run -mod=vendor git.rootprojects.org/root/go-gitver
//go:generate go run -mod=vendor git.rootprojects.org/root/go-gitver/v2
// main runs the things and does the stuff
package main
@ -16,14 +16,23 @@ import (
"time"
"unicode/utf8"
"git.rootprojects.org/root/go-serviceman/manager"
"git.rootprojects.org/root/go-serviceman/runner"
"git.rootprojects.org/root/go-serviceman/service"
"git.rootprojects.org/root/serviceman/manager"
"git.rootprojects.org/root/serviceman/runner"
"git.rootprojects.org/root/serviceman/service"
)
var GitRev = "000000000"
var GitVersion = "v0.5.3-pre+dirty"
var GitTimestamp = time.Now().Format(time.RFC3339)
var (
// commit refers to the abbreviated commit hash
commit = "0000000"
// version refers to the most recent tag, plus any commits made since then
version = "v0.0.0-pre0+0000000"
// date refers to the timestamp of the most recent commit
date = time.Now().Format(time.RFC3339)
)
func ver() string {
return fmt.Sprintf("serviceman %s (%s) %s", version, commit[:7], date)
}
func usage() {
fmt.Println("Usage:")
@ -36,6 +45,14 @@ func usage() {
}
func main() {
if len(os.Args) >= 2 {
if "version" == strings.TrimLeft(os.Args[1], "-") {
fmt.Printf("%s\n", ver())
os.Exit(0)
return
}
}
if len(os.Args) < 2 {
fmt.Fprintf(os.Stderr, "Too few arguments: %s\n", strings.Join(os.Args, " "))
usage()
@ -46,7 +63,7 @@ func main() {
os.Args = append(os.Args[:1], os.Args[2:]...)
switch top {
case "version":
fmt.Println(GitVersion, GitTimestamp, GitRev)
fmt.Println(ver())
case "run":
run()
case "add":

View File

@ -3,7 +3,7 @@ package main
import (
"fmt"
"git.rootprojects.org/root/go-serviceman/service"
"git.rootprojects.org/root/serviceman/service"
)
func printLogMessage(conf *service.Service) {

View File

@ -3,8 +3,8 @@ package main
import (
"fmt"
"git.rootprojects.org/root/go-serviceman/manager"
"git.rootprojects.org/root/go-serviceman/service"
"git.rootprojects.org/root/serviceman/manager"
"git.rootprojects.org/root/serviceman/service"
)
func printLogMessage(conf *service.Service) {

View File

@ -3,7 +3,7 @@ package main
import (
"fmt"
"git.rootprojects.org/root/go-serviceman/service"
"git.rootprojects.org/root/serviceman/service"
)
func printLogMessage(conf *service.Service) {

View File

@ -3,6 +3,6 @@
package tools
import (
_ "git.rootprojects.org/root/go-gitver"
_ "git.rootprojects.org/root/go-gitver/v2"
_ "github.com/UnnoTed/fileb0x"
)

View File

@ -1,3 +0,0 @@
module git.rootprojects.org/root/go-gitver
go 1.12

View File

@ -1,6 +1,10 @@
xversion.go
zversion.go
/go-gitver
hello
examples/*/*.sum
# ---> Go
# Binaries for programs and plugins
*.exe

View File

@ -0,0 +1 @@
{}

View File

@ -1,24 +1,79 @@
# git-version.go
# [Go GitVer](https://git.rootprojects.org/root/go-gitver)
Use git tags to add semver to your go package.
Use **git tags** to add (GoRelesear-compatible) [**semver**](https://semver.org/)
to your go package in under 150
[lines of code](https://git.rootprojects.org/root/go-gitver/src/branch/master/gitver/gitver.go).
```txt
Goal: Either use an exact version like v1.0.0
or translate the git version like v1.0.0-4-g0000000
to a semver like v1.0.1-pre4+g0000000
Goals:
1. Use an exact `git tag` version, like v1.0.0, when clean
2. Translate the `git describe` version (v1.0.0-4-g0000000)
to semver (1.0.1-pre4+g0000000) in between releases
3. Note when `dirty` (and have build timestamp)
Fail gracefully when git repo isn't available.
```
# GoDoc
See <https://pkg.go.dev/git.rootprojects.org/root/go-gitver/v2>.
# How it works
1. You define the fallback version and version printing in `main.go`:
```go
//go:generate go run git.rootprojects.org/root/go-gitver/v2
package main
var (
commit = "0000000"
version = "0.0.0-pre0+0000000"
date = "0000-00-00T00:00:00+0000"
)
func main() {
if (len(os.Args) > 1 && "version" === os.Args[1]) {
fmt.Printf("Foobar v%s (%s) %s\n", version, commit[:7], date)
}
// ...
}
```
2. You `go generate` or `go run git.rootprojects.org/root/go-gitver/v2` to generate `xversion.go`:
```go
package main
func init() {
commit = "0921ed1e"
version = "1.1.2"
date = "2019-07-01T02:32:58-06:00"
}
```
# Demo
Generate an `xversion.go` file:
```bash
go run git.rootprojects.org/root/go-gitver
go run git.rootprojects.org/root/go-gitver/v2
cat xversion.go
```
```go
// Code generated by go generate; DO NOT EDIT.
package main
func init() {
commit = "6dace8255b52e123297a44629bc32c015add310a"
version = "1.1.4-pre2+g6dace82"
date = "2020-07-16T20:48:15-06:00"
}
```
<small>**Note**: The file is named `xversion.go` by default so that the
generated file's `init()` will come later, and thus take priority, over
most other files.</small>
@ -26,15 +81,21 @@ most other files.</small>
See `go-gitver`s self-generated version:
```bash
go run git.rootprojects.org/root/go-gitver version
go run git.rootprojects.org/root/go-gitver/v2 version
```
```txt
6dace8255b52e123297a44629bc32c015add310a
v1.1.4-pre2+g6dace82
2020-07-16T20:48:15-06:00
```
# QuickStart
Add this to the top of your main file:
Add this to the top of your main file, so that it runs with `go generate`:
```go
//go:generate go run -mod=vendor git.rootprojects.org/root/go-gitver
//go:generate go run -mod=vendor git.rootprojects.org/root/go-gitver/v2
```
@ -45,7 +106,7 @@ Add a file that imports go-gitver (for versioning)
package example
import _ "git.rootprojects.org/root/go-gitver"
import _ "git.rootprojects.org/root/go-gitver/v2"
```
Change you build instructions to be something like this:
@ -56,7 +117,7 @@ go generate -mod=vendor ./...
go build -mod=vendor -o example cmd/example/*.go
```
You don't have to use `mod vendor`, but I highly recommend it.
You don't have to use `-mod=vendor`, but I highly recommend it (just `go mod tidy; go mod vendor` to start).
# Options
@ -77,12 +138,12 @@ GITVER_FAIL=true
For example:
```go
//go:generate go run -mod=vendor git.rootprojects.org/root/go-gitver --fail
//go:generate go run -mod=vendor git.rootprojects.org/root/go-gitver/v2 --fail
```
```bash
go run -mod=vendor git.rootprojects.org/root/go-gitver version
go run -mod=vendor git.rootprojects.org/root/go-gitver/v2 version
```
# Usage
@ -91,9 +152,9 @@ See `examples/basic`
1. Create a `tools` package in your project
2. Guard it against regular builds with `// +build tools`
3. Include `_ "git.rootprojects.org/root/go-gitver"` in the imports
4. Declare `var GitRev, GitVersion, GitTimestamp string` in your `package main`
5. Include `//go:generate go run -mod=vendor git.rootprojects.org/root/go-gitver` as well
3. Include `_ "git.rootprojects.org/root/go-gitver/v2"` in the imports
4. Declare `var commit, version, date string` in your `package main`
5. Include `//go:generate go run -mod=vendor git.rootprojects.org/root/go-gitver/v2` as well
`tools/tools.go`:
@ -104,29 +165,29 @@ See `examples/basic`
package tools
import (
_ "git.rootprojects.org/root/go-gitver"
_ "git.rootprojects.org/root/go-gitver/v2"
)
```
`main.go`:
```go
//go:generate go run git.rootprojects.org/root/go-gitver --fail
//go:generate go run git.rootprojects.org/root/go-gitver/v2 --fail
package main
import "fmt"
var (
GitRev = "0000000"
GitVersion = "v0.0.0-pre0+0000000"
GitTimestamp = "0000-00-00T00:00:00+0000"
commit = "0000000"
version = "0.0.0-pre0+0000000"
date = "0000-00-00T00:00:00+0000"
)
func main() {
fmt.Println(GitRev)
fmt.Println(GitVersion)
fmt.Println(GitTimestamp)
fmt.Println(commit)
fmt.Println(version)
fmt.Println(date)
}
```
@ -134,7 +195,7 @@ If you're using `go mod vendor` (which I highly recommend that you do),
you'd modify the `go:generate` ever so slightly:
```go
//go:generate go run -mod=vendor git.rootprojects.org/root/go-gitver --fail
//go:generate go run -mod=vendor git.rootprojects.org/root/go-gitver/v2 --fail
```
The only reason I didn't do that in the example is that I'd be included
@ -142,7 +203,7 @@ the repository in itself and that would be... weird.
# Why a tools package?
> import "git.rootprojects.org/root/go-gitver" is a program, not an importable package
> import "git.rootprojects.org/root/go-gitver/v2" is a program, not an importable package
Having a tools package with a build tag that you don't use is a nice way to add exact
versions of a command package used for tooling to your `go.mod` with `go mod tidy`,
@ -182,8 +243,8 @@ git rev-parse HEAD
### cannot find package "."
```txt
package git.rootprojects.org/root/go-gitver: cannot find package "." in:
/Users/me/go-example/vendor/git.rootprojects.org/root/go-gitver
package git.rootprojects.org/root/go-gitver/v2: cannot find package "." in:
/Users/me/go-example/vendor/git.rootprojects.org/root/go-gitver/v2
cmd/example/example.go:1: running "go": exit status 1
```

View File

@ -1,4 +1,4 @@
//go:generate go run -mod=vendor git.rootprojects.org/root/go-gitver
//go:generate go run -mod=vendor git.rootprojects.org/root/go-gitver/v2
package main
@ -6,15 +6,14 @@ import (
"bytes"
"fmt"
"go/format"
"log"
"os"
"text/template"
"time"
"git.rootprojects.org/root/go-gitver/gitver"
"git.rootprojects.org/root/go-gitver/v2/gitver"
)
var GitRev, GitVersion, GitTimestamp string
var commit, version, date string
var exitCode int
var verFile = "xversion.go"
@ -33,9 +32,9 @@ func main() {
pkg = args[i+1]
args[i+1] = ""
} else if "-V" == arg || "version" == arg || "-version" == arg || "--version" == arg {
fmt.Println(GitRev)
fmt.Println(GitVersion)
fmt.Println(GitTimestamp)
fmt.Println(commit)
fmt.Println(version)
fmt.Println(date)
os.Exit(0)
}
}
@ -45,8 +44,13 @@ func main() {
v, err := gitver.ExecAndParse()
if nil != err {
log.Fatalf("Failed to get git version: %s\n", err)
os.Exit(exitCode)
fmt.Fprintf(os.Stderr, "Failed to get git version: %s\n", err)
if exitCode > 0 {
os.Exit(exitCode)
}
v = &gitver.Versions{
Timestamp: time.Now(),
}
}
// Create or overwrite the go file from template
@ -55,12 +59,12 @@ func main() {
Package string
Timestamp string
Version string
GitRev string
Commit string
}{
Package: pkg,
Timestamp: v.Timestamp.Format(time.RFC3339),
Version: v.Version,
GitRev: v.Rev,
Commit: v.Rev,
}); nil != err {
panic(err)
}
@ -89,10 +93,12 @@ var versionTpl = template.Must(template.New("").Parse(`// Code generated by go g
package {{ .Package }}
func init() {
GitRev = "{{ .GitRev }}"
{{ if .Version -}}
GitVersion = "{{ .Version }}"
{{ if .Commit -}}
commit = "{{ .Commit }}"
{{ end -}}
GitTimestamp = "{{ .Timestamp }}"
{{ if .Version -}}
version = "{{ .Version }}"
{{ end -}}
date = "{{ .Timestamp }}"
}
`))

View File

@ -21,12 +21,14 @@ func init() {
gitVer = regexp.MustCompile(`^(v\d+\.\d+)\.(\d+)(-(\d+))?(-(g[0-9a-f]+))?(-(dirty))?`)
}
// Versions describes the various version properties
type Versions struct {
Timestamp time.Time
Version string
Rev string
}
// ExecAndParse will run git and parse the output
func ExecAndParse() (*Versions, error) {
desc, err := gitDesc()
if nil != err {
@ -58,7 +60,7 @@ func gitDesc() (string, error) {
out, err := cmd.CombinedOutput()
if nil != err {
// Don't panic, just carry on
//out = []byte("v0.0.0-0-g0000000")
//out = []byte("0.0.0-0-g0000000")
return "", err
}
return strings.TrimSpace(string(out)), nil
@ -83,7 +85,7 @@ func gitRev() (string, error) {
func semVer(desc string) (string, error) {
if exactVer.MatchString(desc) {
// v1.0.0
return desc, nil
return strings.TrimPrefix(desc, "v"), nil
}
if !gitVer.MatchString(desc) {
@ -122,10 +124,19 @@ func semVer(desc string) (string, error) {
ver += vers[8]
}
return ver, nil
return strings.TrimPrefix(ver, "v"), nil
}
func gitTimestamp(desc string) (time.Time, error) {
// Other options:
//
// Commit Date
// git log -1 --format=%cd --date=format:%Y-%m-%dT%H:%M:%SZ%z
//
// Author Date
// git log -1 --format=%ad --date=format:%Y-%m-%dT%H:%M:%SZ%z
//
// I think I chose this because it would account for dirty-ness better... maybe?
args := []string{
"git",
"show", desc,

3
vendor/git.rootprojects.org/root/go-gitver/v2/go.mod generated vendored Normal file
View File

@ -0,0 +1,3 @@
module git.rootprojects.org/root/go-gitver/v2
go 1.12

2
vendor/git.rootprojects.org/root/go-gitver/v2/go.sum generated vendored Normal file
View File

@ -0,0 +1,2 @@
git.rootprojects.org/root/go-gitver v1.1.3 h1:/qR9z53vY+IFhWRxLkF9cjaiWh8xRJIm6gyuW+MG81A=
git.rootprojects.org/root/go-gitver v1.1.3/go.mod h1:Rj1v3TBhvdaSphFEqMynUYwAz/4f+wY/+syBTvRrmlI=

View File

@ -3,7 +3,7 @@ package main
// use recently generated version info as a fallback
// for when git isn't present (i.e. go run <url>)
func init() {
GitRev = "0b8c2d86df4bfe32ff4534eec84cd56909c398e9"
GitVersion = "v1.1.1"
GitTimestamp = "2019-06-21T00:18:13-06:00"
commit = "37c1fd4b5694fd62c9f0d6ad1df47d938accbeec"
version = "2.0.0-pre1-dirty"
date = "2020-10-10T16:05:59-06:00"
}

View File

@ -1,39 +0,0 @@
// +build ignore
package termbox
/*
#include <termios.h>
#include <sys/ioctl.h>
*/
import "C"
type syscall_Termios C.struct_termios
const (
syscall_IGNBRK = C.IGNBRK
syscall_BRKINT = C.BRKINT
syscall_PARMRK = C.PARMRK
syscall_ISTRIP = C.ISTRIP
syscall_INLCR = C.INLCR
syscall_IGNCR = C.IGNCR
syscall_ICRNL = C.ICRNL
syscall_IXON = C.IXON
syscall_OPOST = C.OPOST
syscall_ECHO = C.ECHO
syscall_ECHONL = C.ECHONL
syscall_ICANON = C.ICANON
syscall_ISIG = C.ISIG
syscall_IEXTEN = C.IEXTEN
syscall_CSIZE = C.CSIZE
syscall_PARENB = C.PARENB
syscall_CS8 = C.CS8
syscall_VMIN = C.VMIN
syscall_VTIME = C.VTIME
// on darwin change these to (on *bsd too?):
// C.TIOCGETA
// C.TIOCSETA
syscall_TCGETS = C.TCGETS
syscall_TCSETS = C.TCSETS
)

View File

@ -1,94 +0,0 @@
// Copyright 2015 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.
// +build ignore
/*
This program is a server for the WebDAV 'litmus' compliance test at
http://www.webdav.org/neon/litmus/
To run the test:
go run litmus_test_server.go
and separately, from the downloaded litmus-xxx directory:
make URL=http://localhost:9999/ check
*/
package main
import (
"flag"
"fmt"
"log"
"net/http"
"net/url"
"golang.org/x/net/webdav"
)
var port = flag.Int("port", 9999, "server port")
func main() {
flag.Parse()
log.SetFlags(0)
h := &webdav.Handler{
FileSystem: webdav.NewMemFS(),
LockSystem: webdav.NewMemLS(),
Logger: func(r *http.Request, err error) {
litmus := r.Header.Get("X-Litmus")
if len(litmus) > 19 {
litmus = litmus[:16] + "..."
}
switch r.Method {
case "COPY", "MOVE":
dst := ""
if u, err := url.Parse(r.Header.Get("Destination")); err == nil {
dst = u.Path
}
o := r.Header.Get("Overwrite")
log.Printf("%-20s%-10s%-30s%-30so=%-2s%v", litmus, r.Method, r.URL.Path, dst, o, err)
default:
log.Printf("%-20s%-10s%-30s%v", litmus, r.Method, r.URL.Path, err)
}
},
}
// The next line would normally be:
// http.Handle("/", h)
// but we wrap that HTTP handler h to cater for a special case.
//
// The propfind_invalid2 litmus test case expects an empty namespace prefix
// declaration to be an error. The FAQ in the webdav litmus test says:
//
// "What does the "propfind_invalid2" test check for?...
//
// If a request was sent with an XML body which included an empty namespace
// prefix declaration (xmlns:ns1=""), then the server must reject that with
// a "400 Bad Request" response, as it is invalid according to the XML
// Namespace specification."
//
// On the other hand, the Go standard library's encoding/xml package
// accepts an empty xmlns namespace, as per the discussion at
// https://github.com/golang/go/issues/8068
//
// Empty namespaces seem disallowed in the second (2006) edition of the XML
// standard, but allowed in a later edition. The grammar differs between
// http://www.w3.org/TR/2006/REC-xml-names-20060816/#ns-decl and
// http://www.w3.org/TR/REC-xml-names/#dt-prefix
//
// Thus, we assume that the propfind_invalid2 test is obsolete, and
// hard-code the 400 Bad Request response that the test expects.
http.Handle("/", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if r.Header.Get("X-Litmus") == "props: 3 (propfind_invalid2)" {
http.Error(w, "400 Bad Request", http.StatusBadRequest)
return
}
h.ServeHTTP(w, r)
}))
addr := fmt.Sprintf(":%d", *port)
log.Printf("Serving %v", addr)
log.Fatal(http.ListenAndServe(addr, nil))
}

View File

@ -1,61 +0,0 @@
// Copyright 2018 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.
// +build ignore
// mkasm_darwin.go generates assembly trampolines to call libSystem routines from Go.
//This program must be run after mksyscall.go.
package main
import (
"bytes"
"fmt"
"io/ioutil"
"log"
"os"
"strings"
)
func main() {
in1, err := ioutil.ReadFile("syscall_darwin.go")
if err != nil {
log.Fatalf("can't open syscall_darwin.go: %s", err)
}
arch := os.Args[1]
in2, err := ioutil.ReadFile(fmt.Sprintf("syscall_darwin_%s.go", arch))
if err != nil {
log.Fatalf("can't open syscall_darwin_%s.go: %s", arch, err)
}
in3, err := ioutil.ReadFile(fmt.Sprintf("zsyscall_darwin_%s.go", arch))
if err != nil {
log.Fatalf("can't open zsyscall_darwin_%s.go: %s", arch, err)
}
in := string(in1) + string(in2) + string(in3)
trampolines := map[string]bool{}
var out bytes.Buffer
fmt.Fprintf(&out, "// go run mkasm_darwin.go %s\n", strings.Join(os.Args[1:], " "))
fmt.Fprintf(&out, "// Code generated by the command above; DO NOT EDIT.\n")
fmt.Fprintf(&out, "\n")
fmt.Fprintf(&out, "// +build go1.12\n")
fmt.Fprintf(&out, "\n")
fmt.Fprintf(&out, "#include \"textflag.h\"\n")
for _, line := range strings.Split(in, "\n") {
if !strings.HasPrefix(line, "func ") || !strings.HasSuffix(line, "_trampoline()") {
continue
}
fn := line[5 : len(line)-13]
if !trampolines[fn] {
trampolines[fn] = true
fmt.Fprintf(&out, "TEXT ·%s_trampoline(SB),NOSPLIT,$0-0\n", fn)
fmt.Fprintf(&out, "\tJMP\t%s(SB)\n", fn)
}
}
err = ioutil.WriteFile(fmt.Sprintf("zsyscall_darwin_%s.s", arch), out.Bytes(), 0644)
if err != nil {
log.Fatalf("can't write zsyscall_darwin_%s.s: %s", arch, err)
}
}

View File

@ -1,122 +0,0 @@
// Copyright 2016 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.
// +build ignore
// mkpost processes the output of cgo -godefs to
// modify the generated types. It is used to clean up
// the sys API in an architecture specific manner.
//
// mkpost is run after cgo -godefs; see README.md.
package main
import (
"bytes"
"fmt"
"go/format"
"io/ioutil"
"log"
"os"
"regexp"
)
func main() {
// Get the OS and architecture (using GOARCH_TARGET if it exists)
goos := os.Getenv("GOOS")
goarch := os.Getenv("GOARCH_TARGET")
if goarch == "" {
goarch = os.Getenv("GOARCH")
}
// Check that we are using the Docker-based build system if we should be.
if goos == "linux" {
if os.Getenv("GOLANG_SYS_BUILD") != "docker" {
os.Stderr.WriteString("In the Docker-based build system, mkpost should not be called directly.\n")
os.Stderr.WriteString("See README.md\n")
os.Exit(1)
}
}
b, err := ioutil.ReadAll(os.Stdin)
if err != nil {
log.Fatal(err)
}
if goos == "aix" {
// Replace type of Atim, Mtim and Ctim by Timespec in Stat_t
// to avoid having both StTimespec and Timespec.
sttimespec := regexp.MustCompile(`_Ctype_struct_st_timespec`)
b = sttimespec.ReplaceAll(b, []byte("Timespec"))
}
// Intentionally export __val fields in Fsid and Sigset_t
valRegex := regexp.MustCompile(`type (Fsid|Sigset_t) struct {(\s+)X__(bits|val)(\s+\S+\s+)}`)
b = valRegex.ReplaceAll(b, []byte("type $1 struct {${2}Val$4}"))
// Intentionally export __fds_bits field in FdSet
fdSetRegex := regexp.MustCompile(`type (FdSet) struct {(\s+)X__fds_bits(\s+\S+\s+)}`)
b = fdSetRegex.ReplaceAll(b, []byte("type $1 struct {${2}Bits$3}"))
// If we have empty Ptrace structs, we should delete them. Only s390x emits
// nonempty Ptrace structs.
ptraceRexexp := regexp.MustCompile(`type Ptrace((Psw|Fpregs|Per) struct {\s*})`)
b = ptraceRexexp.ReplaceAll(b, nil)
// Replace the control_regs union with a blank identifier for now.
controlRegsRegex := regexp.MustCompile(`(Control_regs)\s+\[0\]uint64`)
b = controlRegsRegex.ReplaceAll(b, []byte("_ [0]uint64"))
// Remove fields that are added by glibc
// Note that this is unstable as the identifers are private.
removeFieldsRegex := regexp.MustCompile(`X__glibc\S*`)
b = removeFieldsRegex.ReplaceAll(b, []byte("_"))
// Convert [65]int8 to [65]byte in Utsname members to simplify
// conversion to string; see golang.org/issue/20753
convertUtsnameRegex := regexp.MustCompile(`((Sys|Node|Domain)name|Release|Version|Machine)(\s+)\[(\d+)\]u?int8`)
b = convertUtsnameRegex.ReplaceAll(b, []byte("$1$3[$4]byte"))
// Convert [1024]int8 to [1024]byte in Ptmget members
convertPtmget := regexp.MustCompile(`([SC]n)(\s+)\[(\d+)\]u?int8`)
b = convertPtmget.ReplaceAll(b, []byte("$1[$3]byte"))
// Remove spare fields (e.g. in Statx_t)
spareFieldsRegex := regexp.MustCompile(`X__spare\S*`)
b = spareFieldsRegex.ReplaceAll(b, []byte("_"))
// Remove cgo padding fields
removePaddingFieldsRegex := regexp.MustCompile(`Pad_cgo_\d+`)
b = removePaddingFieldsRegex.ReplaceAll(b, []byte("_"))
// Remove padding, hidden, or unused fields
removeFieldsRegex = regexp.MustCompile(`\b(X_\S+|Padding)`)
b = removeFieldsRegex.ReplaceAll(b, []byte("_"))
// Remove the first line of warning from cgo
b = b[bytes.IndexByte(b, '\n')+1:]
// Modify the command in the header to include:
// mkpost, our own warning, and a build tag.
replacement := fmt.Sprintf(`$1 | go run mkpost.go
// Code generated by the command above; see README.md. DO NOT EDIT.
// +build %s,%s`, goarch, goos)
cgoCommandRegex := regexp.MustCompile(`(cgo -godefs .*)`)
b = cgoCommandRegex.ReplaceAll(b, []byte(replacement))
// Rename Stat_t time fields
if goos == "freebsd" && goarch == "386" {
// Hide Stat_t.[AMCB]tim_ext fields
renameStatTimeExtFieldsRegex := regexp.MustCompile(`[AMCB]tim_ext`)
b = renameStatTimeExtFieldsRegex.ReplaceAll(b, []byte("_"))
}
renameStatTimeFieldsRegex := regexp.MustCompile(`([AMCB])(?:irth)?time?(?:spec)?\s+(Timespec|StTimespec)`)
b = renameStatTimeFieldsRegex.ReplaceAll(b, []byte("${1}tim ${2}"))
// gofmt
b, err = format.Source(b)
if err != nil {
log.Fatal(err)
}
os.Stdout.Write(b)
}

View File

@ -1,407 +0,0 @@
// Copyright 2018 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.
// +build ignore
/*
This program reads a file containing function prototypes
(like syscall_darwin.go) and generates system call bodies.
The prototypes are marked by lines beginning with "//sys"
and read like func declarations if //sys is replaced by func, but:
* The parameter lists must give a name for each argument.
This includes return parameters.
* The parameter lists must give a type for each argument:
the (x, y, z int) shorthand is not allowed.
* If the return parameter is an error number, it must be named errno.
A line beginning with //sysnb is like //sys, except that the
goroutine will not be suspended during the execution of the system
call. This must only be used for system calls which can never
block, as otherwise the system call could cause all goroutines to
hang.
*/
package main
import (
"bufio"
"flag"
"fmt"
"os"
"regexp"
"strings"
)
var (
b32 = flag.Bool("b32", false, "32bit big-endian")
l32 = flag.Bool("l32", false, "32bit little-endian")
plan9 = flag.Bool("plan9", false, "plan9")
openbsd = flag.Bool("openbsd", false, "openbsd")
netbsd = flag.Bool("netbsd", false, "netbsd")
dragonfly = flag.Bool("dragonfly", false, "dragonfly")
arm = flag.Bool("arm", false, "arm") // 64-bit value should use (even, odd)-pair
tags = flag.String("tags", "", "build tags")
filename = flag.String("output", "", "output file name (standard output if omitted)")
)
// cmdLine returns this programs's commandline arguments
func cmdLine() string {
return "go run mksyscall.go " + strings.Join(os.Args[1:], " ")
}
// buildTags returns build tags
func buildTags() string {
return *tags
}
// Param is function parameter
type Param struct {
Name string
Type string
}
// usage prints the program usage
func usage() {
fmt.Fprintf(os.Stderr, "usage: go run mksyscall.go [-b32 | -l32] [-tags x,y] [file ...]\n")
os.Exit(1)
}
// parseParamList parses parameter list and returns a slice of parameters
func parseParamList(list string) []string {
list = strings.TrimSpace(list)
if list == "" {
return []string{}
}
return regexp.MustCompile(`\s*,\s*`).Split(list, -1)
}
// parseParam splits a parameter into name and type
func parseParam(p string) Param {
ps := regexp.MustCompile(`^(\S*) (\S*)$`).FindStringSubmatch(p)
if ps == nil {
fmt.Fprintf(os.Stderr, "malformed parameter: %s\n", p)
os.Exit(1)
}
return Param{ps[1], ps[2]}
}
func main() {
// Get the OS and architecture (using GOARCH_TARGET if it exists)
goos := os.Getenv("GOOS")
if goos == "" {
fmt.Fprintln(os.Stderr, "GOOS not defined in environment")
os.Exit(1)
}
goarch := os.Getenv("GOARCH_TARGET")
if goarch == "" {
goarch = os.Getenv("GOARCH")
}
// Check that we are using the Docker-based build system if we should
if goos == "linux" {
if os.Getenv("GOLANG_SYS_BUILD") != "docker" {
fmt.Fprintf(os.Stderr, "In the Docker-based build system, mksyscall should not be called directly.\n")
fmt.Fprintf(os.Stderr, "See README.md\n")
os.Exit(1)
}
}
flag.Usage = usage
flag.Parse()
if len(flag.Args()) <= 0 {
fmt.Fprintf(os.Stderr, "no files to parse provided\n")
usage()
}
endianness := ""
if *b32 {
endianness = "big-endian"
} else if *l32 {
endianness = "little-endian"
}
libc := false
if goos == "darwin" && strings.Contains(buildTags(), ",go1.12") {
libc = true
}
trampolines := map[string]bool{}
text := ""
for _, path := range flag.Args() {
file, err := os.Open(path)
if err != nil {
fmt.Fprintf(os.Stderr, err.Error())
os.Exit(1)
}
s := bufio.NewScanner(file)
for s.Scan() {
t := s.Text()
t = strings.TrimSpace(t)
t = regexp.MustCompile(`\s+`).ReplaceAllString(t, ` `)
nonblock := regexp.MustCompile(`^\/\/sysnb `).FindStringSubmatch(t)
if regexp.MustCompile(`^\/\/sys `).FindStringSubmatch(t) == nil && nonblock == nil {
continue
}
// Line must be of the form
// func Open(path string, mode int, perm int) (fd int, errno error)
// Split into name, in params, out params.
f := regexp.MustCompile(`^\/\/sys(nb)? (\w+)\(([^()]*)\)\s*(?:\(([^()]+)\))?\s*(?:=\s*((?i)SYS_[A-Z0-9_]+))?$`).FindStringSubmatch(t)
if f == nil {
fmt.Fprintf(os.Stderr, "%s:%s\nmalformed //sys declaration\n", path, t)
os.Exit(1)
}
funct, inps, outps, sysname := f[2], f[3], f[4], f[5]
// ClockGettime doesn't have a syscall number on Darwin, only generate libc wrappers.
if goos == "darwin" && !libc && funct == "ClockGettime" {
continue
}
// Split argument lists on comma.
in := parseParamList(inps)
out := parseParamList(outps)
// Try in vain to keep people from editing this file.
// The theory is that they jump into the middle of the file
// without reading the header.
text += "// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT\n\n"
// Go function header.
outDecl := ""
if len(out) > 0 {
outDecl = fmt.Sprintf(" (%s)", strings.Join(out, ", "))
}
text += fmt.Sprintf("func %s(%s)%s {\n", funct, strings.Join(in, ", "), outDecl)
// Check if err return available
errvar := ""
for _, param := range out {
p := parseParam(param)
if p.Type == "error" {
errvar = p.Name
break
}
}
// Prepare arguments to Syscall.
var args []string
n := 0
for _, param := range in {
p := parseParam(param)
if regexp.MustCompile(`^\*`).FindStringSubmatch(p.Type) != nil {
args = append(args, "uintptr(unsafe.Pointer("+p.Name+"))")
} else if p.Type == "string" && errvar != "" {
text += fmt.Sprintf("\tvar _p%d *byte\n", n)
text += fmt.Sprintf("\t_p%d, %s = BytePtrFromString(%s)\n", n, errvar, p.Name)
text += fmt.Sprintf("\tif %s != nil {\n\t\treturn\n\t}\n", errvar)
args = append(args, fmt.Sprintf("uintptr(unsafe.Pointer(_p%d))", n))
n++
} else if p.Type == "string" {
fmt.Fprintf(os.Stderr, path+":"+funct+" uses string arguments, but has no error return\n")
text += fmt.Sprintf("\tvar _p%d *byte\n", n)
text += fmt.Sprintf("\t_p%d, _ = BytePtrFromString(%s)\n", n, p.Name)
args = append(args, fmt.Sprintf("uintptr(unsafe.Pointer(_p%d))", n))
n++
} else if regexp.MustCompile(`^\[\](.*)`).FindStringSubmatch(p.Type) != nil {
// Convert slice into pointer, length.
// Have to be careful not to take address of &a[0] if len == 0:
// pass dummy pointer in that case.
// Used to pass nil, but some OSes or simulators reject write(fd, nil, 0).
text += fmt.Sprintf("\tvar _p%d unsafe.Pointer\n", n)
text += fmt.Sprintf("\tif len(%s) > 0 {\n\t\t_p%d = unsafe.Pointer(&%s[0])\n\t}", p.Name, n, p.Name)
text += fmt.Sprintf(" else {\n\t\t_p%d = unsafe.Pointer(&_zero)\n\t}\n", n)
args = append(args, fmt.Sprintf("uintptr(_p%d)", n), fmt.Sprintf("uintptr(len(%s))", p.Name))
n++
} else if p.Type == "int64" && (*openbsd || *netbsd) {
args = append(args, "0")
if endianness == "big-endian" {
args = append(args, fmt.Sprintf("uintptr(%s>>32)", p.Name), fmt.Sprintf("uintptr(%s)", p.Name))
} else if endianness == "little-endian" {
args = append(args, fmt.Sprintf("uintptr(%s)", p.Name), fmt.Sprintf("uintptr(%s>>32)", p.Name))
} else {
args = append(args, fmt.Sprintf("uintptr(%s)", p.Name))
}
} else if p.Type == "int64" && *dragonfly {
if regexp.MustCompile(`^(?i)extp(read|write)`).FindStringSubmatch(funct) == nil {
args = append(args, "0")
}
if endianness == "big-endian" {
args = append(args, fmt.Sprintf("uintptr(%s>>32)", p.Name), fmt.Sprintf("uintptr(%s)", p.Name))
} else if endianness == "little-endian" {
args = append(args, fmt.Sprintf("uintptr(%s)", p.Name), fmt.Sprintf("uintptr(%s>>32)", p.Name))
} else {
args = append(args, fmt.Sprintf("uintptr(%s)", p.Name))
}
} else if (p.Type == "int64" || p.Type == "uint64") && endianness != "" {
if len(args)%2 == 1 && *arm {
// arm abi specifies 64-bit argument uses
// (even, odd) pair
args = append(args, "0")
}
if endianness == "big-endian" {
args = append(args, fmt.Sprintf("uintptr(%s>>32)", p.Name), fmt.Sprintf("uintptr(%s)", p.Name))
} else {
args = append(args, fmt.Sprintf("uintptr(%s)", p.Name), fmt.Sprintf("uintptr(%s>>32)", p.Name))
}
} else {
args = append(args, fmt.Sprintf("uintptr(%s)", p.Name))
}
}
// Determine which form to use; pad args with zeros.
asm := "Syscall"
if nonblock != nil {
if errvar == "" && goos == "linux" {
asm = "RawSyscallNoError"
} else {
asm = "RawSyscall"
}
} else {
if errvar == "" && goos == "linux" {
asm = "SyscallNoError"
}
}
if len(args) <= 3 {
for len(args) < 3 {
args = append(args, "0")
}
} else if len(args) <= 6 {
asm += "6"
for len(args) < 6 {
args = append(args, "0")
}
} else if len(args) <= 9 {
asm += "9"
for len(args) < 9 {
args = append(args, "0")
}
} else {
fmt.Fprintf(os.Stderr, "%s:%s too many arguments to system call\n", path, funct)
}
// System call number.
if sysname == "" {
sysname = "SYS_" + funct
sysname = regexp.MustCompile(`([a-z])([A-Z])`).ReplaceAllString(sysname, `${1}_$2`)
sysname = strings.ToUpper(sysname)
}
var libcFn string
if libc {
asm = "syscall_" + strings.ToLower(asm[:1]) + asm[1:] // internal syscall call
sysname = strings.TrimPrefix(sysname, "SYS_") // remove SYS_
sysname = strings.ToLower(sysname) // lowercase
if sysname == "getdirentries64" {
// Special case - libSystem name and
// raw syscall name don't match.
sysname = "__getdirentries64"
}
libcFn = sysname
sysname = "funcPC(libc_" + sysname + "_trampoline)"
}
// Actual call.
arglist := strings.Join(args, ", ")
call := fmt.Sprintf("%s(%s, %s)", asm, sysname, arglist)
// Assign return values.
body := ""
ret := []string{"_", "_", "_"}
doErrno := false
for i := 0; i < len(out); i++ {
p := parseParam(out[i])
reg := ""
if p.Name == "err" && !*plan9 {
reg = "e1"
ret[2] = reg
doErrno = true
} else if p.Name == "err" && *plan9 {
ret[0] = "r0"
ret[2] = "e1"
break
} else {
reg = fmt.Sprintf("r%d", i)
ret[i] = reg
}
if p.Type == "bool" {
reg = fmt.Sprintf("%s != 0", reg)
}
if p.Type == "int64" && endianness != "" {
// 64-bit number in r1:r0 or r0:r1.
if i+2 > len(out) {
fmt.Fprintf(os.Stderr, "%s:%s not enough registers for int64 return\n", path, funct)
}
if endianness == "big-endian" {
reg = fmt.Sprintf("int64(r%d)<<32 | int64(r%d)", i, i+1)
} else {
reg = fmt.Sprintf("int64(r%d)<<32 | int64(r%d)", i+1, i)
}
ret[i] = fmt.Sprintf("r%d", i)
ret[i+1] = fmt.Sprintf("r%d", i+1)
}