From 4d1e95bb63c4d43369ea335680aa65000e3f3866 Mon Sep 17 00:00:00 2001 From: Tobias Klauser Date: Tue, 30 Oct 2018 00:40:24 +0000 Subject: [PATCH] os: add support for long path names on solaris RemoveAll Follow CL 146020 and enable RemoveAll based on Unlinkat and Openat on solaris. Updates #27029 Change-Id: I0b0e92f4422fa960a13dcd3e9adb57cd23f09ed4 Reviewed-on: https://go-review.googlesource.com/c/145839 Run-TryBot: Tobias Klauser Reviewed-by: Brad Fitzpatrick Reviewed-by: Ian Lance Taylor TryBot-Result: Gobot Gobot --- src/internal/syscall/unix/asm_solaris.s | 10 ++++ src/internal/syscall/unix/at_solaris.go | 75 +++++++++++++++++++++++++ src/os/removeall_at.go | 2 +- src/os/removeall_noat.go | 2 +- src/os/removeall_test.go | 4 +- 5 files changed, 89 insertions(+), 4 deletions(-) create mode 100644 src/internal/syscall/unix/asm_solaris.s create mode 100644 src/internal/syscall/unix/at_solaris.go diff --git a/src/internal/syscall/unix/asm_solaris.s b/src/internal/syscall/unix/asm_solaris.s new file mode 100644 index 0000000000..a7ad26df9b --- /dev/null +++ b/src/internal/syscall/unix/asm_solaris.s @@ -0,0 +1,10 @@ +// Copyright 2018 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. + +#include "textflag.h" + +// System calls for Solaris are implemented in runtime/syscall_solaris.go + +TEXT ·sysvicall6(SB),NOSPLIT,$0-88 + JMP syscall·sysvicall6(SB) diff --git a/src/internal/syscall/unix/at_solaris.go b/src/internal/syscall/unix/at_solaris.go new file mode 100644 index 0000000000..d63ee990fd --- /dev/null +++ b/src/internal/syscall/unix/at_solaris.go @@ -0,0 +1,75 @@ +// Copyright 2018 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 unix + +import ( + "syscall" + "unsafe" +) + +// Implemented in runtime/syscall_solaris.go. +func sysvicall6(trap, nargs, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err syscall.Errno) + +//go:cgo_import_dynamic libc_fstatat fstatat "libc.so" +//go:cgo_import_dynamic libc_openat openat "libc.so" +//go:cgo_import_dynamic libc_unlinkat unlinkat "libc.so" + +//go:linkname procFstatat libc_fstatat +//go:linkname procOpenat libc_openat +//go:linkname procUnlinkat libc_unlinkat + +var ( + procFstatat, + procOpenat, + procUnlinkat uintptr +) + +const AT_REMOVEDIR = 0x1 +const AT_SYMLINK_NOFOLLOW = 0x1000 + +func Unlinkat(dirfd int, path string, flags int) error { + var p *byte + p, err := syscall.BytePtrFromString(path) + if err != nil { + return err + } + + _, _, errno := sysvicall6(uintptr(unsafe.Pointer(&procUnlinkat)), 3, uintptr(dirfd), uintptr(unsafe.Pointer(p)), uintptr(flags), 0, 0, 0) + if errno != 0 { + return errno + } + + return nil +} + +func Openat(dirfd int, path string, flags int, perm uint32) (int, error) { + var p *byte + p, err := syscall.BytePtrFromString(path) + if err != nil { + return 0, err + } + + fd, _, errno := sysvicall6(uintptr(unsafe.Pointer(&procOpenat)), 4, uintptr(dirfd), uintptr(unsafe.Pointer(p)), uintptr(flags), uintptr(perm), 0, 0) + if errno != 0 { + return 0, errno + } + + return int(fd), nil +} + +func Fstatat(dirfd int, path string, stat *syscall.Stat_t, flags int) error { + var p *byte + p, err := syscall.BytePtrFromString(path) + if err != nil { + return err + } + + _, _, errno := sysvicall6(uintptr(unsafe.Pointer(&procFstatat)), 4, uintptr(dirfd), uintptr(unsafe.Pointer(p)), uintptr(unsafe.Pointer(stat)), uintptr(flags), 0, 0) + if errno != 0 { + return errno + } + + return nil +} diff --git a/src/os/removeall_at.go b/src/os/removeall_at.go index 062b81e577..b7ed2aa6d4 100644 --- a/src/os/removeall_at.go +++ b/src/os/removeall_at.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 linux darwin openbsd netbsd dragonfly +// +build linux darwin openbsd netbsd dragonfly solaris package os diff --git a/src/os/removeall_noat.go b/src/os/removeall_noat.go index 1b85a6afa5..02af047d6e 100644 --- a/src/os/removeall_noat.go +++ b/src/os/removeall_noat.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 !linux,!darwin,!openbsd,!netbsd,!dragonfly +// +build !linux,!darwin,!openbsd,!netbsd,!dragonfly,!solaris package os diff --git a/src/os/removeall_test.go b/src/os/removeall_test.go index a1006230da..4b6f3e9256 100644 --- a/src/os/removeall_test.go +++ b/src/os/removeall_test.go @@ -153,7 +153,7 @@ func TestRemoveAllLarge(t *testing.T) { func TestRemoveAllLongPath(t *testing.T) { switch runtime.GOOS { - case "linux", "darwin", "openbsd", "netbsd", "dragonfly": + case "linux", "darwin", "openbsd", "netbsd", "dragonfly", "solaris": break default: t.Skip("skipping for not implemented platforms") @@ -201,7 +201,7 @@ func TestRemoveAllLongPath(t *testing.T) { func TestRemoveAllDot(t *testing.T) { switch runtime.GOOS { - case "linux", "darwin", "openbsd", "netbsd", "dragonfly": + case "linux", "darwin", "openbsd", "netbsd", "dragonfly", "solaris": break default: t.Skip("skipping for not implemented platforms") -- 2.50.0