os: Implement Pipe for darwin, add smoke test.

Evidently when you read from pipes in Go, you have to adjust your slice length to reflect the number of bytes read.
Verified upstream behaves the same way.
Этот коммит содержится в:
Dan Kegel 2021-12-31 21:53:20 -08:00 коммит произвёл Ron Evans
родитель c0d257d682
коммит c78df85015
6 изменённых файлов: 84 добавлений и 4 удалений

56
src/os/pipe_test.go Обычный файл
Просмотреть файл

@ -0,0 +1,56 @@
//go:build windows || darwin || (linux && !baremetal && !wasi)
// +build windows darwin linux,!baremetal,!wasi
// Copyright 2021 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// Test pipes on Unix and Windows systems.
package os_test
import (
"bytes"
"os"
"testing"
)
// TestSmokePipe is a simple smoke test for Pipe().
func TestSmokePipe(t *testing.T) {
// Procedure:
// 1. Get the bytes
// 2. Light the bytes on fire
// 3. Smoke the bytes
r, w, err := os.Pipe()
if err != nil {
t.Fatal(err)
return // TODO: remove once Fatal is fatal
}
defer r.Close()
defer w.Close()
msg := []byte("Sed nvlla nisi ardva virtvs")
n, err := w.Write(msg)
if err != nil {
t.Errorf("Writing to fresh pipe failed, error %v", err)
}
want := len(msg)
if n != want {
t.Errorf("Writing to fresh pipe wrote %d bytes, expected %d", n, want)
}
buf := make([]byte, 2*len(msg))
n, err = r.Read(buf)
if err != nil {
t.Errorf("Reading from pipe failed, error %v", err)
}
if n != want {
t.Errorf("Reading from pipe got %d bytes, expected %d", n, want)
}
// Read() does not set len(buf), so do it here.
buf = buf[:n]
if !bytes.Equal(buf, msg) {
t.Errorf("Reading from fresh pipe got wrong bytes")
}
}

Просмотреть файл

@ -153,10 +153,6 @@ func Kill(pid int, sig Signal) (err error) {
type SysProcAttr struct{} type SysProcAttr struct{}
func Pipe2(p []int, flags int) (err error) {
return ENOSYS // TODO
}
// TODO // TODO
type WaitStatus uint32 type WaitStatus uint32

Просмотреть файл

@ -246,6 +246,19 @@ func Fdopendir(fd int) (dir uintptr, err error) {
return return
} }
func Pipe2(fds []int, flags int) (err error) {
// Mac only has Pipe, which ignores the flags argument
buf := make([]int32, 2)
fail := int(libc_pipe(&buf[0]))
if fail < 0 {
err = getErrno()
} else {
fds[0] = int(buf[0])
fds[1] = int(buf[1])
}
return
}
func readdir_r(dir uintptr, entry *Dirent, result **Dirent) (err error) { func readdir_r(dir uintptr, entry *Dirent, result **Dirent) (err error) {
e1 := libc_readdir_r(unsafe.Pointer(dir), unsafe.Pointer(entry), unsafe.Pointer(result)) e1 := libc_readdir_r(unsafe.Pointer(dir), unsafe.Pointer(entry), unsafe.Pointer(result))
if e1 != 0 { if e1 != 0 {
@ -278,3 +291,7 @@ func libc_fstat(fd int32, ptr unsafe.Pointer) int32
// int lstat(const char *path, struct stat * buf); // int lstat(const char *path, struct stat * buf);
//export lstat$INODE64 //export lstat$INODE64
func libc_lstat(pathname *byte, ptr unsafe.Pointer) int32 func libc_lstat(pathname *byte, ptr unsafe.Pointer) int32
// int pipe(int32 *fds);
//export pipe
func libc_pipe(fds *int32) int32

Просмотреть файл

@ -63,3 +63,7 @@ var libcErrno uintptr
func getErrno() error { func getErrno() error {
return Errno(libcErrno) return Errno(libcErrno)
} }
func Pipe2(p []int, flags int) (err error) {
return ENOSYS // TODO
}

Просмотреть файл

@ -292,6 +292,10 @@ func Lstat(path string, p *Stat_t) (err error) {
return return
} }
func Pipe2(p []int, flags int) (err error) {
return ENOSYS // TODO
}
// int stat(const char *path, struct stat * buf); // int stat(const char *path, struct stat * buf);
//export stat //export stat
func libc_stat(pathname *byte, ptr unsafe.Pointer) int32 func libc_stat(pathname *byte, ptr unsafe.Pointer) int32

Просмотреть файл

@ -180,6 +180,9 @@ type SysProcAttr struct {
func Getgroups() ([]int, error) { return []int{1}, nil } func Getgroups() ([]int, error) { return []int{1}, nil }
func Gettimeofday(tv *Timeval) error { return ENOSYS } func Gettimeofday(tv *Timeval) error { return ENOSYS }
func Kill(pid int, signum Signal) error { return ENOSYS } func Kill(pid int, signum Signal) error { return ENOSYS }
func Pipe2(p []int, flags int) (err error) {
return ENOSYS // TODO
}
func Sendfile(outfd int, infd int, offset *int64, count int) (written int, err error) { func Sendfile(outfd int, infd int, offset *int64, count int) (written int, err error) {
return 0, ENOSYS return 0, ENOSYS
} }