Codebase list golang-github-pkg-xattr / 42b6d3be-5cd0-492a-8c29-914a92972878/upstream
Import upstream version 0.4.6 Debian Janitor 2 years ago
10 changed file(s) with 243 addition(s) and 56 deletion(s). Raw diff Collapse all Expand all
0 name: build
1 on: [push]
2
3 jobs:
4 build:
5 strategy:
6 matrix:
7 go-version: [1.15, 1.16, 1.17]
8 os: [ubuntu-latest, macos-latest]
9 runs-on: ${{ matrix.os }}
10 steps:
11 - name: Set up Go
12 uses: actions/setup-go@v2
13 with:
14 go-version: ${{ matrix.go-version }}
15
16 - name: Checkout code
17 uses: actions/checkout@v2
18
19 - name: Build
20 run: |
21 GOOS=freebsd go build
22 GOOS=windows go build
23 go build -v .
24
25 - name: Test
26 run: |
27 go vet
28 go test -v -race -coverprofile=coverage.txt -covermode=atomic
29
30 - name: After success
31 run: |
32 bash <(curl -s https://codecov.io/bash)
33
+0
-17
.travis.sh less more
0 #!/bin/sh -e
1
2 echo "Building for Linux..."
3 GOOS=linux go build
4
5 echo "Building for Darwin..."
6 GOOS=darwin go build
7
8 echo "Building for FreeBSD..."
9 GOOS=freebsd go build
10
11 echo "Building for Windows...(dummy)"
12 GOOS=windows go build
13
14 echo "Running tests..."
15 go vet
16 go test -v -race -coverprofile=coverage.txt -covermode=atomic
+0
-27
.travis.yml less more
0 language: go
1 sudo: false
2
3 go:
4 - "1.15.x"
5 - "1.14.x"
6
7 os:
8 - linux
9 - osx
10 - windows
11
12 before_install:
13 - export GO111MODULE=on
14 - go version
15 - go get golang.org/x/tools/cmd/goimports
16
17 install:
18 - go build
19
20 script:
21 - ./.travis.sh
22 # goimports on windows gives false positives
23 - if [[ "${TRAVIS_OS_NAME}" != "windows" ]]; then diff <(goimports -d .) <(printf ""); fi
24
25 after_success:
26 - bash <(curl -s https://codecov.io/bash)
00 [![GoDoc](https://godoc.org/github.com/pkg/xattr?status.svg)](http://godoc.org/github.com/pkg/xattr)
11 [![Go Report Card](https://goreportcard.com/badge/github.com/pkg/xattr)](https://goreportcard.com/report/github.com/pkg/xattr)
2 [![Build Status](https://travis-ci.org/pkg/xattr.svg?branch=master)](https://travis-ci.org/pkg/xattr)
3 [![Version](https://badge.fury.io/gh/pkg%2Fxattr.svg)](https://github.com/pkg/xattr/releases)
2 [![Build Status](https://github.com/pkg/xattr/workflows/build/badge.svg)](https://github.com/pkg/xattr/actions?query=workflow%3Abuild)
43 [![Codecov](https://codecov.io/gh/pkg/xattr/branch/master/graph/badge.svg)](https://codecov.io/gh/pkg/xattr)
54
65 xattr
76 =====
8 Extended attribute support for Go (linux + darwin + freebsd + netbsd).
7 Extended attribute support for Go (linux + darwin + freebsd + netbsd + solaris).
98
109 "Extended attributes are name:value pairs associated permanently with files and directories, similar to the environment strings associated with a process. An attribute may be defined or undefined. If it is defined, its value may be empty or non-empty." [See more...](https://en.wikipedia.org/wiki/Extended_file_attributes)
1110
2828 Err error
2929 }
3030
31 func (e *Error) Error() string {
32 return e.Op + " " + e.Path + " " + e.Name + ": " + e.Err.Error()
31 func (e *Error) Error() (errstr string) {
32 if e.Op != "" {
33 errstr += e.Op
34 }
35 if e.Path != "" {
36 if errstr != "" {
37 errstr += " "
38 }
39 errstr += e.Path
40 }
41 if e.Name != "" {
42 if errstr != "" {
43 errstr += " "
44 }
45 errstr += e.Name
46 }
47 if e.Err != nil {
48 if errstr != "" {
49 errstr += ": "
50 }
51 errstr += e.Err.Error()
52 }
53 return
3354 }
3455
3556 // Get retrieves extended attribute data associated with path. It will follow
84105 // truncated, and we retry with a bigger buffer. Contrary to documentation,
85106 // MacOS never seems to return ERANGE!
86107 // To keep the code simple, we always check both conditions, and sometimes
87 // double the buffer size without it being strictly neccessary.
108 // double the buffer size without it being strictly necessary.
88109 if err == syscall.ERANGE || read == size {
89110 // The buffer was too small. Try again.
90111 size <<= 1
0 // +build linux darwin
0 // +build linux darwin solaris
11
22 package xattr
33
22 package xattr
33
44 import (
5 "errors"
65 "os"
76 "syscall"
87
3029 func ignoringEINTR(fn func() error) (err error) {
3130 for {
3231 err = fn()
33 if !errors.Is(err, unix.EINTR) {
32 if err != unix.EINTR {
3433 break
3534 }
3635 }
0 // +build solaris
1
2 package xattr
3
4 import (
5 "os"
6 "syscall"
7
8 "golang.org/x/sys/unix"
9 )
10
11 const (
12 // XATTR_SUPPORTED will be true if the current platform is supported
13 XATTR_SUPPORTED = true
14
15 XATTR_CREATE = 0x1
16 XATTR_REPLACE = 0x2
17
18 // ENOATTR is not exported by the syscall package on Linux, because it is
19 // an alias for ENODATA. We export it here so it is available on all
20 // our supported platforms.
21 ENOATTR = syscall.ENODATA
22 )
23
24 func getxattr(path string, name string, data []byte) (int, error) {
25 f, err := os.OpenFile(path, os.O_RDONLY, 0)
26 if err != nil {
27 return 0, err
28 }
29 defer func() {
30 _ = f.Close()
31 }()
32 return fgetxattr(f, name, data)
33 }
34
35 func lgetxattr(path string, name string, data []byte) (int, error) {
36 return 0, unix.ENOTSUP
37 }
38
39 func fgetxattr(f *os.File, name string, data []byte) (int, error) {
40 fd, err := unix.Openat(int(f.Fd()), name, unix.O_RDONLY|unix.O_XATTR, 0)
41 if err != nil {
42 return 0, err
43 }
44 defer func() {
45 _ = unix.Close(fd)
46 }()
47 return unix.Read(fd, data)
48 }
49
50 func setxattr(path string, name string, data []byte, flags int) error {
51 f, err := os.OpenFile(path, os.O_RDONLY, 0)
52 if err != nil {
53 return err
54 }
55 err = fsetxattr(f, name, data, flags)
56 if err != nil {
57 _ = f.Close()
58 return err
59 }
60 return f.Close()
61 }
62
63 func lsetxattr(path string, name string, data []byte, flags int) error {
64 return unix.ENOTSUP
65 }
66
67 func fsetxattr(f *os.File, name string, data []byte, flags int) error {
68 mode := unix.O_WRONLY | unix.O_XATTR
69 if flags&XATTR_REPLACE != 0 {
70 mode |= unix.O_TRUNC
71 } else if flags&XATTR_CREATE != 0 {
72 mode |= unix.O_CREAT | unix.O_EXCL
73 } else {
74 mode |= unix.O_CREAT | unix.O_TRUNC
75 }
76 fd, err := unix.Openat(int(f.Fd()), name, mode, 0666)
77 if err != nil {
78 return err
79 }
80 if _, err = unix.Write(fd, data); err != nil {
81 _ = unix.Close(fd)
82 return err
83 }
84 return unix.Close(fd)
85 }
86
87 func removexattr(path string, name string) error {
88 fd, err := unix.Open(path, unix.O_RDONLY|unix.O_XATTR, 0)
89 if err != nil {
90 return err
91 }
92 f := os.NewFile(uintptr(fd), path);
93 defer func() {
94 _ = f.Close()
95 }()
96 return fremovexattr(f, name)
97 }
98
99 func lremovexattr(path string, name string) error {
100 return unix.ENOTSUP
101 }
102
103 func fremovexattr(f *os.File, name string) error {
104 fd, err := unix.Openat(int(f.Fd()), ".", unix.O_XATTR, 0)
105 if err != nil {
106 return err
107 }
108 defer func() {
109 _ = unix.Close(fd)
110 }()
111 return unix.Unlinkat(fd, name, 0)
112 }
113
114 func listxattr(path string, data []byte) (int, error) {
115 f, err := os.OpenFile(path, os.O_RDONLY, 0)
116 if err != nil {
117 return 0, err
118 }
119 defer func() {
120 _ = f.Close()
121 }()
122 return flistxattr(f, data)
123 }
124
125 func llistxattr(path string, data []byte) (int, error) {
126 return 0, unix.ENOTSUP
127 }
128
129 func flistxattr(f *os.File, data []byte) (int, error) {
130 fd, err := unix.Openat(int(f.Fd()), ".", unix.O_RDONLY|unix.O_XATTR, 0)
131 if err != nil {
132 return 0, err
133 }
134 xf := os.NewFile(uintptr(fd), f.Name())
135 defer func() {
136 _ = xf.Close()
137 }()
138 names, err := xf.Readdirnames(-1)
139 if err != nil {
140 return 0, err
141 }
142 var buf []byte
143 for _, name := range names {
144 buf = append(buf, append([]byte(name), '\000')...)
145 }
146 if data == nil {
147 return len(buf), nil
148 }
149 return copy(data, buf), nil
150 }
151
152 // stringsFromByteSlice converts a sequence of attributes to a []string.
153 // On Darwin and Linux, each entry is a NULL-terminated string.
154 func stringsFromByteSlice(buf []byte) (result []string) {
155 offset := 0
156 for index, b := range buf {
157 if b == 0 {
158 result = append(result, string(buf[offset:index]))
159 offset = index + 1
160 }
161 }
162 return
163 }
0 // +build linux darwin freebsd netbsd
0 // +build linux darwin freebsd netbsd solaris
11
22 package xattr
33
146146 // Test that Get/LGet, Set/LSet etc operate as expected on symlinks. The
147147 // functions should behave differently when operating on a symlink.
148148 func TestSymlink(t *testing.T) {
149 if runtime.GOOS == "solaris" || runtime.GOOS == "illumos" {
150 t.Skipf("extended attributes aren't supported for symlinks on %s", runtime.GOOS)
151 }
149152 dir, err := ioutil.TempDir("", "")
150153 if err != nil {
151154 t.Fatal(err)
280283 if !ok {
281284 log.Panicf("cannot unpack err=%#v", err)
282285 }
283 return err2.Err.(syscall.Errno)
286 err3, ok := err2.Err.(syscall.Errno)
287 if !ok {
288 log.Panicf("cannot unpack err2=%#v", err2)
289 }
290 return err3
284291 }
285292
286293 // wrappers to adapt "F" variants to the test
0 // +build !linux,!freebsd,!netbsd,!darwin
0 //go:build !linux && !freebsd && !netbsd && !darwin && !solaris
1 // +build !linux,!freebsd,!netbsd,!darwin,!solaris
12
23 package xattr
34
45 import (
56 "os"
7 "syscall"
8 )
9
10 const (
11 // We need to use the default for non supported operating systems
12 ENOATTR = syscall.ENODATA
613 )
714
815 // XATTR_SUPPORTED will be true if the current platform is supported