mirror of
https://github.com/criyle/go-judge.git
synced 2025-11-04 14:50:02 +08:00
reorganize platform specific function
This commit is contained in:
parent
a2a6c0f97b
commit
6a9c90cafb
@ -7,6 +7,8 @@ import (
|
||||
"os"
|
||||
)
|
||||
|
||||
var _ File = &localFile{}
|
||||
|
||||
// localFile stores a path to represent a local file
|
||||
type localFile struct {
|
||||
name, path string
|
||||
|
||||
@ -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
12
file/memfile_linux.go
Normal 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
14
file/memfile_others.go
Normal 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
|
||||
}
|
||||
@ -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
|
||||
}
|
||||
|
||||
55
pkg/envexec/file_util_linux.go
Normal file
55
pkg/envexec/file_util_linux.go
Normal 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
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user