--- src/os/pipe_bsd.go
+++ src/os/pipe_bsd.go
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-// +build darwin dragonfly freebsd nacl netbsd openbsd solaris
+// +build darwin dragonfly nacl netbsd openbsd solaris
 
 package os
 
--- /dev/null
+++ src/os/pipe_freebsd.go
@@ -0,0 +1,20 @@
+// 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.
+
+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("pipe", e)
+	}
+
+	return NewFile(uintptr(p[0]), "|0"), NewFile(uintptr(p[1]), "|1"), nil
+}
--- src/syscall/exec_bsd.go
+++ src/syscall/exec_bsd.go
@@ -256,17 +256,3 @@ childerror:
 		RawSyscall(SYS_EXIT, 253, 0, 0)
 	}
 }
-
-// Try to open a pipe with O_CLOEXEC set on both file descriptors.
-func forkExecPipe(p []int) error {
-	err := Pipe(p)
-	if err != nil {
-		return err
-	}
-	_, err = fcntl(p[0], F_SETFD, FD_CLOEXEC)
-	if err != nil {
-		return err
-	}
-	_, err = fcntl(p[1], F_SETFD, FD_CLOEXEC)
-	return err
-}
--- /dev/null
+++ src/syscall/exec_freebsd.go
@@ -0,0 +1,9 @@
+// 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.
+
+package syscall
+
+func forkExecPipe(p []int) error {
+	return Pipe2(p, O_CLOEXEC)
+}
--- /dev/null
+++ src/syscall/forkpipe_bsd.go
@@ -0,0 +1,20 @@
+// Copyright 2011 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.
+
+// +build darwin dragonfly netbsd openbsd
+
+package syscall
+
+func forkExecPipe(p []int) error {
+	err := Pipe(p)
+	if err != nil {
+		return err
+	}
+	_, err = fcntl(p[0], F_SETFD, FD_CLOEXEC)
+	if err != nil {
+		return err
+	}
+	_, err = fcntl(p[1], F_SETFD, FD_CLOEXEC)
+	return err
+}
--- src/syscall/syscall_freebsd.go
+++ src/syscall/syscall_freebsd.go
@@ -66,14 +66,21 @@ func direntNamlen(buf []byte) (uint64, bool) {
 	return readInt(buf, unsafe.Offsetof(Dirent{}.Namlen), unsafe.Sizeof(Dirent{}.Namlen))
 }
 
-//sysnb pipe() (r int, w int, err error)
+func Pipe(p []int) error {
+	return Pipe2(p, 0)
+}
+
+//sysnb pipe2(p *[2]_C_int, flags int) (err error)
 
-func Pipe(p []int) (err error) {
+func Pipe2(p []int, flags int) error {
 	if len(p) != 2 {
 		return EINVAL
 	}
-	p[0], p[1], err = pipe()
-	return
+	var pp [2]_C_int
+	err := pipe2(&pp, flags)
+	p[0] = int(pp[0])
+	p[1] = int(pp[1])
+	return err
 }
 
 func GetsockoptIPMreqn(fd, level, opt int) (*IPMreqn, error) {
--- src/syscall/zsyscall_freebsd_386.go
+++ src/syscall/zsyscall_freebsd_386.go
@@ -261,10 +261,8 @@ func fcntl(fd int, cmd int, arg int) (val int, err error) {
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
-func pipe() (r int, w int, err error) {
-	r0, r1, e1 := RawSyscall(SYS_PIPE, 0, 0, 0)
-	r = int(r0)
-	w = int(r1)
+func pipe2(p *[2]_C_int, flags int) (err error) {
+	_, _, e1 := RawSyscall(SYS_PIPE2, uintptr(unsafe.Pointer(p)), uintptr(flags), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
--- src/syscall/zsyscall_freebsd_amd64.go
+++ src/syscall/zsyscall_freebsd_amd64.go
@@ -261,10 +261,8 @@ func fcntl(fd int, cmd int, arg int) (val int, err error) {
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
-func pipe() (r int, w int, err error) {
-	r0, r1, e1 := RawSyscall(SYS_PIPE, 0, 0, 0)
-	r = int(r0)
-	w = int(r1)
+func pipe2(p *[2]_C_int, flags int) (err error) {
+	_, _, e1 := RawSyscall(SYS_PIPE2, uintptr(unsafe.Pointer(p)), uintptr(flags), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
--- src/syscall/zsyscall_freebsd_arm.go
+++ src/syscall/zsyscall_freebsd_arm.go
@@ -261,10 +261,8 @@ func fcntl(fd int, cmd int, arg int) (val int, err error) {
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
-func pipe() (r int, w int, err error) {
-	r0, r1, e1 := RawSyscall(SYS_PIPE, 0, 0, 0)
-	r = int(r0)
-	w = int(r1)
+func pipe2(p *[2]_C_int, flags int) (err error) {
+	_, _, e1 := RawSyscall(SYS_PIPE2, uintptr(unsafe.Pointer(p)), uintptr(flags), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
