1// Copyright 2013 The Go Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style
3// license that can be found in the LICENSE file.
4
5package os
6
7import "syscall"
8
9// Pipe returns a connected pair of Files; reads from r return bytes written to w.
10// It returns the files and an error, if any.
11func Pipe() (r *File, w *File, err error) {
12	var p [2]int
13
14	e := syscall.Pipe2(p[0:], syscall.O_CLOEXEC)
15	// pipe2 was added in 2.6.27 and our minimum requirement is 2.6.23, so it
16	// might not be implemented.
17	if e == syscall.ENOSYS {
18		// See ../syscall/exec.go for description of lock.
19		syscall.ForkLock.RLock()
20		e = syscall.Pipe(p[0:])
21		if e != nil {
22			syscall.ForkLock.RUnlock()
23			return nil, nil, NewSyscallError("pipe", e)
24		}
25		syscall.CloseOnExec(p[0])
26		syscall.CloseOnExec(p[1])
27		syscall.ForkLock.RUnlock()
28	} else if e != nil {
29		return nil, nil, NewSyscallError("pipe2", e)
30	}
31
32	return NewFile(uintptr(p[0]), "|0"), NewFile(uintptr(p[1]), "|1"), nil
33}
34