os: stub out support for some more features
This is necessary for the following: - to make sure os/exec can be imported - to make sure internal/testenv can be imported The internal/testenv package (which imports os/exec) is used by a lot of tests. By adding support for it, more tests can be run. This commit adds a bunch of new packages that now pass all tests.
Этот коммит содержится в:
родитель
6cbaed75c8
коммит
718746dd21
12 изменённых файлов: 186 добавлений и 12 удалений
12
Makefile
12
Makefile
|
@ -200,31 +200,41 @@ test: wasi-libc
|
|||
|
||||
TEST_PACKAGES = \
|
||||
compress/bzip2 \
|
||||
compress/flate \
|
||||
compress/zlib \
|
||||
container/heap \
|
||||
container/list \
|
||||
container/ring \
|
||||
crypto/des \
|
||||
crypto/dsa \
|
||||
crypto/elliptic/internal/fiat \
|
||||
crypto/internal/subtle \
|
||||
crypto/md5 \
|
||||
crypto/rc4 \
|
||||
crypto/sha1 \
|
||||
crypto/sha256 \
|
||||
crypto/sha512 \
|
||||
debug/macho \
|
||||
encoding \
|
||||
encoding/ascii85 \
|
||||
encoding/base32 \
|
||||
encoding/csv \
|
||||
encoding/hex \
|
||||
go/scanner \
|
||||
hash \
|
||||
hash/adler32 \
|
||||
hash/fnv \
|
||||
hash/crc64 \
|
||||
hash/fnv \
|
||||
html \
|
||||
index/suffixarray \
|
||||
internal/itoa \
|
||||
internal/profile \
|
||||
math \
|
||||
math/cmplx \
|
||||
net/http/internal/ascii \
|
||||
net/mail \
|
||||
os \
|
||||
path \
|
||||
reflect \
|
||||
testing \
|
||||
testing/iotest \
|
||||
|
|
|
@ -12,3 +12,7 @@ func Getenv(key string) string {
|
|||
func LookupEnv(key string) (string, bool) {
|
||||
return syscall.Getenv(key)
|
||||
}
|
||||
|
||||
func Environ() []string {
|
||||
return syscall.Environ()
|
||||
}
|
||||
|
|
|
@ -16,3 +16,36 @@ func Getpid() int {
|
|||
func Getppid() int {
|
||||
return syscall.Getppid()
|
||||
}
|
||||
|
||||
type ProcAttr struct {
|
||||
Dir string
|
||||
Env []string
|
||||
Files []*File
|
||||
Sys *syscall.SysProcAttr
|
||||
}
|
||||
|
||||
type ProcessState struct {
|
||||
}
|
||||
|
||||
func (p *ProcessState) String() string {
|
||||
return "" // TODO
|
||||
}
|
||||
func (p *ProcessState) Success() bool {
|
||||
return false // TODO
|
||||
}
|
||||
|
||||
type Process struct {
|
||||
Pid int
|
||||
}
|
||||
|
||||
func StartProcess(name string, argv []string, attr *ProcAttr) (*Process, error) {
|
||||
return nil, &PathError{"fork/exec", name, ErrNotImplemented}
|
||||
}
|
||||
|
||||
func (p *Process) Wait() (*ProcessState, error) {
|
||||
return nil, ErrNotImplemented
|
||||
}
|
||||
|
||||
func (p *Process) Kill() error {
|
||||
return ErrNotImplemented
|
||||
}
|
||||
|
|
|
@ -52,6 +52,16 @@ func Remove(path string) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
// Symlink is a stub, it is not implemented.
|
||||
func Symlink(oldname, newname string) error {
|
||||
return ErrNotImplemented
|
||||
}
|
||||
|
||||
// RemoveAll is a stub, it is not implemented.
|
||||
func RemoveAll(path string) error {
|
||||
return ErrNotImplemented
|
||||
}
|
||||
|
||||
// File represents an open file descriptor.
|
||||
type File struct {
|
||||
handle FileHandle
|
||||
|
@ -187,6 +197,27 @@ func (e *PathError) Error() string {
|
|||
return e.Op + " " + e.Path + ": " + e.Err.Error()
|
||||
}
|
||||
|
||||
func (e *PathError) Unwrap() error {
|
||||
return e.Err
|
||||
}
|
||||
|
||||
// LinkError records an error during a link or symlink or rename system call and
|
||||
// the paths that caused it.
|
||||
type LinkError struct {
|
||||
Op string
|
||||
Old string
|
||||
New string
|
||||
Err error
|
||||
}
|
||||
|
||||
func (e *LinkError) Error() string {
|
||||
return e.Op + " " + e.Old + " " + e.New + ": " + e.Err.Error()
|
||||
}
|
||||
|
||||
func (e *LinkError) Unwrap() error {
|
||||
return e.Err
|
||||
}
|
||||
|
||||
const (
|
||||
O_RDONLY int = syscall.O_RDONLY
|
||||
O_WRONLY int = syscall.O_WRONLY
|
||||
|
|
|
@ -21,6 +21,8 @@ var (
|
|||
Stderr = &File{unixFileHandle(syscall.Stderr), "/dev/stderr"}
|
||||
)
|
||||
|
||||
const DevNull = "/dev/null"
|
||||
|
||||
// isOS indicates whether we're running on a real operating system with
|
||||
// filesystem support.
|
||||
const isOS = true
|
||||
|
|
|
@ -48,3 +48,7 @@ func (f stdioFileHandle) Close() error {
|
|||
|
||||
//go:linkname putchar runtime.putchar
|
||||
func putchar(c byte)
|
||||
|
||||
func Pipe() (r *File, w *File, err error) {
|
||||
return nil, nil, ErrNotImplemented
|
||||
}
|
||||
|
|
|
@ -2,4 +2,23 @@
|
|||
|
||||
package os
|
||||
|
||||
import "syscall"
|
||||
|
||||
type syscallFd = int
|
||||
|
||||
func Pipe() (r *File, w *File, err error) {
|
||||
var p [2]int
|
||||
err = handleSyscallError(syscall.Pipe2(p[:], syscall.O_CLOEXEC))
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
r = &File{
|
||||
handle: unixFileHandle(p[0]),
|
||||
name: "|0",
|
||||
}
|
||||
w = &File{
|
||||
handle: unixFileHandle(p[1]),
|
||||
name: "|1",
|
||||
}
|
||||
return
|
||||
}
|
||||
|
|
|
@ -5,3 +5,20 @@ package os
|
|||
import "syscall"
|
||||
|
||||
type syscallFd = syscall.Handle
|
||||
|
||||
func Pipe() (r *File, w *File, err error) {
|
||||
var p [2]syscall.Handle
|
||||
e := handleSyscallError(syscall.Pipe(p[:]))
|
||||
if e != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
r = &File{
|
||||
handle: unixFileHandle(p[0]),
|
||||
name: "|0",
|
||||
}
|
||||
w = &File{
|
||||
handle: unixFileHandle(p[1]),
|
||||
name: "|1",
|
||||
}
|
||||
return
|
||||
}
|
||||
|
|
|
@ -81,6 +81,12 @@ func Kill(pid int, sig Signal) (err error) {
|
|||
return ENOSYS // TODO
|
||||
}
|
||||
|
||||
type SysProcAttr struct{}
|
||||
|
||||
func Pipe2(p []int, flags int) (err error) {
|
||||
return ENOSYS // TODO
|
||||
}
|
||||
|
||||
func Getenv(key string) (value string, found bool) {
|
||||
data := cstring(key)
|
||||
raw := libc_getenv(&data[0])
|
||||
|
@ -115,6 +121,26 @@ func Mprotect(b []byte, prot int) (err error) {
|
|||
return
|
||||
}
|
||||
|
||||
func Environ() []string {
|
||||
environ := libc_environ
|
||||
var envs []string
|
||||
for *environ != nil {
|
||||
// Convert the C string to a Go string.
|
||||
length := libc_strlen(*environ)
|
||||
var envVar string
|
||||
rawEnvVar := (*struct {
|
||||
ptr unsafe.Pointer
|
||||
length uintptr
|
||||
})(unsafe.Pointer(&envVar))
|
||||
rawEnvVar.ptr = *environ
|
||||
rawEnvVar.length = length
|
||||
envs = append(envs, envVar)
|
||||
// This is the Go equivalent of "environ++" in C.
|
||||
environ = (*unsafe.Pointer)(unsafe.Pointer(uintptr(unsafe.Pointer(environ)) + unsafe.Sizeof(environ)))
|
||||
}
|
||||
return envs
|
||||
}
|
||||
|
||||
// cstring converts a Go string to a C string.
|
||||
func cstring(s string) []byte {
|
||||
data := make([]byte, len(s)+1)
|
||||
|
@ -128,6 +154,9 @@ func splitSlice(p []byte) (buf *byte, len uintptr) {
|
|||
return slice.buf, slice.len
|
||||
}
|
||||
|
||||
//export strlen
|
||||
func libc_strlen(ptr unsafe.Pointer) uintptr
|
||||
|
||||
// ssize_t write(int fd, const void *buf, size_t count)
|
||||
//export write
|
||||
func libc_write(fd int32, buf *byte, count uint) int
|
||||
|
@ -167,3 +196,6 @@ func libc_rmdir(pathname *byte) int32
|
|||
// int unlink(const char *pathname);
|
||||
//export unlink
|
||||
func libc_unlink(pathname *byte) int32
|
||||
|
||||
//go:extern environ
|
||||
var libc_environ *unsafe.Pointer
|
||||
|
|
|
@ -36,18 +36,20 @@ func (e Errno) Is(target error) bool {
|
|||
return false
|
||||
}
|
||||
|
||||
// Source: https://opensource.apple.com/source/xnu/xnu-7195.81.3/bsd/sys/errno.h.auto.html
|
||||
const (
|
||||
EPERM Errno = 0x1
|
||||
ENOENT Errno = 0x2
|
||||
EACCES Errno = 0xd
|
||||
EEXIST Errno = 0x11
|
||||
EINTR Errno = 0x4
|
||||
ENOTDIR Errno = 0x14
|
||||
EINVAL Errno = 0x16
|
||||
EMFILE Errno = 0x18
|
||||
EAGAIN Errno = 0x23
|
||||
ETIMEDOUT Errno = 0x3c
|
||||
ENOSYS Errno = 0x4e
|
||||
EPERM Errno = 1
|
||||
ENOENT Errno = 2
|
||||
EACCES Errno = 13
|
||||
EEXIST Errno = 17
|
||||
EINTR Errno = 4
|
||||
ENOTDIR Errno = 20
|
||||
EINVAL Errno = 22
|
||||
EMFILE Errno = 24
|
||||
EPIPE Errno = 32
|
||||
EAGAIN Errno = 35
|
||||
ETIMEDOUT Errno = 60
|
||||
ENOSYS Errno = 78
|
||||
EWOULDBLOCK Errno = EAGAIN
|
||||
)
|
||||
|
||||
|
@ -77,6 +79,8 @@ const (
|
|||
O_CREAT = 0x200
|
||||
O_TRUNC = 0x400
|
||||
O_EXCL = 0x800
|
||||
|
||||
O_CLOEXEC = 0x01000000
|
||||
)
|
||||
|
||||
// Source: https://opensource.apple.com/source/xnu/xnu-7195.81.3/bsd/sys/mman.h.auto.html
|
||||
|
|
|
@ -67,6 +67,13 @@ func Getenv(key string) (value string, found bool) {
|
|||
return "", false
|
||||
}
|
||||
|
||||
func Environ() []string {
|
||||
env := runtime_envs()
|
||||
envCopy := make([]string, len(env))
|
||||
copy(envCopy, env)
|
||||
return envCopy
|
||||
}
|
||||
|
||||
func Open(path string, mode int, perm uint32) (fd int, err error) {
|
||||
return 0, ENOSYS
|
||||
}
|
||||
|
|
11
testdata/env.go
предоставленный
11
testdata/env.go
предоставленный
|
@ -13,6 +13,17 @@ func main() {
|
|||
}
|
||||
println("ENV2:", v)
|
||||
|
||||
found := false
|
||||
expected := "ENV1=" + os.Getenv("ENV1")
|
||||
for _, envVar := range os.Environ() {
|
||||
if envVar == expected {
|
||||
found = true
|
||||
}
|
||||
}
|
||||
if !found {
|
||||
println("could not find " + expected + " in os.Environ()")
|
||||
}
|
||||
|
||||
// Check for command line arguments.
|
||||
// Argument 0 is skipped because it is the program name, which varies by
|
||||
// test run.
|
||||
|
|
Загрузка…
Создание таблицы
Сослаться в новой задаче