This commit is contained in:
parent
e01b0b3951
commit
b55b582b69
4 changed files with 39 additions and 39 deletions
|
@ -16,6 +16,7 @@ func TestExec(t *testing.T) {
|
|||
assert.Equal(t, cli.Exec([]string{"build", "../../examples/hello", "--dry", "--os", "mac", "--arch", "x86"}), 0)
|
||||
assert.Equal(t, cli.Exec([]string{"build", "../../examples/hello", "--dry", "--os", "windows", "--arch", "arm"}), 0)
|
||||
assert.Equal(t, cli.Exec([]string{"build", "../../examples/hello", "--dry", "--os", "windows", "--arch", "x86"}), 0)
|
||||
assert.Equal(t, cli.Exec([]string{"run", "../../examples/hello"}), 0)
|
||||
assert.Equal(t, cli.Exec([]string{"help"}), 0)
|
||||
}
|
||||
|
||||
|
|
|
@ -3,45 +3,17 @@
|
|||
package memfile
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"strconv"
|
||||
"syscall"
|
||||
"unsafe"
|
||||
|
||||
"golang.org/x/sys/unix"
|
||||
"os/exec"
|
||||
)
|
||||
|
||||
// Exec executes an in-memory file.
|
||||
func Exec(file *os.File) error {
|
||||
empty, err := syscall.BytePtrFromString("")
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
argv := []string{"/proc/self/fd/" + strconv.Itoa(int(file.Fd()))}
|
||||
argvp, err := syscall.SlicePtrFromStrings(argv)
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
envv := os.Environ()
|
||||
envvp, err := syscall.SlicePtrFromStrings(envv)
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
_, _, errno := syscall.Syscall6(
|
||||
unix.SYS_EXECVEAT,
|
||||
file.Fd(),
|
||||
uintptr(unsafe.Pointer(empty)),
|
||||
uintptr(unsafe.Pointer(&argvp[0])),
|
||||
uintptr(unsafe.Pointer(&envvp[0])),
|
||||
uintptr(unix.AT_EMPTY_PATH),
|
||||
0,
|
||||
)
|
||||
|
||||
return errno
|
||||
defer file.Close()
|
||||
cmd := exec.Command(fmt.Sprintf("/proc/self/fd/%d", file.Fd()))
|
||||
cmd.Stdout = os.Stdout
|
||||
cmd.Stdin = os.Stdin
|
||||
cmd.Stderr = os.Stderr
|
||||
return cmd.Run()
|
||||
}
|
|
@ -10,7 +10,7 @@ import (
|
|||
|
||||
// New creates a new anonymous in-memory file.
|
||||
func New(name string) (*os.File, error) {
|
||||
pattern := ""
|
||||
pattern := "*"
|
||||
|
||||
if global.OS == "windows" {
|
||||
pattern = "*.exe"
|
||||
|
|
|
@ -1,15 +1,42 @@
|
|||
package memfile_test
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"io/fs"
|
||||
"testing"
|
||||
|
||||
"git.urbach.dev/cli/q/src/build"
|
||||
"git.urbach.dev/cli/q/src/compiler"
|
||||
"git.urbach.dev/cli/q/src/linker"
|
||||
"git.urbach.dev/cli/q/src/memfile"
|
||||
"git.urbach.dev/go/assert"
|
||||
)
|
||||
|
||||
func TestNew(t *testing.T) {
|
||||
func TestEmptyFile(t *testing.T) {
|
||||
file, err := memfile.New("")
|
||||
assert.Nil(t, err)
|
||||
assert.NotNil(t, file)
|
||||
// memfile.Exec can't be tested because it would replace the test executable
|
||||
|
||||
err = memfile.Exec(file)
|
||||
assert.NotNil(t, err)
|
||||
|
||||
err = file.Close()
|
||||
assert.True(t, errors.Is(err, fs.ErrClosed))
|
||||
}
|
||||
|
||||
func TestHelloExample(t *testing.T) {
|
||||
file, err := memfile.New("")
|
||||
assert.Nil(t, err)
|
||||
assert.NotNil(t, file)
|
||||
|
||||
b := build.New("../../examples/hello")
|
||||
env, err := compiler.Compile(b)
|
||||
assert.Nil(t, err)
|
||||
|
||||
linker.Write(file, b, env)
|
||||
err = memfile.Exec(file)
|
||||
assert.Nil(t, err)
|
||||
|
||||
err = file.Close()
|
||||
assert.True(t, errors.Is(err, fs.ErrClosed))
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue