From 9d4e42a20653790449273b3c85e67d6d8bae6e2e Mon Sep 17 00:00:00 2001 From: Riku Voipio Date: Fri, 4 Mar 2016 11:29:42 +0200 Subject: [PATCH] x/sys/unix: add Dup2 wrapper for arm64/ppc64 arm64 doesn't have a Dup2 syscall, instead Dup3 is supposed to be used. Since Dup3 is linux-specific, provide a wrapper to make writing portable code easier. Updates golang/go#10235 To verify it, added a testcase for Dup and Dup2. Change-Id: I066bb60d62b2bd64d7ba0fdfbb334ce2213c78e9 Reviewed-on: https://go-review.googlesource.com/20178 Run-TryBot: Brad Fitzpatrick Reviewed-by: Riku Voipio Reviewed-by: Brad Fitzpatrick --- unix/syscall_linux_arm64.go | 4 ++++ unix/syscall_linux_ppc64x.go | 1 + unix/syscall_unix_test.go | 35 ++++++++++++++++++++++++++++++++++ unix/zsyscall_linux_ppc64.go | 10 ++++++++++ unix/zsyscall_linux_ppc64le.go | 10 ++++++++++ 5 files changed, 60 insertions(+) diff --git a/unix/syscall_linux_arm64.go b/unix/syscall_linux_arm64.go index 42581156..1f6f4b9a 100644 --- a/unix/syscall_linux_arm64.go +++ b/unix/syscall_linux_arm64.go @@ -152,6 +152,10 @@ func InotifyInit() (fd int, err error) { return InotifyInit1(0) } +func Dup2(oldfd int, newfd int) (err error) { + return Dup3(oldfd, newfd, 0) +} + // TODO(dfc): constants that should be in zsysnum_linux_arm64.go, remove // these when the deprecated syscalls that the syscall package relies on // are removed. diff --git a/unix/syscall_linux_ppc64x.go b/unix/syscall_linux_ppc64x.go index 2503b7f5..20a1c230 100644 --- a/unix/syscall_linux_ppc64x.go +++ b/unix/syscall_linux_ppc64x.go @@ -7,6 +7,7 @@ package unix +//sys Dup2(oldfd int, newfd int) (err error) //sys Fchown(fd int, uid int, gid int) (err error) //sys Fstat(fd int, stat *Stat_t) (err error) //sys Fstatfs(fd int, buf *Statfs_t) (err error) diff --git a/unix/syscall_unix_test.go b/unix/syscall_unix_test.go index bcc79d19..49208a00 100644 --- a/unix/syscall_unix_test.go +++ b/unix/syscall_unix_test.go @@ -316,3 +316,38 @@ func TestSeekFailure(t *testing.T) { t.Fatalf("Seek(-1, 0, 0) return error with empty message") } } + +func TestDup(t *testing.T) { + file, err := ioutil.TempFile("", "TestDup") + if err != nil { + t.Fatalf("Tempfile failed: %v", err) + } + defer os.Remove(file.Name()) + defer file.Close() + f := int(file.Fd()) + + newFd, err := unix.Dup(f) + if err != nil { + t.Fatalf("Dup: %v", err) + } + + err = unix.Dup2(newFd, newFd+1) + if err != nil { + t.Fatalf("Dup2: %v", err) + } + + b1 := []byte("Test123") + b2 := make([]byte, 7) + _, err = unix.Write(newFd+1, b1) + if err != nil { + t.Fatalf("Write to dup2 fd failed: %v", err) + } + _, err = unix.Seek(f, 0, 0) + _, err = unix.Read(f, b2) + if err != nil { + t.Fatalf("Read back failed: %v", err) + } + if string(b1) != string(b2) { + t.Errorf("Dup: stdout write not in file, expected %v, got %v", string(b1), string(b2)) + } +} diff --git a/unix/zsyscall_linux_ppc64.go b/unix/zsyscall_linux_ppc64.go index f8eaae9a..9c9fcb29 100644 --- a/unix/zsyscall_linux_ppc64.go +++ b/unix/zsyscall_linux_ppc64.go @@ -1216,6 +1216,16 @@ func Munlockall() (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func Dup2(oldfd int, newfd int) (err error) { + _, _, e1 := Syscall(SYS_DUP2, uintptr(oldfd), uintptr(newfd), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Fchown(fd int, uid int, gid int) (err error) { _, _, e1 := Syscall(SYS_FCHOWN, uintptr(fd), uintptr(uid), uintptr(gid)) if e1 != 0 { diff --git a/unix/zsyscall_linux_ppc64le.go b/unix/zsyscall_linux_ppc64le.go index 22d444fe..692a1e11 100644 --- a/unix/zsyscall_linux_ppc64le.go +++ b/unix/zsyscall_linux_ppc64le.go @@ -1216,6 +1216,16 @@ func Munlockall() (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func Dup2(oldfd int, newfd int) (err error) { + _, _, e1 := Syscall(SYS_DUP2, uintptr(oldfd), uintptr(newfd), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Fchown(fd int, uid int, gid int) (err error) { _, _, e1 := Syscall(SYS_FCHOWN, uintptr(fd), uintptr(uid), uintptr(gid)) if e1 != 0 {