diff --git a/internal/lib/os/os.go b/internal/lib/os/os.go index 9350272c..591f2ced 100644 --- a/internal/lib/os/os.go +++ b/internal/lib/os/os.go @@ -274,9 +274,6 @@ func Mkdir(name string, perm FileMode) error { // func MkdirAll(path string, perm FileMode) error // func MkdirTemp(dir, pattern string) (string, error) // func NewSyscallError(syscall string, err error) error -func Pipe() (r *File, w *File, err error) { - panic("todo: os.Pipe") -} // func ReadFile(name string) ([]byte, error) diff --git a/internal/lib/os/pipe2_unix.go b/internal/lib/os/pipe2_unix.go new file mode 100644 index 00000000..2d293fdb --- /dev/null +++ b/internal/lib/os/pipe2_unix.go @@ -0,0 +1,22 @@ +// Copyright 2017 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. + +//go:build dragonfly || freebsd || linux || netbsd || openbsd || solaris + +package os + +import "syscall" + +// Pipe returns a connected pair of Files; reads from r return bytes written to w. +// It returns the files and an error, if any. +func Pipe() (r *File, w *File, err error) { + var p [2]int + + e := syscall.Pipe2(p[0:], syscall.O_CLOEXEC) + if e != nil { + return nil, nil, NewSyscallError("pipe2", e) + } + + return newFile(p[0], "|0", kindPipe), newFile(p[1], "|1", kindPipe), nil +} diff --git a/internal/lib/os/pipe_unix.go b/internal/lib/os/pipe_unix.go new file mode 100644 index 00000000..2eb11a04 --- /dev/null +++ b/internal/lib/os/pipe_unix.go @@ -0,0 +1,28 @@ +// Copyright 2009 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. + +//go:build aix || darwin + +package os + +import "syscall" + +// Pipe returns a connected pair of Files; reads from r return bytes written to w. +// It returns the files and an error, if any. +func Pipe() (r *File, w *File, err error) { + var p [2]int + + // See ../syscall/exec.go for description of lock. + syscall.ForkLock.RLock() + e := syscall.Pipe(p[0:]) + if e != nil { + syscall.ForkLock.RUnlock() + return nil, nil, NewSyscallError("pipe", e) + } + syscall.CloseOnExec(p[0]) + syscall.CloseOnExec(p[1]) + syscall.ForkLock.RUnlock() + + return newFile(p[0], "|0", kindPipe), newFile(p[1], "|1", kindPipe), nil +} diff --git a/internal/lib/os/pipe_wasm.go b/internal/lib/os/pipe_wasm.go new file mode 100644 index 00000000..87a29b1f --- /dev/null +++ b/internal/lib/os/pipe_wasm.go @@ -0,0 +1,16 @@ +// Copyright 2023 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. + +//go:build wasm + +package os + +import "syscall" + +// Pipe returns a connected pair of Files; reads from r return bytes written to w. +// It returns the files and an error, if any. +func Pipe() (r *File, w *File, err error) { + // Neither GOOS=js nor GOOS=wasip1 have pipes. + return nil, nil, NewSyscallError("pipe", syscall.ENOSYS) +} diff --git a/internal/lib/syscall/exec_unix.go b/internal/lib/syscall/exec_unix.go index d979d891..21a12178 100644 --- a/internal/lib/syscall/exec_unix.go +++ b/internal/lib/syscall/exec_unix.go @@ -68,10 +68,7 @@ import ( var ForkLock sync.RWMutex func CloseOnExec(fd int) { - /* TODO(xsw): - fcntl(fd, F_SETFD, FD_CLOEXEC) - */ - panic("todo: syscall.CloseOnExec") + os.Fcntl(c.Int(fd), syscall.F_SETFD, syscall.FD_CLOEXEC) } func SetNonblock(fd int, nonblocking bool) (err error) {