Implemented running executables in memory
All checks were successful
/ test (push) Successful in 16s
All checks were successful
/ test (push) Successful in 16s
This commit is contained in:
parent
e5aa006623
commit
5d39a13181
10 changed files with 175 additions and 42 deletions
47
src/memfile/Exec_linux.go
Normal file
47
src/memfile/Exec_linux.go
Normal file
|
@ -0,0 +1,47 @@
|
|||
//go:build linux
|
||||
|
||||
package memfile
|
||||
|
||||
import (
|
||||
"os"
|
||||
"strconv"
|
||||
"syscall"
|
||||
"unsafe"
|
||||
|
||||
"golang.org/x/sys/unix"
|
||||
)
|
||||
|
||||
// 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,
|
||||
uintptr(file.Fd()),
|
||||
uintptr(unsafe.Pointer(empty)),
|
||||
uintptr(unsafe.Pointer(&argvp[0])),
|
||||
uintptr(unsafe.Pointer(&envvp[0])),
|
||||
uintptr(unix.AT_EMPTY_PATH),
|
||||
0,
|
||||
)
|
||||
|
||||
return errno
|
||||
}
|
29
src/memfile/Exec_other.go
Normal file
29
src/memfile/Exec_other.go
Normal file
|
@ -0,0 +1,29 @@
|
|||
//go:build !linux
|
||||
|
||||
package memfile
|
||||
|
||||
import (
|
||||
"os"
|
||||
"os/exec"
|
||||
)
|
||||
|
||||
// Exec executes an in-memory file.
|
||||
func Exec(file *os.File) error {
|
||||
err := file.Chmod(0o700)
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = file.Close()
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
cmd := exec.Command(file.Name())
|
||||
cmd.Stdout = os.Stdout
|
||||
cmd.Stdin = os.Stdin
|
||||
cmd.Stderr = os.Stderr
|
||||
return cmd.Run()
|
||||
}
|
21
src/memfile/New_linux.go
Normal file
21
src/memfile/New_linux.go
Normal file
|
@ -0,0 +1,21 @@
|
|||
//go:build linux
|
||||
|
||||
package memfile
|
||||
|
||||
import (
|
||||
"os"
|
||||
|
||||
"golang.org/x/sys/unix"
|
||||
)
|
||||
|
||||
// New creates a new anonymous in-memory file.
|
||||
func New(name string) (*os.File, error) {
|
||||
fd, err := unix.MemfdCreate(name, unix.MFD_CLOEXEC)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
memFile := os.NewFile(uintptr(fd), name)
|
||||
return memFile, nil
|
||||
}
|
12
src/memfile/New_other.go
Normal file
12
src/memfile/New_other.go
Normal file
|
@ -0,0 +1,12 @@
|
|||
//go:build !linux
|
||||
|
||||
package memfile
|
||||
|
||||
import (
|
||||
"os"
|
||||
)
|
||||
|
||||
// New creates a new anonymous in-memory file.
|
||||
func New(name string) (*os.File, error) {
|
||||
return os.CreateTemp("", "")
|
||||
}
|
15
src/memfile/memfile_test.go
Normal file
15
src/memfile/memfile_test.go
Normal file
|
@ -0,0 +1,15 @@
|
|||
package memfile_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"git.urbach.dev/cli/q/src/memfile"
|
||||
"git.urbach.dev/go/assert"
|
||||
)
|
||||
|
||||
func TestNew(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
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue