diff --git a/src/os/pipe_test.go b/src/os/pipe_test.go new file mode 100644 index 00000000..dcb99528 --- /dev/null +++ b/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") + } +} diff --git a/src/syscall/syscall_libc.go b/src/syscall/syscall_libc.go index bbc54888..3fa3db04 100644 --- a/src/syscall/syscall_libc.go +++ b/src/syscall/syscall_libc.go @@ -153,10 +153,6 @@ func Kill(pid int, sig Signal) (err error) { type SysProcAttr struct{} -func Pipe2(p []int, flags int) (err error) { - return ENOSYS // TODO -} - // TODO type WaitStatus uint32 diff --git a/src/syscall/syscall_libc_darwin.go b/src/syscall/syscall_libc_darwin.go index 770e71b5..80acebfc 100644 --- a/src/syscall/syscall_libc_darwin.go +++ b/src/syscall/syscall_libc_darwin.go @@ -246,6 +246,19 @@ func Fdopendir(fd int) (dir uintptr, err error) { 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) { e1 := libc_readdir_r(unsafe.Pointer(dir), unsafe.Pointer(entry), unsafe.Pointer(result)) if e1 != 0 { @@ -278,3 +291,7 @@ func libc_fstat(fd int32, ptr unsafe.Pointer) int32 // int lstat(const char *path, struct stat * buf); //export lstat$INODE64 func libc_lstat(pathname *byte, ptr unsafe.Pointer) int32 + +// int pipe(int32 *fds); +//export pipe +func libc_pipe(fds *int32) int32 diff --git a/src/syscall/syscall_libc_nintendoswitch.go b/src/syscall/syscall_libc_nintendoswitch.go index 98494643..52b73939 100644 --- a/src/syscall/syscall_libc_nintendoswitch.go +++ b/src/syscall/syscall_libc_nintendoswitch.go @@ -63,3 +63,7 @@ var libcErrno uintptr func getErrno() error { return Errno(libcErrno) } + +func Pipe2(p []int, flags int) (err error) { + return ENOSYS // TODO +} diff --git a/src/syscall/syscall_libc_wasi.go b/src/syscall/syscall_libc_wasi.go index 6bfab090..cf9da47f 100644 --- a/src/syscall/syscall_libc_wasi.go +++ b/src/syscall/syscall_libc_wasi.go @@ -292,6 +292,10 @@ func Lstat(path string, p *Stat_t) (err error) { return } +func Pipe2(p []int, flags int) (err error) { + return ENOSYS // TODO +} + // int stat(const char *path, struct stat * buf); //export stat func libc_stat(pathname *byte, ptr unsafe.Pointer) int32 diff --git a/src/syscall/syscall_nonhosted.go b/src/syscall/syscall_nonhosted.go index 4a558550..3528087f 100644 --- a/src/syscall/syscall_nonhosted.go +++ b/src/syscall/syscall_nonhosted.go @@ -180,6 +180,9 @@ type SysProcAttr struct { func Getgroups() ([]int, error) { return []int{1}, nil } func Gettimeofday(tv *Timeval) 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) { return 0, ENOSYS }