reorganize platform specific function

This commit is contained in:
criyle 2020-04-16 20:35:54 -04:00
parent a2a6c0f97b
commit 6a9c90cafb
6 changed files with 86 additions and 54 deletions

View File

@ -7,6 +7,8 @@ import (
"os"
)
var _ File = &localFile{}
// localFile stores a path to represent a local file
type localFile struct {
name, path string

View File

@ -5,11 +5,10 @@ import (
"fmt"
"io"
"io/ioutil"
"os"
"github.com/criyle/go-sandbox/pkg/memfd"
)
var _ File = &memFile{}
// memFile represent a file like byte array
type memFile struct {
name string
@ -32,10 +31,6 @@ func (m *memFile) Content() ([]byte, error) {
return m.content, nil
}
func (m *memFile) Open() (*os.File, error) {
return memfd.DupToMemfd(m.name, bytes.NewReader(m.content))
}
func (m *memFile) String() string {
return fmt.Sprintf("[memfile:%v,%d]", m.name, len(m.content))
}

12
file/memfile_linux.go Normal file
View File

@ -0,0 +1,12 @@
package file
import (
"bytes"
"os"
"github.com/criyle/go-sandbox/pkg/memfd"
)
func (m *memFile) Open() (*os.File, error) {
return memfd.DupToMemfd(m.name, bytes.NewReader(m.content))
}

14
file/memfile_others.go Normal file
View File

@ -0,0 +1,14 @@
// +build !linux
package file
import (
"errors"
"os"
)
var errNotImplemented = errors.New("Memfile open is not defined on this platform")
func (m *memFile) Open() (*os.File, error) {
return nil, errNotImplemented
}

View File

@ -3,7 +3,6 @@ package envexec
import (
"io/ioutil"
"os"
"syscall"
"github.com/criyle/go-judge/file"
"github.com/criyle/go-sandbox/runner"
@ -50,25 +49,7 @@ func copyOutAndCollect(m Environment, c *Cmd, ptc []pipeCollector) (map[string]f
// copy out dir
if c.CopyOutDir != "" {
g.Go(func() error {
// make sure dir exists
os.MkdirAll(c.CopyOutDir, 0777)
newDir, err := os.Open(c.CopyOutDir)
if err != nil {
return err
}
defer newDir.Close()
dir := m.WorkDir()
names, err := dir.Readdirnames(-1)
if err != nil {
return err
}
for _, n := range names {
if err := copyFileDir(int(dir.Fd()), int(newDir.Fd()), n); err != nil {
return err
}
}
return nil
return copyDir(m.WorkDir(), c.CopyOutDir)
})
}
@ -84,30 +65,3 @@ func copyOutAndCollect(m Environment, c *Cmd, ptc []pipeCollector) (map[string]f
}
return rt, err
}
func copyFileDir(srcDirFd, dstDirFd int, name string) error {
// open the source file
fd, err := syscall.Openat(srcDirFd, name, syscall.O_CLOEXEC|syscall.O_RDONLY, 0777)
if err != nil {
return err
}
defer syscall.Close(fd)
var st syscall.Stat_t
if err := syscall.Fstat(fd, &st); err != nil {
return err
}
// open the dst file
dstFd, err := syscall.Openat(dstDirFd, name, syscall.O_CLOEXEC|syscall.O_WRONLY|syscall.O_CREAT|syscall.O_TRUNC, 0777)
if err != nil {
return err
}
defer syscall.Close(dstFd)
// send file, ignore error for now if it is dir
if _, err := syscall.Sendfile(dstFd, fd, nil, int(st.Size)); err != nil && err != syscall.EINVAL {
return err
}
return nil
}

View File

@ -0,0 +1,55 @@
package envexec
import (
"os"
"syscall"
)
func copyDir(src *os.File, dst string) error {
// make sure dir exists
os.MkdirAll(dst, 0777)
newDir, err := os.Open(dst)
if err != nil {
return err
}
defer newDir.Close()
dir := src
names, err := dir.Readdirnames(-1)
if err != nil {
return err
}
for _, n := range names {
if err := copyFileDir(int(dir.Fd()), int(newDir.Fd()), n); err != nil {
return err
}
}
return nil
}
func copyFileDir(srcDirFd, dstDirFd int, name string) error {
// open the source file
fd, err := syscall.Openat(srcDirFd, name, syscall.O_CLOEXEC|syscall.O_RDONLY, 0777)
if err != nil {
return err
}
defer syscall.Close(fd)
var st syscall.Stat_t
if err := syscall.Fstat(fd, &st); err != nil {
return err
}
// open the dst file
dstFd, err := syscall.Openat(dstDirFd, name, syscall.O_CLOEXEC|syscall.O_WRONLY|syscall.O_CREAT|syscall.O_TRUNC, 0777)
if err != nil {
return err
}
defer syscall.Close(dstFd)
// send file, ignore error for now if it is dir
if _, err := syscall.Sendfile(dstFd, fd, nil, int(st.Size)); err != nil && err != syscall.EINVAL {
return err
}
return nil
}