Implemented running executables in memory
All checks were successful
/ test (push) Successful in 16s

This commit is contained in:
Eduard Urbach 2025-07-06 20:02:28 +02:00
parent e5aa006623
commit 5d39a13181
Signed by: akyoto
GPG key ID: 49226B848C78F6C8
10 changed files with 175 additions and 42 deletions

47
src/memfile/Exec_linux.go Normal file
View 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
View 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
View 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
View 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("", "")
}

View 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
}