1
0
mirror of https://github.com/golang/go synced 2024-11-20 10:54:49 -07:00

syscall: implement Pipe2 on Linux and use it in ForkExec

Fixes #2656.

R=golang-dev, bradfitz, iant, minux.ma
CC=golang-dev
https://golang.org/cl/7062057
This commit is contained in:
Georg Reinke 2013-01-10 17:04:55 -08:00 committed by Ian Lance Taylor
parent 6e981c181c
commit e32d1154ec
7 changed files with 74 additions and 7 deletions

View File

@ -221,3 +221,17 @@ childerror:
// and this shuts up the compiler.
panic("unreached")
}
// 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
}

View File

@ -233,3 +233,20 @@ childerror:
// and this shuts up the compiler.
panic("unreached")
}
// Try to open a pipe with O_CLOEXEC set on both file descriptors.
func forkExecPipe(p []int) (err error) {
err = Pipe2(p, O_CLOEXEC)
// pipe2 was added in 2.6.27 and our minimum requirement is 2.6.23, so it
// might not be implemented.
if err == ENOSYS {
if err = Pipe(p); err != nil {
return
}
if _, err = fcntl(p[0], F_SETFD, FD_CLOEXEC); err != nil {
return
}
_, err = fcntl(p[1], F_SETFD, FD_CLOEXEC)
}
return
}

View File

@ -183,13 +183,7 @@ func forkExec(argv0 string, argv []string, attr *ProcAttr) (pid int, err error)
ForkLock.Lock()
// Allocate child status pipe close on exec.
if err = Pipe(p[0:]); err != nil {
goto error
}
if _, err = fcntl(p[0], F_SETFD, FD_CLOEXEC); err != nil {
goto error
}
if _, err = fcntl(p[1], F_SETFD, FD_CLOEXEC); err != nil {
if err = forkExecPipe(p[:]); err != nil {
goto error
}

View File

@ -39,6 +39,18 @@ func Pipe(p []int) (err error) {
return
}
//sysnb pipe2(p *[2]_C_int, flags int) (err error)
func Pipe2(p []int, flags int) (err error) {
if len(p) != 2 {
return EINVAL
}
var pp [2]_C_int
err = pipe2(&pp, flags)
p[0] = int(pp[0])
p[1] = int(pp[1])
return
}
//sys utimes(path string, times *[2]Timeval) (err error)
func Utimes(path string, tv []Timeval) (err error) {
if len(tv) != 2 {

View File

@ -49,6 +49,16 @@ func pipe(p *[2]_C_int) (err error) {
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
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 = e1
}
return
}
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func utimes(path string, times *[2]Timeval) (err error) {
var _p0 *byte
_p0, err = BytePtrFromString(path)

View File

@ -49,6 +49,16 @@ func pipe(p *[2]_C_int) (err error) {
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
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 = e1
}
return
}
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func utimes(path string, times *[2]Timeval) (err error) {
var _p0 *byte
_p0, err = BytePtrFromString(path)

View File

@ -49,6 +49,16 @@ func pipe(p *[2]_C_int) (err error) {
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
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 = e1
}
return
}
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func utimes(path string, times *[2]Timeval) (err error) {
var _p0 *byte
_p0, err = BytePtrFromString(path)