Skip to content

Commit c78df85

Browse files
dankegeldeadprogram
authored andcommitted
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.
1 parent c0d257d commit c78df85

File tree

6 files changed

+84
-4
lines changed

6 files changed

+84
-4
lines changed

src/os/pipe_test.go

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
//go:build windows || darwin || (linux && !baremetal && !wasi)
2+
// +build windows darwin linux,!baremetal,!wasi
3+
4+
// Copyright 2021 The Go Authors. All rights reserved.
5+
// Use of this source code is governed by a BSD-style
6+
// license that can be found in the LICENSE file.
7+
8+
// Test pipes on Unix and Windows systems.
9+
10+
package os_test
11+
12+
import (
13+
"bytes"
14+
"os"
15+
"testing"
16+
)
17+
18+
// TestSmokePipe is a simple smoke test for Pipe().
19+
func TestSmokePipe(t *testing.T) {
20+
// Procedure:
21+
// 1. Get the bytes
22+
// 2. Light the bytes on fire
23+
// 3. Smoke the bytes
24+
25+
r, w, err := os.Pipe()
26+
if err != nil {
27+
t.Fatal(err)
28+
return // TODO: remove once Fatal is fatal
29+
}
30+
defer r.Close()
31+
defer w.Close()
32+
33+
msg := []byte("Sed nvlla nisi ardva virtvs")
34+
n, err := w.Write(msg)
35+
if err != nil {
36+
t.Errorf("Writing to fresh pipe failed, error %v", err)
37+
}
38+
want := len(msg)
39+
if n != want {
40+
t.Errorf("Writing to fresh pipe wrote %d bytes, expected %d", n, want)
41+
}
42+
43+
buf := make([]byte, 2*len(msg))
44+
n, err = r.Read(buf)
45+
if err != nil {
46+
t.Errorf("Reading from pipe failed, error %v", err)
47+
}
48+
if n != want {
49+
t.Errorf("Reading from pipe got %d bytes, expected %d", n, want)
50+
}
51+
// Read() does not set len(buf), so do it here.
52+
buf = buf[:n]
53+
if !bytes.Equal(buf, msg) {
54+
t.Errorf("Reading from fresh pipe got wrong bytes")
55+
}
56+
}

src/syscall/syscall_libc.go

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -153,10 +153,6 @@ func Kill(pid int, sig Signal) (err error) {
153153

154154
type SysProcAttr struct{}
155155

156-
func Pipe2(p []int, flags int) (err error) {
157-
return ENOSYS // TODO
158-
}
159-
160156
// TODO
161157
type WaitStatus uint32
162158

src/syscall/syscall_libc_darwin.go

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -246,6 +246,19 @@ func Fdopendir(fd int) (dir uintptr, err error) {
246246
return
247247
}
248248

249+
func Pipe2(fds []int, flags int) (err error) {
250+
// Mac only has Pipe, which ignores the flags argument
251+
buf := make([]int32, 2)
252+
fail := int(libc_pipe(&buf[0]))
253+
if fail < 0 {
254+
err = getErrno()
255+
} else {
256+
fds[0] = int(buf[0])
257+
fds[1] = int(buf[1])
258+
}
259+
return
260+
}
261+
249262
func readdir_r(dir uintptr, entry *Dirent, result **Dirent) (err error) {
250263
e1 := libc_readdir_r(unsafe.Pointer(dir), unsafe.Pointer(entry), unsafe.Pointer(result))
251264
if e1 != 0 {
@@ -278,3 +291,7 @@ func libc_fstat(fd int32, ptr unsafe.Pointer) int32
278291
// int lstat(const char *path, struct stat * buf);
279292
//export lstat$INODE64
280293
func libc_lstat(pathname *byte, ptr unsafe.Pointer) int32
294+
295+
// int pipe(int32 *fds);
296+
//export pipe
297+
func libc_pipe(fds *int32) int32

src/syscall/syscall_libc_nintendoswitch.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,3 +63,7 @@ var libcErrno uintptr
6363
func getErrno() error {
6464
return Errno(libcErrno)
6565
}
66+
67+
func Pipe2(p []int, flags int) (err error) {
68+
return ENOSYS // TODO
69+
}

src/syscall/syscall_libc_wasi.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -292,6 +292,10 @@ func Lstat(path string, p *Stat_t) (err error) {
292292
return
293293
}
294294

295+
func Pipe2(p []int, flags int) (err error) {
296+
return ENOSYS // TODO
297+
}
298+
295299
// int stat(const char *path, struct stat * buf);
296300
//export stat
297301
func libc_stat(pathname *byte, ptr unsafe.Pointer) int32

src/syscall/syscall_nonhosted.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -180,6 +180,9 @@ type SysProcAttr struct {
180180
func Getgroups() ([]int, error) { return []int{1}, nil }
181181
func Gettimeofday(tv *Timeval) error { return ENOSYS }
182182
func Kill(pid int, signum Signal) error { return ENOSYS }
183+
func Pipe2(p []int, flags int) (err error) {
184+
return ENOSYS // TODO
185+
}
183186
func Sendfile(outfd int, infd int, offset *int64, count int) (written int, err error) {
184187
return 0, ENOSYS
185188
}

0 commit comments

Comments
 (0)