diff --git a/src/cli/Exec_test.go b/src/cli/Exec_test.go index 15c6182..9f44c60 100644 --- a/src/cli/Exec_test.go +++ b/src/cli/Exec_test.go @@ -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) } diff --git a/src/memfile/Exec_linux.go b/src/memfile/Exec_linux.go index ea40ea5..11df712 100644 --- a/src/memfile/Exec_linux.go +++ b/src/memfile/Exec_linux.go @@ -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() } \ No newline at end of file diff --git a/src/memfile/New_other.go b/src/memfile/New_other.go index d693823..d6d9b0a 100644 --- a/src/memfile/New_other.go +++ b/src/memfile/New_other.go @@ -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" diff --git a/src/memfile/memfile_test.go b/src/memfile/memfile_test.go index 9880b1f..3546861 100644 --- a/src/memfile/memfile_test.go +++ b/src/memfile/memfile_test.go @@ -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)) } \ No newline at end of file