From: Georg Reinke Date: Fri, 11 Jan 2013 01:04:55 +0000 (-0800) Subject: syscall: implement Pipe2 on Linux and use it in ForkExec X-Git-Tag: go1.1rc2~1425 X-Git-Url: http://www.git.cypherpunks.su/?a=commitdiff_plain;h=e32d1154ec3176a81659720c1ca665e68ac95c42;p=gostls13.git 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 --- diff --git a/src/pkg/syscall/exec_bsd.go b/src/pkg/syscall/exec_bsd.go index 9c3af5ec95..318cbc060c 100644 --- a/src/pkg/syscall/exec_bsd.go +++ b/src/pkg/syscall/exec_bsd.go @@ -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 +} diff --git a/src/pkg/syscall/exec_linux.go b/src/pkg/syscall/exec_linux.go index adb6a06ba8..a8dc672b8c 100644 --- a/src/pkg/syscall/exec_linux.go +++ b/src/pkg/syscall/exec_linux.go @@ -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 +} diff --git a/src/pkg/syscall/exec_unix.go b/src/pkg/syscall/exec_unix.go index dd892a9abe..01b76c1068 100644 --- a/src/pkg/syscall/exec_unix.go +++ b/src/pkg/syscall/exec_unix.go @@ -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 } diff --git a/src/pkg/syscall/syscall_linux.go b/src/pkg/syscall/syscall_linux.go index 61c64b5f8a..f44fb48fa7 100644 --- a/src/pkg/syscall/syscall_linux.go +++ b/src/pkg/syscall/syscall_linux.go @@ -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 { diff --git a/src/pkg/syscall/zsyscall_linux_386.go b/src/pkg/syscall/zsyscall_linux_386.go index f1be0b3f85..3f0470c988 100644 --- a/src/pkg/syscall/zsyscall_linux_386.go +++ b/src/pkg/syscall/zsyscall_linux_386.go @@ -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) diff --git a/src/pkg/syscall/zsyscall_linux_amd64.go b/src/pkg/syscall/zsyscall_linux_amd64.go index 11179648da..3cdc1873b8 100644 --- a/src/pkg/syscall/zsyscall_linux_amd64.go +++ b/src/pkg/syscall/zsyscall_linux_amd64.go @@ -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) diff --git a/src/pkg/syscall/zsyscall_linux_arm.go b/src/pkg/syscall/zsyscall_linux_arm.go index 2966bb60d6..db17d96823 100644 --- a/src/pkg/syscall/zsyscall_linux_arm.go +++ b/src/pkg/syscall/zsyscall_linux_arm.go @@ -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)