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", "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", "arm"}), 0)
|
||||||
assert.Equal(t, cli.Exec([]string{"build", "../../examples/hello", "--dry", "--os", "windows", "--arch", "x86"}), 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)
|
assert.Equal(t, cli.Exec([]string{"help"}), 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3,45 +3,17 @@
|
||||||
package memfile
|
package memfile
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
"strconv"
|
"os/exec"
|
||||||
"syscall"
|
|
||||||
"unsafe"
|
|
||||||
|
|
||||||
"golang.org/x/sys/unix"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// Exec executes an in-memory file.
|
// Exec executes an in-memory file.
|
||||||
func Exec(file *os.File) error {
|
func Exec(file *os.File) error {
|
||||||
empty, err := syscall.BytePtrFromString("")
|
defer file.Close()
|
||||||
|
cmd := exec.Command(fmt.Sprintf("/proc/self/fd/%d", file.Fd()))
|
||||||
if err != nil {
|
cmd.Stdout = os.Stdout
|
||||||
return err
|
cmd.Stdin = os.Stdin
|
||||||
}
|
cmd.Stderr = os.Stderr
|
||||||
|
return cmd.Run()
|
||||||
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
|
|
||||||
}
|
}
|
|
@ -10,7 +10,7 @@ import (
|
||||||
|
|
||||||
// New creates a new anonymous in-memory file.
|
// New creates a new anonymous in-memory file.
|
||||||
func New(name string) (*os.File, error) {
|
func New(name string) (*os.File, error) {
|
||||||
pattern := ""
|
pattern := "*"
|
||||||
|
|
||||||
if global.OS == "windows" {
|
if global.OS == "windows" {
|
||||||
pattern = "*.exe"
|
pattern = "*.exe"
|
||||||
|
|
|
@ -1,15 +1,42 @@
|
||||||
package memfile_test
|
package memfile_test
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"errors"
|
||||||
|
"io/fs"
|
||||||
"testing"
|
"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/cli/q/src/memfile"
|
||||||
"git.urbach.dev/go/assert"
|
"git.urbach.dev/go/assert"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestNew(t *testing.T) {
|
func TestEmptyFile(t *testing.T) {
|
||||||
file, err := memfile.New("")
|
file, err := memfile.New("")
|
||||||
assert.Nil(t, err)
|
assert.Nil(t, err)
|
||||||
assert.NotNil(t, file)
|
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