Compare commits
5 Commits
699c19e972
...
d42067df7c
| Author | SHA1 | Date | |
|---|---|---|---|
|
d42067df7c
|
|||
|
b9459a80c7
|
|||
|
f8189d1488
|
|||
|
5063b774c1
|
|||
|
766dd89ffa
|
@@ -2,7 +2,6 @@ package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"log"
|
||||
@@ -227,8 +226,11 @@ func buildCommand(ctx context.Context, msg message.Msg, early *earlyHardeningErr
|
||||
} else {
|
||||
if f, err := os.Open(flagDBusConfigSession); err != nil {
|
||||
log.Fatal(err.Error())
|
||||
} else if err = json.NewDecoder(f).Decode(&config.SessionBus); err != nil {
|
||||
log.Fatalf("cannot load session bus proxy config from %q: %s", flagDBusConfigSession, err)
|
||||
} else {
|
||||
decodeJSON(log.Fatal, "load session bus proxy config", f, &config.SessionBus)
|
||||
if err = f.Close(); err != nil {
|
||||
log.Fatal(err.Error())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -236,8 +238,11 @@ func buildCommand(ctx context.Context, msg message.Msg, early *earlyHardeningErr
|
||||
if flagDBusConfigSystem != "nil" {
|
||||
if f, err := os.Open(flagDBusConfigSystem); err != nil {
|
||||
log.Fatal(err.Error())
|
||||
} else if err = json.NewDecoder(f).Decode(&config.SystemBus); err != nil {
|
||||
log.Fatalf("cannot load system bus proxy config from %q: %s", flagDBusConfigSystem, err)
|
||||
} else {
|
||||
decodeJSON(log.Fatal, "load system bus proxy config", f, &config.SystemBus)
|
||||
if err = f.Close(); err != nil {
|
||||
log.Fatal(err.Error())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -323,7 +328,7 @@ func buildCommand(ctx context.Context, msg message.Msg, early *earlyHardeningErr
|
||||
|
||||
c.Command("version", "Display version information", func(args []string) error { fmt.Println(internal.Version()); return errSuccess })
|
||||
c.Command("license", "Show full license text", func(args []string) error { fmt.Println(license); return errSuccess })
|
||||
c.Command("template", "Produce a config template", func(args []string) error { printJSON(os.Stdout, false, hst.Template()); return errSuccess })
|
||||
c.Command("template", "Produce a config template", func(args []string) error { encodeJSON(log.Fatal, os.Stdout, false, hst.Template()); return errSuccess })
|
||||
c.Command("help", "Show this help message", func([]string) error { c.PrintHelp(); return errSuccess })
|
||||
|
||||
return c
|
||||
|
||||
60
cmd/hakurei/json.go
Normal file
60
cmd/hakurei/json.go
Normal file
@@ -0,0 +1,60 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"io"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
// decodeJSON decodes json from r and stores it in v. A non-nil error results in a call to fatal.
|
||||
func decodeJSON(fatal func(v ...any), op string, r io.Reader, v any) {
|
||||
err := json.NewDecoder(r).Decode(v)
|
||||
if err == nil {
|
||||
return
|
||||
}
|
||||
|
||||
var (
|
||||
syntaxError *json.SyntaxError
|
||||
unmarshalTypeError *json.UnmarshalTypeError
|
||||
|
||||
msg string
|
||||
)
|
||||
|
||||
switch {
|
||||
case errors.As(err, &syntaxError) && syntaxError != nil:
|
||||
msg = syntaxError.Error() +
|
||||
" at byte " + strconv.FormatInt(syntaxError.Offset, 10)
|
||||
|
||||
case errors.As(err, &unmarshalTypeError) && unmarshalTypeError != nil:
|
||||
msg = "inappropriate " + unmarshalTypeError.Value +
|
||||
" at byte " + strconv.FormatInt(unmarshalTypeError.Offset, 10)
|
||||
|
||||
default:
|
||||
// InvalidUnmarshalError: incorrect usage, does not need to be handled
|
||||
// io.ErrUnexpectedEOF: no additional error information available
|
||||
msg = err.Error()
|
||||
}
|
||||
|
||||
fatal("cannot " + op + ": " + msg)
|
||||
}
|
||||
|
||||
// encodeJSON encodes v to output. A non-nil error results in a call to fatal.
|
||||
func encodeJSON(fatal func(v ...any), output io.Writer, short bool, v any) {
|
||||
encoder := json.NewEncoder(output)
|
||||
if !short {
|
||||
encoder.SetIndent("", " ")
|
||||
}
|
||||
|
||||
if err := encoder.Encode(v); err != nil {
|
||||
var marshalerError *json.MarshalerError
|
||||
if errors.As(err, &marshalerError) && marshalerError != nil {
|
||||
// this likely indicates an implementation error in hst
|
||||
fatal("cannot encode json for " + marshalerError.Type.String() + ": " + marshalerError.Err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
// UnsupportedTypeError, UnsupportedValueError: incorrect usage, does not need to be handled
|
||||
fatal("cannot write json: " + err.Error())
|
||||
}
|
||||
}
|
||||
107
cmd/hakurei/json_test.go
Normal file
107
cmd/hakurei/json_test.go
Normal file
@@ -0,0 +1,107 @@
|
||||
package main_test
|
||||
|
||||
import (
|
||||
"io"
|
||||
"reflect"
|
||||
"strings"
|
||||
"testing"
|
||||
_ "unsafe"
|
||||
|
||||
"hakurei.app/container/stub"
|
||||
)
|
||||
|
||||
//go:linkname decodeJSON hakurei.app/cmd/hakurei.decodeJSON
|
||||
func decodeJSON(fatal func(v ...any), op string, r io.Reader, v any)
|
||||
|
||||
func TestDecodeJSON(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
testCases := []struct {
|
||||
name string
|
||||
t reflect.Type
|
||||
data string
|
||||
want any
|
||||
msg string
|
||||
}{
|
||||
{"success", reflect.TypeFor[uintptr](), "3735928559\n", uintptr(0xdeadbeef), ""},
|
||||
|
||||
{"syntax", reflect.TypeFor[*int](), "\x00", nil,
|
||||
`cannot load sample: invalid character '\x00' looking for beginning of value at byte 1`},
|
||||
{"type", reflect.TypeFor[uintptr](), "-1", nil,
|
||||
`cannot load sample: inappropriate number -1 at byte 2`},
|
||||
{"default", reflect.TypeFor[*int](), "{", nil,
|
||||
"cannot load sample: unexpected EOF"},
|
||||
}
|
||||
for _, tc := range testCases {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
var (
|
||||
gotP = reflect.New(tc.t)
|
||||
gotMsg *string
|
||||
)
|
||||
decodeJSON(func(v ...any) {
|
||||
if gotMsg != nil {
|
||||
t.Fatal("fatal called twice")
|
||||
}
|
||||
msg := v[0].(string)
|
||||
gotMsg = &msg
|
||||
}, "load sample", strings.NewReader(tc.data), gotP.Interface())
|
||||
if tc.msg != "" {
|
||||
if gotMsg == nil {
|
||||
t.Errorf("decodeJSON: success, want fatal %q", tc.msg)
|
||||
} else if *gotMsg != tc.msg {
|
||||
t.Errorf("decodeJSON: fatal = %q, want %q", *gotMsg, tc.msg)
|
||||
}
|
||||
} else if gotMsg != nil {
|
||||
t.Errorf("decodeJSON: fatal = %q", *gotMsg)
|
||||
} else if !reflect.DeepEqual(gotP.Elem().Interface(), tc.want) {
|
||||
t.Errorf("decodeJSON: %#v, want %#v", gotP.Elem().Interface(), tc.want)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
//go:linkname encodeJSON hakurei.app/cmd/hakurei.encodeJSON
|
||||
func encodeJSON(fatal func(v ...any), output io.Writer, short bool, v any)
|
||||
|
||||
func TestEncodeJSON(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
testCases := []struct {
|
||||
name string
|
||||
v any
|
||||
want string
|
||||
}{
|
||||
{"marshaler", errorJSONMarshaler{},
|
||||
`cannot encode json for main_test.errorJSONMarshaler: unique error 3735928559 injected by the test suite`},
|
||||
{"default", func() {},
|
||||
`cannot write json: json: unsupported type: func()`},
|
||||
}
|
||||
for _, tc := range testCases {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
var called bool
|
||||
encodeJSON(func(v ...any) {
|
||||
if called {
|
||||
t.Fatal("fatal called twice")
|
||||
}
|
||||
called = true
|
||||
|
||||
if v[0].(string) != tc.want {
|
||||
t.Errorf("encodeJSON: fatal = %q, want %q", v[0].(string), tc.want)
|
||||
}
|
||||
}, nil, false, tc.v)
|
||||
|
||||
if !called {
|
||||
t.Errorf("encodeJSON: success, want fatal %q", tc.want)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// errorJSONMarshaler implements json.Marshaler.
|
||||
type errorJSONMarshaler struct{}
|
||||
|
||||
func (errorJSONMarshaler) MarshalJSON() ([]byte, error) { return nil, stub.UniqueError(0xdeadbeef) }
|
||||
@@ -1,7 +1,6 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"io"
|
||||
"log"
|
||||
@@ -42,10 +41,7 @@ func tryPath(msg message.Msg, name string) (config *hst.Config) {
|
||||
r = os.Stdin
|
||||
}
|
||||
|
||||
if err := json.NewDecoder(r).Decode(&config); err != nil {
|
||||
log.Fatalf("cannot load configuration: %v", err)
|
||||
}
|
||||
|
||||
decodeJSON(log.Fatal, "load configuration", r, &config)
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"log"
|
||||
@@ -12,23 +11,26 @@ import (
|
||||
"time"
|
||||
|
||||
"hakurei.app/hst"
|
||||
"hakurei.app/internal"
|
||||
"hakurei.app/internal/app"
|
||||
"hakurei.app/internal/app/state"
|
||||
"hakurei.app/message"
|
||||
)
|
||||
|
||||
// printShowSystem populates and writes a representation of [hst.Info] to output.
|
||||
func printShowSystem(output io.Writer, short, flagJSON bool) {
|
||||
t := newPrinter(output)
|
||||
defer t.MustFlush()
|
||||
|
||||
info := &hst.Info{User: new(app.Hsu).MustID(nil)}
|
||||
info := &hst.Info{Version: internal.Version(), User: new(app.Hsu).MustID(nil)}
|
||||
app.CopyPaths().Copy(&info.Paths, info.User)
|
||||
|
||||
if flagJSON {
|
||||
printJSON(output, short, info)
|
||||
encodeJSON(log.Fatal, output, short, info)
|
||||
return
|
||||
}
|
||||
|
||||
t.Printf("Version:\t%s\n", info.Version)
|
||||
t.Printf("User:\t%d\n", info.User)
|
||||
t.Printf("TempDir:\t%s\n", info.TempDir)
|
||||
t.Printf("SharePath:\t%s\n", info.SharePath)
|
||||
@@ -36,6 +38,7 @@ func printShowSystem(output io.Writer, short, flagJSON bool) {
|
||||
t.Printf("RunDirPath:\t%s\n", info.RunDirPath)
|
||||
}
|
||||
|
||||
// printShowInstance writes a representation of [state.State] or [hst.Config] to output.
|
||||
func printShowInstance(
|
||||
output io.Writer, now time.Time,
|
||||
instance *state.State, config *hst.Config,
|
||||
@@ -44,9 +47,9 @@ func printShowInstance(
|
||||
|
||||
if flagJSON {
|
||||
if instance != nil {
|
||||
printJSON(output, short, instance)
|
||||
encodeJSON(log.Fatal, output, short, instance)
|
||||
} else {
|
||||
printJSON(output, short, config)
|
||||
encodeJSON(log.Fatal, output, short, config)
|
||||
}
|
||||
return
|
||||
}
|
||||
@@ -168,6 +171,7 @@ func printShowInstance(
|
||||
return
|
||||
}
|
||||
|
||||
// printPs writes a representation of active instances to output.
|
||||
func printPs(output io.Writer, now time.Time, s state.Store, short, flagJSON bool) {
|
||||
var entries state.Entries
|
||||
if e, err := state.Join(s); err != nil {
|
||||
@@ -184,7 +188,7 @@ func printPs(output io.Writer, now time.Time, s state.Store, short, flagJSON boo
|
||||
for id, instance := range entries {
|
||||
es[id.String()] = instance
|
||||
}
|
||||
printJSON(output, short, es)
|
||||
encodeJSON(log.Fatal, output, short, es)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -213,7 +217,7 @@ func printPs(output io.Writer, now time.Time, s state.Store, short, flagJSON boo
|
||||
for i, e := range exp {
|
||||
v[i] = e.s
|
||||
}
|
||||
printJSON(output, short, v)
|
||||
encodeJSON(log.Fatal, output, short, v)
|
||||
} else {
|
||||
for _, e := range exp {
|
||||
mustPrintln(output, e.s[:8])
|
||||
@@ -247,40 +251,39 @@ func printPs(output io.Writer, now time.Time, s state.Store, short, flagJSON boo
|
||||
}
|
||||
}
|
||||
|
||||
// expandedStateEntry stores [state.State] alongside a string representation of its [state.ID].
|
||||
type expandedStateEntry struct {
|
||||
s string
|
||||
*state.State
|
||||
}
|
||||
|
||||
func printJSON(output io.Writer, short bool, v any) {
|
||||
encoder := json.NewEncoder(output)
|
||||
if !short {
|
||||
encoder.SetIndent("", " ")
|
||||
}
|
||||
if err := encoder.Encode(v); err != nil {
|
||||
log.Fatalf("cannot serialise: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
// newPrinter returns a configured, wrapped [tabwriter.Writer].
|
||||
func newPrinter(output io.Writer) *tp { return &tp{tabwriter.NewWriter(output, 0, 1, 4, ' ', 0)} }
|
||||
|
||||
// tp wraps [tabwriter.Writer] to provide additional formatting methods.
|
||||
type tp struct{ *tabwriter.Writer }
|
||||
|
||||
// Printf calls [fmt.Fprintf] on the underlying [tabwriter.Writer].
|
||||
func (p *tp) Printf(format string, a ...any) {
|
||||
if _, err := fmt.Fprintf(p, format, a...); err != nil {
|
||||
log.Fatalf("cannot write to tabwriter: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
// Println calls [fmt.Fprintln] on the underlying [tabwriter.Writer].
|
||||
func (p *tp) Println(a ...any) {
|
||||
if _, err := fmt.Fprintln(p, a...); err != nil {
|
||||
log.Fatalf("cannot write to tabwriter: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
// MustFlush calls the Flush method of [tabwriter.Writer] and calls [log.Fatalf] on a non-nil error.
|
||||
func (p *tp) MustFlush() {
|
||||
if err := p.Writer.Flush(); err != nil {
|
||||
log.Fatalf("cannot flush tabwriter: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
func mustPrint(output io.Writer, a ...any) {
|
||||
if _, err := fmt.Fprint(output, a...); err != nil {
|
||||
log.Fatalf("cannot print: %v", err)
|
||||
|
||||
@@ -14,7 +14,7 @@ import (
|
||||
"hakurei.app/message"
|
||||
)
|
||||
|
||||
var hakureiPath = internal.MustHakureiPath()
|
||||
var hakureiPathVal = internal.MustHakureiPath().String()
|
||||
|
||||
func mustRunApp(ctx context.Context, msg message.Msg, config *hst.Config, beforeFail func()) {
|
||||
var (
|
||||
@@ -27,9 +27,9 @@ func mustRunApp(ctx context.Context, msg message.Msg, config *hst.Config, before
|
||||
log.Fatalf("cannot pipe: %v", err)
|
||||
} else {
|
||||
if msg.IsVerbose() {
|
||||
cmd = exec.CommandContext(ctx, hakureiPath.String(), "-v", "app", "3")
|
||||
cmd = exec.CommandContext(ctx, hakureiPathVal, "-v", "app", "3")
|
||||
} else {
|
||||
cmd = exec.CommandContext(ctx, hakureiPath.String(), "app", "3")
|
||||
cmd = exec.CommandContext(ctx, hakureiPathVal, "app", "3")
|
||||
}
|
||||
cmd.Stdin, cmd.Stdout, cmd.Stderr = os.Stdin, os.Stdout, os.Stderr
|
||||
cmd.ExtraFiles = []*os.File{r}
|
||||
|
||||
@@ -26,6 +26,11 @@ const (
|
||||
identityMax = 9999
|
||||
)
|
||||
|
||||
// hakureiPath is the absolute path to Hakurei.
|
||||
//
|
||||
// This is set by the linker.
|
||||
var hakureiPath string
|
||||
|
||||
func main() {
|
||||
log.SetFlags(0)
|
||||
log.SetPrefix("hsu: ")
|
||||
@@ -43,13 +48,18 @@ func main() {
|
||||
log.Fatal("this program must not be started by root")
|
||||
}
|
||||
|
||||
if !path.IsAbs(hakureiPath) {
|
||||
log.Fatal("this program is compiled incorrectly")
|
||||
return
|
||||
}
|
||||
|
||||
var toolPath string
|
||||
pexe := path.Join("/proc", strconv.Itoa(os.Getppid()), "exe")
|
||||
if p, err := os.Readlink(pexe); err != nil {
|
||||
log.Fatalf("cannot read parent executable path: %v", err)
|
||||
} else if strings.HasSuffix(p, " (deleted)") {
|
||||
log.Fatal("hakurei executable has been deleted")
|
||||
} else if p != mustCheckPath(hmain) {
|
||||
} else if p != hakureiPath {
|
||||
log.Fatal("this program must be started by hakurei")
|
||||
} else {
|
||||
toolPath = p
|
||||
|
||||
@@ -19,5 +19,5 @@ buildGoModule {
|
||||
ldflags = lib.attrsets.foldlAttrs (
|
||||
ldflags: name: value:
|
||||
ldflags ++ [ "-X main.${name}=${value}" ]
|
||||
) [ "-s -w" ] { hmain = "${hakurei}/libexec/hakurei"; };
|
||||
) [ "-s -w" ] { hakureiPath = "${hakurei}/libexec/hakurei"; };
|
||||
}
|
||||
|
||||
@@ -1,20 +0,0 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"log"
|
||||
"path"
|
||||
)
|
||||
|
||||
const compPoison = "INVALIDINVALIDINVALIDINVALIDINVALID"
|
||||
|
||||
var (
|
||||
hmain = compPoison
|
||||
)
|
||||
|
||||
func mustCheckPath(p string) string {
|
||||
if p != compPoison && p != "" && path.IsAbs(p) {
|
||||
return p
|
||||
}
|
||||
log.Fatal("this program is compiled incorrectly")
|
||||
return compPoison
|
||||
}
|
||||
@@ -1029,8 +1029,8 @@ func TestInitEntrypoint(t *testing.T) {
|
||||
/* end apply */
|
||||
call("mount", stub.ExpectArgs{"host", "host", "", uintptr(0x4c000), ""}, nil, nil),
|
||||
call("unmount", stub.ExpectArgs{"host", 2}, nil, nil),
|
||||
call("open", stub.ExpectArgs{"/", 0x10000, uint32(0)}, 1<<35, syscall.EINTR),
|
||||
call("open", stub.ExpectArgs{"/", 0x10000, uint32(0)}, 1<<35, stub.UniqueError(37)),
|
||||
call("open", stub.ExpectArgs{"/", syscall.O_DIRECTORY | syscall.O_RDONLY, uint32(0)}, 1<<35, syscall.EINTR),
|
||||
call("open", stub.ExpectArgs{"/", syscall.O_DIRECTORY | syscall.O_RDONLY, uint32(0)}, 1<<35, stub.UniqueError(37)),
|
||||
call("fatalf", stub.ExpectArgs{"cannot open intermediate root: %v", []any{stub.UniqueError(37)}}, nil, nil),
|
||||
},
|
||||
}, nil},
|
||||
@@ -1088,8 +1088,8 @@ func TestInitEntrypoint(t *testing.T) {
|
||||
/* end apply */
|
||||
call("mount", stub.ExpectArgs{"host", "host", "", uintptr(0x4c000), ""}, nil, nil),
|
||||
call("unmount", stub.ExpectArgs{"host", 2}, nil, nil),
|
||||
call("open", stub.ExpectArgs{"/", 0x10000, uint32(0)}, 1<<35, syscall.EINTR),
|
||||
call("open", stub.ExpectArgs{"/", 0x10000, uint32(0)}, 1<<35, nil),
|
||||
call("open", stub.ExpectArgs{"/", syscall.O_DIRECTORY | syscall.O_RDONLY, uint32(0)}, 1<<35, syscall.EINTR),
|
||||
call("open", stub.ExpectArgs{"/", syscall.O_DIRECTORY | syscall.O_RDONLY, uint32(0)}, 1<<35, nil),
|
||||
call("chdir", stub.ExpectArgs{"/sysroot"}, nil, stub.UniqueError(35)),
|
||||
call("fatalf", stub.ExpectArgs{"cannot enter sysroot: %v", []any{stub.UniqueError(35)}}, nil, nil),
|
||||
},
|
||||
@@ -1148,8 +1148,8 @@ func TestInitEntrypoint(t *testing.T) {
|
||||
/* end apply */
|
||||
call("mount", stub.ExpectArgs{"host", "host", "", uintptr(0x4c000), ""}, nil, nil),
|
||||
call("unmount", stub.ExpectArgs{"host", 2}, nil, nil),
|
||||
call("open", stub.ExpectArgs{"/", 0x10000, uint32(0)}, 1<<35, syscall.EINTR),
|
||||
call("open", stub.ExpectArgs{"/", 0x10000, uint32(0)}, 1<<35, nil),
|
||||
call("open", stub.ExpectArgs{"/", syscall.O_DIRECTORY | syscall.O_RDONLY, uint32(0)}, 1<<35, syscall.EINTR),
|
||||
call("open", stub.ExpectArgs{"/", syscall.O_DIRECTORY | syscall.O_RDONLY, uint32(0)}, 1<<35, nil),
|
||||
call("chdir", stub.ExpectArgs{"/sysroot"}, nil, nil),
|
||||
call("pivotRoot", stub.ExpectArgs{".", "."}, nil, stub.UniqueError(33)),
|
||||
call("fatalf", stub.ExpectArgs{"cannot pivot into sysroot: %v", []any{stub.UniqueError(33)}}, nil, nil),
|
||||
@@ -1209,8 +1209,8 @@ func TestInitEntrypoint(t *testing.T) {
|
||||
/* end apply */
|
||||
call("mount", stub.ExpectArgs{"host", "host", "", uintptr(0x4c000), ""}, nil, nil),
|
||||
call("unmount", stub.ExpectArgs{"host", 2}, nil, nil),
|
||||
call("open", stub.ExpectArgs{"/", 0x10000, uint32(0)}, 1<<35, syscall.EINTR),
|
||||
call("open", stub.ExpectArgs{"/", 0x10000, uint32(0)}, 1<<35, nil),
|
||||
call("open", stub.ExpectArgs{"/", syscall.O_DIRECTORY | syscall.O_RDONLY, uint32(0)}, 1<<35, syscall.EINTR),
|
||||
call("open", stub.ExpectArgs{"/", syscall.O_DIRECTORY | syscall.O_RDONLY, uint32(0)}, 1<<35, nil),
|
||||
call("chdir", stub.ExpectArgs{"/sysroot"}, nil, nil),
|
||||
call("pivotRoot", stub.ExpectArgs{".", "."}, nil, nil),
|
||||
call("fchdir", stub.ExpectArgs{1 << 35}, nil, stub.UniqueError(31)),
|
||||
@@ -1271,8 +1271,8 @@ func TestInitEntrypoint(t *testing.T) {
|
||||
/* end apply */
|
||||
call("mount", stub.ExpectArgs{"host", "host", "", uintptr(0x4c000), ""}, nil, nil),
|
||||
call("unmount", stub.ExpectArgs{"host", 2}, nil, nil),
|
||||
call("open", stub.ExpectArgs{"/", 0x10000, uint32(0)}, 1<<35, syscall.EINTR),
|
||||
call("open", stub.ExpectArgs{"/", 0x10000, uint32(0)}, 1<<35, nil),
|
||||
call("open", stub.ExpectArgs{"/", syscall.O_DIRECTORY | syscall.O_RDONLY, uint32(0)}, 1<<35, syscall.EINTR),
|
||||
call("open", stub.ExpectArgs{"/", syscall.O_DIRECTORY | syscall.O_RDONLY, uint32(0)}, 1<<35, nil),
|
||||
call("chdir", stub.ExpectArgs{"/sysroot"}, nil, nil),
|
||||
call("pivotRoot", stub.ExpectArgs{".", "."}, nil, nil),
|
||||
call("fchdir", stub.ExpectArgs{1 << 35}, nil, nil),
|
||||
@@ -1334,8 +1334,8 @@ func TestInitEntrypoint(t *testing.T) {
|
||||
/* end apply */
|
||||
call("mount", stub.ExpectArgs{"host", "host", "", uintptr(0x4c000), ""}, nil, nil),
|
||||
call("unmount", stub.ExpectArgs{"host", 2}, nil, nil),
|
||||
call("open", stub.ExpectArgs{"/", 0x10000, uint32(0)}, 1<<35, syscall.EINTR),
|
||||
call("open", stub.ExpectArgs{"/", 0x10000, uint32(0)}, 1<<35, nil),
|
||||
call("open", stub.ExpectArgs{"/", syscall.O_DIRECTORY | syscall.O_RDONLY, uint32(0)}, 1<<35, syscall.EINTR),
|
||||
call("open", stub.ExpectArgs{"/", syscall.O_DIRECTORY | syscall.O_RDONLY, uint32(0)}, 1<<35, nil),
|
||||
call("chdir", stub.ExpectArgs{"/sysroot"}, nil, nil),
|
||||
call("pivotRoot", stub.ExpectArgs{".", "."}, nil, nil),
|
||||
call("fchdir", stub.ExpectArgs{1 << 35}, nil, nil),
|
||||
@@ -1398,8 +1398,8 @@ func TestInitEntrypoint(t *testing.T) {
|
||||
/* end apply */
|
||||
call("mount", stub.ExpectArgs{"host", "host", "", uintptr(0x4c000), ""}, nil, nil),
|
||||
call("unmount", stub.ExpectArgs{"host", 2}, nil, nil),
|
||||
call("open", stub.ExpectArgs{"/", 0x10000, uint32(0)}, 1<<35, syscall.EINTR),
|
||||
call("open", stub.ExpectArgs{"/", 0x10000, uint32(0)}, 1<<35, nil),
|
||||
call("open", stub.ExpectArgs{"/", syscall.O_DIRECTORY | syscall.O_RDONLY, uint32(0)}, 1<<35, syscall.EINTR),
|
||||
call("open", stub.ExpectArgs{"/", syscall.O_DIRECTORY | syscall.O_RDONLY, uint32(0)}, 1<<35, nil),
|
||||
call("chdir", stub.ExpectArgs{"/sysroot"}, nil, nil),
|
||||
call("pivotRoot", stub.ExpectArgs{".", "."}, nil, nil),
|
||||
call("fchdir", stub.ExpectArgs{1 << 35}, nil, nil),
|
||||
@@ -1463,8 +1463,8 @@ func TestInitEntrypoint(t *testing.T) {
|
||||
/* end apply */
|
||||
call("mount", stub.ExpectArgs{"host", "host", "", uintptr(0x4c000), ""}, nil, nil),
|
||||
call("unmount", stub.ExpectArgs{"host", 2}, nil, nil),
|
||||
call("open", stub.ExpectArgs{"/", 0x10000, uint32(0)}, 1<<35, syscall.EINTR),
|
||||
call("open", stub.ExpectArgs{"/", 0x10000, uint32(0)}, 1<<35, nil),
|
||||
call("open", stub.ExpectArgs{"/", syscall.O_DIRECTORY | syscall.O_RDONLY, uint32(0)}, 1<<35, syscall.EINTR),
|
||||
call("open", stub.ExpectArgs{"/", syscall.O_DIRECTORY | syscall.O_RDONLY, uint32(0)}, 1<<35, nil),
|
||||
call("chdir", stub.ExpectArgs{"/sysroot"}, nil, nil),
|
||||
call("pivotRoot", stub.ExpectArgs{".", "."}, nil, nil),
|
||||
call("fchdir", stub.ExpectArgs{1 << 35}, nil, nil),
|
||||
@@ -1529,8 +1529,8 @@ func TestInitEntrypoint(t *testing.T) {
|
||||
/* end apply */
|
||||
call("mount", stub.ExpectArgs{"host", "host", "", uintptr(0x4c000), ""}, nil, nil),
|
||||
call("unmount", stub.ExpectArgs{"host", 2}, nil, nil),
|
||||
call("open", stub.ExpectArgs{"/", 0x10000, uint32(0)}, 1<<35, syscall.EINTR),
|
||||
call("open", stub.ExpectArgs{"/", 0x10000, uint32(0)}, 1<<35, nil),
|
||||
call("open", stub.ExpectArgs{"/", syscall.O_DIRECTORY | syscall.O_RDONLY, uint32(0)}, 1<<35, syscall.EINTR),
|
||||
call("open", stub.ExpectArgs{"/", syscall.O_DIRECTORY | syscall.O_RDONLY, uint32(0)}, 1<<35, nil),
|
||||
call("chdir", stub.ExpectArgs{"/sysroot"}, nil, nil),
|
||||
call("pivotRoot", stub.ExpectArgs{".", "."}, nil, nil),
|
||||
call("fchdir", stub.ExpectArgs{1 << 35}, nil, nil),
|
||||
@@ -1603,8 +1603,8 @@ func TestInitEntrypoint(t *testing.T) {
|
||||
/* end apply */
|
||||
call("mount", stub.ExpectArgs{"host", "host", "", uintptr(0x4c000), ""}, nil, nil),
|
||||
call("unmount", stub.ExpectArgs{"host", 2}, nil, nil),
|
||||
call("open", stub.ExpectArgs{"/", 0x10000, uint32(0)}, 1<<35, syscall.EINTR),
|
||||
call("open", stub.ExpectArgs{"/", 0x10000, uint32(0)}, 1<<35, nil),
|
||||
call("open", stub.ExpectArgs{"/", syscall.O_DIRECTORY | syscall.O_RDONLY, uint32(0)}, 1<<35, syscall.EINTR),
|
||||
call("open", stub.ExpectArgs{"/", syscall.O_DIRECTORY | syscall.O_RDONLY, uint32(0)}, 1<<35, nil),
|
||||
call("chdir", stub.ExpectArgs{"/sysroot"}, nil, nil),
|
||||
call("pivotRoot", stub.ExpectArgs{".", "."}, nil, nil),
|
||||
call("fchdir", stub.ExpectArgs{1 << 35}, nil, nil),
|
||||
@@ -1710,8 +1710,8 @@ func TestInitEntrypoint(t *testing.T) {
|
||||
/* end apply */
|
||||
call("mount", stub.ExpectArgs{"host", "host", "", uintptr(0x4c000), ""}, nil, nil),
|
||||
call("unmount", stub.ExpectArgs{"host", 2}, nil, nil),
|
||||
call("open", stub.ExpectArgs{"/", 0x10000, uint32(0)}, 1<<35, syscall.EINTR),
|
||||
call("open", stub.ExpectArgs{"/", 0x10000, uint32(0)}, 1<<35, nil),
|
||||
call("open", stub.ExpectArgs{"/", syscall.O_DIRECTORY | syscall.O_RDONLY, uint32(0)}, 1<<35, syscall.EINTR),
|
||||
call("open", stub.ExpectArgs{"/", syscall.O_DIRECTORY | syscall.O_RDONLY, uint32(0)}, 1<<35, nil),
|
||||
call("chdir", stub.ExpectArgs{"/sysroot"}, nil, nil),
|
||||
call("pivotRoot", stub.ExpectArgs{".", "."}, nil, nil),
|
||||
call("fchdir", stub.ExpectArgs{1 << 35}, nil, nil),
|
||||
@@ -1818,8 +1818,8 @@ func TestInitEntrypoint(t *testing.T) {
|
||||
/* end apply */
|
||||
call("mount", stub.ExpectArgs{"host", "host", "", uintptr(0x4c000), ""}, nil, nil),
|
||||
call("unmount", stub.ExpectArgs{"host", 2}, nil, nil),
|
||||
call("open", stub.ExpectArgs{"/", 0x10000, uint32(0)}, 1<<35, syscall.EINTR),
|
||||
call("open", stub.ExpectArgs{"/", 0x10000, uint32(0)}, 1<<35, nil),
|
||||
call("open", stub.ExpectArgs{"/", syscall.O_DIRECTORY | syscall.O_RDONLY, uint32(0)}, 1<<35, syscall.EINTR),
|
||||
call("open", stub.ExpectArgs{"/", syscall.O_DIRECTORY | syscall.O_RDONLY, uint32(0)}, 1<<35, nil),
|
||||
call("chdir", stub.ExpectArgs{"/sysroot"}, nil, nil),
|
||||
call("pivotRoot", stub.ExpectArgs{".", "."}, nil, nil),
|
||||
call("fchdir", stub.ExpectArgs{1 << 35}, nil, nil),
|
||||
@@ -1927,8 +1927,8 @@ func TestInitEntrypoint(t *testing.T) {
|
||||
/* end apply */
|
||||
call("mount", stub.ExpectArgs{"host", "host", "", uintptr(0x4c000), ""}, nil, nil),
|
||||
call("unmount", stub.ExpectArgs{"host", 2}, nil, nil),
|
||||
call("open", stub.ExpectArgs{"/", 0x10000, uint32(0)}, 1<<35, syscall.EINTR),
|
||||
call("open", stub.ExpectArgs{"/", 0x10000, uint32(0)}, 1<<35, nil),
|
||||
call("open", stub.ExpectArgs{"/", syscall.O_DIRECTORY | syscall.O_RDONLY, uint32(0)}, 1<<35, syscall.EINTR),
|
||||
call("open", stub.ExpectArgs{"/", syscall.O_DIRECTORY | syscall.O_RDONLY, uint32(0)}, 1<<35, nil),
|
||||
call("chdir", stub.ExpectArgs{"/sysroot"}, nil, nil),
|
||||
call("pivotRoot", stub.ExpectArgs{".", "."}, nil, nil),
|
||||
call("fchdir", stub.ExpectArgs{1 << 35}, nil, nil),
|
||||
@@ -2041,8 +2041,8 @@ func TestInitEntrypoint(t *testing.T) {
|
||||
/* end apply */
|
||||
call("mount", stub.ExpectArgs{"host", "host", "", uintptr(0x4c000), ""}, nil, nil),
|
||||
call("unmount", stub.ExpectArgs{"host", 2}, nil, nil),
|
||||
call("open", stub.ExpectArgs{"/", 0x10000, uint32(0)}, 1<<35, syscall.EINTR),
|
||||
call("open", stub.ExpectArgs{"/", 0x10000, uint32(0)}, 1<<35, nil),
|
||||
call("open", stub.ExpectArgs{"/", syscall.O_DIRECTORY | syscall.O_RDONLY, uint32(0)}, 1<<35, syscall.EINTR),
|
||||
call("open", stub.ExpectArgs{"/", syscall.O_DIRECTORY | syscall.O_RDONLY, uint32(0)}, 1<<35, nil),
|
||||
call("chdir", stub.ExpectArgs{"/sysroot"}, nil, nil),
|
||||
call("pivotRoot", stub.ExpectArgs{".", "."}, nil, nil),
|
||||
call("fchdir", stub.ExpectArgs{1 << 35}, nil, nil),
|
||||
@@ -2143,8 +2143,8 @@ func TestInitEntrypoint(t *testing.T) {
|
||||
/* end apply */
|
||||
call("mount", stub.ExpectArgs{"host", "host", "", uintptr(0x4c000), ""}, nil, nil),
|
||||
call("unmount", stub.ExpectArgs{"host", 2}, nil, nil),
|
||||
call("open", stub.ExpectArgs{"/", 0x10000, uint32(0)}, 1<<35, syscall.EINTR),
|
||||
call("open", stub.ExpectArgs{"/", 0x10000, uint32(0)}, 1<<35, nil),
|
||||
call("open", stub.ExpectArgs{"/", syscall.O_DIRECTORY | syscall.O_RDONLY, uint32(0)}, 1<<35, syscall.EINTR),
|
||||
call("open", stub.ExpectArgs{"/", syscall.O_DIRECTORY | syscall.O_RDONLY, uint32(0)}, 1<<35, nil),
|
||||
call("chdir", stub.ExpectArgs{"/sysroot"}, nil, nil),
|
||||
call("pivotRoot", stub.ExpectArgs{".", "."}, nil, nil),
|
||||
call("fchdir", stub.ExpectArgs{1 << 35}, nil, nil),
|
||||
@@ -2236,8 +2236,8 @@ func TestInitEntrypoint(t *testing.T) {
|
||||
/* end apply */
|
||||
call("mount", stub.ExpectArgs{"host", "host", "", uintptr(0x4c000), ""}, nil, nil),
|
||||
call("unmount", stub.ExpectArgs{"host", 2}, nil, nil),
|
||||
call("open", stub.ExpectArgs{"/", 0x10000, uint32(0)}, 1<<35, syscall.EINTR),
|
||||
call("open", stub.ExpectArgs{"/", 0x10000, uint32(0)}, 1<<35, nil),
|
||||
call("open", stub.ExpectArgs{"/", syscall.O_DIRECTORY | syscall.O_RDONLY, uint32(0)}, 1<<35, syscall.EINTR),
|
||||
call("open", stub.ExpectArgs{"/", syscall.O_DIRECTORY | syscall.O_RDONLY, uint32(0)}, 1<<35, nil),
|
||||
call("chdir", stub.ExpectArgs{"/sysroot"}, nil, nil),
|
||||
call("pivotRoot", stub.ExpectArgs{".", "."}, nil, nil),
|
||||
call("fchdir", stub.ExpectArgs{1 << 35}, nil, nil),
|
||||
@@ -2331,8 +2331,8 @@ func TestInitEntrypoint(t *testing.T) {
|
||||
/* end apply */
|
||||
call("mount", stub.ExpectArgs{"host", "host", "", uintptr(0x4c000), ""}, nil, nil),
|
||||
call("unmount", stub.ExpectArgs{"host", 2}, nil, nil),
|
||||
call("open", stub.ExpectArgs{"/", 0x10000, uint32(0)}, 1<<35, syscall.EINTR),
|
||||
call("open", stub.ExpectArgs{"/", 0x10000, uint32(0)}, 1<<35, nil),
|
||||
call("open", stub.ExpectArgs{"/", syscall.O_DIRECTORY | syscall.O_RDONLY, uint32(0)}, 1<<35, syscall.EINTR),
|
||||
call("open", stub.ExpectArgs{"/", syscall.O_DIRECTORY | syscall.O_RDONLY, uint32(0)}, 1<<35, nil),
|
||||
call("chdir", stub.ExpectArgs{"/sysroot"}, nil, nil),
|
||||
call("pivotRoot", stub.ExpectArgs{".", "."}, nil, nil),
|
||||
call("fchdir", stub.ExpectArgs{1 << 35}, nil, nil),
|
||||
@@ -2433,8 +2433,8 @@ func TestInitEntrypoint(t *testing.T) {
|
||||
/* end apply */
|
||||
call("mount", stub.ExpectArgs{"host", "host", "", uintptr(0x4c000), ""}, nil, nil),
|
||||
call("unmount", stub.ExpectArgs{"host", 2}, nil, nil),
|
||||
call("open", stub.ExpectArgs{"/", 0x10000, uint32(0)}, 1<<35, syscall.EINTR),
|
||||
call("open", stub.ExpectArgs{"/", 0x10000, uint32(0)}, 1<<35, nil),
|
||||
call("open", stub.ExpectArgs{"/", syscall.O_DIRECTORY | syscall.O_RDONLY, uint32(0)}, 1<<35, syscall.EINTR),
|
||||
call("open", stub.ExpectArgs{"/", syscall.O_DIRECTORY | syscall.O_RDONLY, uint32(0)}, 1<<35, nil),
|
||||
call("chdir", stub.ExpectArgs{"/sysroot"}, nil, nil),
|
||||
call("pivotRoot", stub.ExpectArgs{".", "."}, nil, nil),
|
||||
call("fchdir", stub.ExpectArgs{1 << 35}, nil, nil),
|
||||
@@ -2572,8 +2572,8 @@ func TestInitEntrypoint(t *testing.T) {
|
||||
/* end apply */
|
||||
call("mount", stub.ExpectArgs{"host", "host", "", uintptr(0x4c000), ""}, nil, nil),
|
||||
call("unmount", stub.ExpectArgs{"host", 2}, nil, nil),
|
||||
call("open", stub.ExpectArgs{"/", 0x10000, uint32(0)}, 1<<35, syscall.EINTR),
|
||||
call("open", stub.ExpectArgs{"/", 0x10000, uint32(0)}, 1<<35, nil),
|
||||
call("open", stub.ExpectArgs{"/", syscall.O_DIRECTORY | syscall.O_RDONLY, uint32(0)}, 1<<35, syscall.EINTR),
|
||||
call("open", stub.ExpectArgs{"/", syscall.O_DIRECTORY | syscall.O_RDONLY, uint32(0)}, 1<<35, nil),
|
||||
call("chdir", stub.ExpectArgs{"/sysroot"}, nil, nil),
|
||||
call("pivotRoot", stub.ExpectArgs{".", "."}, nil, nil),
|
||||
call("fchdir", stub.ExpectArgs{1 << 35}, nil, nil),
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
package container
|
||||
|
||||
import (
|
||||
"syscall"
|
||||
. "syscall"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
// SetPtracer allows processes to ptrace(2) the calling process.
|
||||
func SetPtracer(pid uintptr) error {
|
||||
_, _, errno := syscall.Syscall(syscall.SYS_PRCTL, syscall.PR_SET_PTRACER, pid, 0)
|
||||
_, _, errno := Syscall(SYS_PRCTL, PR_SET_PTRACER, pid, 0)
|
||||
if errno == 0 {
|
||||
return nil
|
||||
}
|
||||
@@ -22,7 +22,7 @@ const (
|
||||
// SetDumpable sets the "dumpable" attribute of the calling process.
|
||||
func SetDumpable(dumpable uintptr) error {
|
||||
// linux/sched/coredump.h
|
||||
if _, _, errno := syscall.Syscall(syscall.SYS_PRCTL, syscall.PR_SET_DUMPABLE, dumpable, 0); errno != 0 {
|
||||
if _, _, errno := Syscall(SYS_PRCTL, PR_SET_DUMPABLE, dumpable, 0); errno != 0 {
|
||||
return errno
|
||||
}
|
||||
|
||||
@@ -31,7 +31,7 @@ func SetDumpable(dumpable uintptr) error {
|
||||
|
||||
// SetNoNewPrivs sets the calling thread's no_new_privs attribute.
|
||||
func SetNoNewPrivs() error {
|
||||
_, _, errno := syscall.Syscall(syscall.SYS_PRCTL, PR_SET_NO_NEW_PRIVS, 1, 0)
|
||||
_, _, errno := Syscall(SYS_PRCTL, PR_SET_NO_NEW_PRIVS, 1, 0)
|
||||
if errno == 0 {
|
||||
return nil
|
||||
}
|
||||
@@ -41,10 +41,10 @@ func SetNoNewPrivs() error {
|
||||
// Isatty tests whether a file descriptor refers to a terminal.
|
||||
func Isatty(fd int) bool {
|
||||
var buf [8]byte
|
||||
r, _, _ := syscall.Syscall(
|
||||
syscall.SYS_IOCTL,
|
||||
r, _, _ := Syscall(
|
||||
SYS_IOCTL,
|
||||
uintptr(fd),
|
||||
syscall.TIOCGWINSZ,
|
||||
TIOCGWINSZ,
|
||||
uintptr(unsafe.Pointer(&buf[0])),
|
||||
)
|
||||
return r == 0
|
||||
@@ -60,7 +60,7 @@ func Isatty(fd int) bool {
|
||||
func IgnoringEINTR(fn func() error) error {
|
||||
for {
|
||||
err := fn()
|
||||
if err != syscall.EINTR {
|
||||
if err != EINTR {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
8
dist/release.sh
vendored
8
dist/release.sh
vendored
@@ -10,10 +10,10 @@ cp -rv "dist/comp" "${out}"
|
||||
|
||||
go generate ./...
|
||||
go build -trimpath -v -o "${out}/bin/" -ldflags "-s -w -buildid= -extldflags '-static'
|
||||
-X hakurei.app/internal.version=${VERSION}
|
||||
-X hakurei.app/internal.hmain=/usr/bin/hakurei
|
||||
-X hakurei.app/internal.hsu=/usr/bin/hsu
|
||||
-X main.hmain=/usr/bin/hakurei" ./...
|
||||
-X hakurei.app/internal.buildVersion=${VERSION}
|
||||
-X hakurei.app/internal.hakureiPath=/usr/bin/hakurei
|
||||
-X hakurei.app/internal.hsuPath=/usr/bin/hsu
|
||||
-X main.hakureiPath=/usr/bin/hakurei" ./...
|
||||
|
||||
rm -f "./${out}.tar.gz" && tar -C dist -czf "${out}.tar.gz" "${pname}"
|
||||
rm -rf "./${out}"
|
||||
|
||||
@@ -52,7 +52,10 @@ type Paths struct {
|
||||
RunDirPath *check.Absolute `json:"run_dir_path"`
|
||||
}
|
||||
|
||||
// Info holds basic system information collected from the implementation.
|
||||
type Info struct {
|
||||
// Version is a hardcoded version string.
|
||||
Version string `json:"version"`
|
||||
// User is the userid according to hsu.
|
||||
User int `json:"user"`
|
||||
|
||||
|
||||
@@ -1,17 +0,0 @@
|
||||
package internal
|
||||
|
||||
const compPoison = "INVALIDINVALIDINVALIDINVALIDINVALID"
|
||||
|
||||
var (
|
||||
version = compPoison
|
||||
)
|
||||
|
||||
// checkComp validates string value set at compile time.
|
||||
func checkComp(s string) (string, bool) { return s, s != compPoison && s != "" }
|
||||
|
||||
func Version() string {
|
||||
if v, ok := checkComp(version); ok {
|
||||
return v
|
||||
}
|
||||
return "impure"
|
||||
}
|
||||
@@ -6,20 +6,20 @@ import (
|
||||
"hakurei.app/container/check"
|
||||
)
|
||||
|
||||
var (
|
||||
hmain = compPoison
|
||||
hsu = compPoison
|
||||
)
|
||||
// Absolute paths to the Hakurei installation.
|
||||
//
|
||||
// These are set by the linker.
|
||||
var hakureiPath, hsuPath string
|
||||
|
||||
// MustHakureiPath returns the absolute path to hakurei, configured at compile time.
|
||||
func MustHakureiPath() *check.Absolute { return mustCheckPath(log.Fatal, "hakurei", hmain) }
|
||||
// MustHakureiPath returns the [check.Absolute] path to hakurei.
|
||||
func MustHakureiPath() *check.Absolute { return mustCheckPath(log.Fatal, "hakurei", hakureiPath) }
|
||||
|
||||
// MustHsuPath returns the absolute path to hakurei, configured at compile time.
|
||||
func MustHsuPath() *check.Absolute { return mustCheckPath(log.Fatal, "hsu", hsu) }
|
||||
// MustHsuPath returns the [check.Absolute] to hsu.
|
||||
func MustHsuPath() *check.Absolute { return mustCheckPath(log.Fatal, "hsu", hsuPath) }
|
||||
|
||||
// mustCheckPath checks a pathname against compPoison, then [container.NewAbs], calling fatal if either step fails.
|
||||
// mustCheckPath checks a pathname to not be zero, then [check.NewAbs], calling fatal if either step fails.
|
||||
func mustCheckPath(fatal func(v ...any), name, pathname string) *check.Absolute {
|
||||
if pathname != compPoison && pathname != "" {
|
||||
if pathname != "" {
|
||||
if a, err := check.NewAbs(pathname); err != nil {
|
||||
fatal(err.Error())
|
||||
return nil // unreachable
|
||||
|
||||
@@ -15,7 +15,6 @@ func TestMustCheckPath(t *testing.T) {
|
||||
pathname string
|
||||
wantFatal string
|
||||
}{
|
||||
{"poison", compPoison, "invalid test path, this program is compiled incorrectly"},
|
||||
{"zero", "", "invalid test path, this program is compiled incorrectly"},
|
||||
{"not absolute", "\x00", `path "\x00" is not absolute`},
|
||||
{"success", "/proc/nonexistent", ""},
|
||||
|
||||
19
internal/version.go
Normal file
19
internal/version.go
Normal file
@@ -0,0 +1,19 @@
|
||||
package internal
|
||||
|
||||
// FallbackVersion is returned when a version string was not set by the linker.
|
||||
const FallbackVersion = "dirty"
|
||||
|
||||
// buildVersion is the Hakurei tree's version string at build time.
|
||||
//
|
||||
// This is set by the linker.
|
||||
var buildVersion string
|
||||
|
||||
// Version returns the Hakurei tree's version string.
|
||||
// It is either the value of the constant [FallbackVersion] or,
|
||||
// when possible, a release tag like "v1.0.0".
|
||||
func Version() string {
|
||||
if buildVersion != "" {
|
||||
return buildVersion
|
||||
}
|
||||
return FallbackVersion
|
||||
}
|
||||
@@ -75,9 +75,9 @@ buildGoModule rec {
|
||||
]
|
||||
)
|
||||
{
|
||||
version = "v${version}";
|
||||
hmain = "${placeholder "out"}/libexec/hakurei";
|
||||
hsu = "/run/wrappers/bin/hsu";
|
||||
buildVersion = "v${version}";
|
||||
hakureiPath = "${placeholder "out"}/libexec/hakurei";
|
||||
hsuPath = "/run/wrappers/bin/hsu";
|
||||
};
|
||||
|
||||
# nix build environment does not allow acls
|
||||
|
||||
Reference in New Issue
Block a user