Codebase list golang-github-pkg-xattr / 8771568
New upstream version 0.4.8 Mathias Gibbens 1 year, 7 months ago
14 changed file(s) with 254 addition(s) and 57 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, 1.18]
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
11
22 go 1.14
33
4 require golang.org/x/sys v0.0.0-20201101102859-da207088b7d1
4 require golang.org/x/sys v0.0.0-20220408201424-a24fb2fb8a0f
00 golang.org/x/sys v0.0.0-20201101102859-da207088b7d1 h1:a/mKvvZr9Jcc8oKfcmgzyp7OwF73JPWsQLvH1z2Kxck=
11 golang.org/x/sys v0.0.0-20201101102859-da207088b7d1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
2 golang.org/x/sys v0.0.0-20220408201424-a24fb2fb8a0f h1:8w7RhxzTVgUzw/AH/9mUV5q0vMgy40SQRursCcfmkCw=
3 golang.org/x/sys v0.0.0-20220408201424-a24fb2fb8a0f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
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) Unwrap() error { return e.Err }
32
33 func (e *Error) Error() (errstr string) {
34 if e.Op != "" {
35 errstr += e.Op
36 }
37 if e.Path != "" {
38 if errstr != "" {
39 errstr += " "
40 }
41 errstr += e.Path
42 }
43 if e.Name != "" {
44 if errstr != "" {
45 errstr += " "
46 }
47 errstr += e.Name
48 }
49 if e.Err != nil {
50 if errstr != "" {
51 errstr += ": "
52 }
53 errstr += e.Err.Error()
54 }
55 return
3356 }
3457
3558 // Get retrieves extended attribute data associated with path. It will follow
84107 // truncated, and we retry with a bigger buffer. Contrary to documentation,
85108 // MacOS never seems to return ERANGE!
86109 // To keep the code simple, we always check both conditions, and sometimes
87 // double the buffer size without it being strictly neccessary.
110 // double the buffer size without it being strictly necessary.
88111 if err == syscall.ERANGE || read == size {
89112 // The buffer was too small. Try again.
90113 size <<= 1
0 //go:build freebsd || netbsd
01 // +build freebsd netbsd
12
23 package xattr
0 //go:build darwin
01 // +build darwin
12
23 package xattr
0 // +build linux darwin
0 //go:build linux || darwin || solaris
1 // +build linux darwin solaris
12
23 package xattr
34
0 //go:build linux
01 // +build linux
12
23 package xattr
34
45 import (
5 "errors"
66 "os"
77 "syscall"
88
3030 func ignoringEINTR(fn func() error) (err error) {
3131 for {
3232 err = fn()
33 if !errors.Is(err, unix.EINTR) {
33 if err != unix.EINTR {
3434 break
3535 }
3636 }
0 //go:build solaris
1 // +build solaris
2
3 package xattr
4
5 import (
6 "os"
7 "syscall"
8
9 "golang.org/x/sys/unix"
10 )
11
12 const (
13 // XATTR_SUPPORTED will be true if the current platform is supported
14 XATTR_SUPPORTED = true
15
16 XATTR_CREATE = 0x1
17 XATTR_REPLACE = 0x2
18
19 // ENOATTR is not exported by the syscall package on Linux, because it is
20 // an alias for ENODATA. We export it here so it is available on all
21 // our supported platforms.
22 ENOATTR = syscall.ENODATA
23 )
24
25 func getxattr(path string, name string, data []byte) (int, error) {
26 f, err := os.OpenFile(path, os.O_RDONLY, 0)
27 if err != nil {
28 return 0, err
29 }
30 defer func() {
31 _ = f.Close()
32 }()
33 return fgetxattr(f, name, data)
34 }
35
36 func lgetxattr(path string, name string, data []byte) (int, error) {
37 return 0, unix.ENOTSUP
38 }
39
40 func fgetxattr(f *os.File, name string, data []byte) (int, error) {
41 fd, err := unix.Openat(int(f.Fd()), name, unix.O_RDONLY|unix.O_XATTR, 0)
42 if err != nil {
43 return 0, err
44 }
45 defer func() {
46 _ = unix.Close(fd)
47 }()
48 return unix.Read(fd, data)
49 }
50
51 func setxattr(path string, name string, data []byte, flags int) error {
52 f, err := os.OpenFile(path, os.O_RDONLY, 0)
53 if err != nil {
54 return err
55 }
56 err = fsetxattr(f, name, data, flags)
57 if err != nil {
58 _ = f.Close()
59 return err
60 }
61 return f.Close()
62 }
63
64 func lsetxattr(path string, name string, data []byte, flags int) error {
65 return unix.ENOTSUP
66 }
67
68 func fsetxattr(f *os.File, name string, data []byte, flags int) error {
69 mode := unix.O_WRONLY | unix.O_XATTR
70 if flags&XATTR_REPLACE != 0 {
71 mode |= unix.O_TRUNC
72 } else if flags&XATTR_CREATE != 0 {
73 mode |= unix.O_CREAT | unix.O_EXCL
74 } else {
75 mode |= unix.O_CREAT | unix.O_TRUNC
76 }
77 fd, err := unix.Openat(int(f.Fd()), name, mode, 0666)
78 if err != nil {
79 return err
80 }
81 if _, err = unix.Write(fd, data); err != nil {
82 _ = unix.Close(fd)
83 return err
84 }
85 return unix.Close(fd)
86 }
87
88 func removexattr(path string, name string) error {
89 fd, err := unix.Open(path, unix.O_RDONLY|unix.O_XATTR, 0)
90 if err != nil {
91 return err
92 }
93 f := os.NewFile(uintptr(fd), path)
94 defer func() {
95 _ = f.Close()
96 }()
97 return fremovexattr(f, name)
98 }
99
100 func lremovexattr(path string, name string) error {
101 return unix.ENOTSUP
102 }
103
104 func fremovexattr(f *os.File, name string) error {
105 fd, err := unix.Openat(int(f.Fd()), ".", unix.O_XATTR, 0)
106 if err != nil {
107 return err
108 }
109 defer func() {
110 _ = unix.Close(fd)
111 }()
112 return unix.Unlinkat(fd, name, 0)
113 }
114
115 func listxattr(path string, data []byte) (int, error) {
116 f, err := os.OpenFile(path, os.O_RDONLY, 0)
117 if err != nil {
118 return 0, err
119 }
120 defer func() {
121 _ = f.Close()
122 }()
123 return flistxattr(f, data)
124 }
125
126 func llistxattr(path string, data []byte) (int, error) {
127 return 0, unix.ENOTSUP
128 }
129
130 func flistxattr(f *os.File, data []byte) (int, error) {
131 fd, err := unix.Openat(int(f.Fd()), ".", unix.O_RDONLY|unix.O_XATTR, 0)
132 if err != nil {
133 return 0, unix.ENOTSUP
134 }
135 xf := os.NewFile(uintptr(fd), f.Name())
136 defer func() {
137 _ = xf.Close()
138 }()
139 names, err := xf.Readdirnames(-1)
140 if err != nil {
141 return 0, err
142 }
143 var buf []byte
144 for _, name := range names {
145 buf = append(buf, append([]byte(name), '\000')...)
146 }
147 if data == nil {
148 return len(buf), nil
149 }
150 return copy(data, buf), nil
151 }
152
153 // stringsFromByteSlice converts a sequence of attributes to a []string.
154 // On Darwin and Linux, each entry is a NULL-terminated string.
155 func stringsFromByteSlice(buf []byte) (result []string) {
156 offset := 0
157 for index, b := range buf {
158 if b == 0 {
159 result = append(result, string(buf[offset:index]))
160 offset = index + 1
161 }
162 }
163 return
164 }
0 // +build linux darwin freebsd netbsd
0 //go:build linux || darwin || freebsd || netbsd || solaris
1 // +build linux darwin freebsd netbsd solaris
12
23 package xattr
34
146147 // Test that Get/LGet, Set/LSet etc operate as expected on symlinks. The
147148 // functions should behave differently when operating on a symlink.
148149 func TestSymlink(t *testing.T) {
150 if runtime.GOOS == "solaris" || runtime.GOOS == "illumos" {
151 t.Skipf("extended attributes aren't supported for symlinks on %s", runtime.GOOS)
152 }
149153 dir, err := ioutil.TempDir("", "")
150154 if err != nil {
151155 t.Fatal(err)
280284 if !ok {
281285 log.Panicf("cannot unpack err=%#v", err)
282286 }
283 return err2.Err.(syscall.Errno)
287 err3, ok := err2.Err.(syscall.Errno)
288 if !ok {
289 log.Panicf("cannot unpack err2=%#v", err2)
290 }
291 return err3
284292 }
285293
286294 // 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