github.com/go-xe2/third@v1.0.3/golang.org/x/sys/unix/xattr_test.go (about) 1 // Copyright 2018 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 // +build darwin freebsd linux netbsd 6 7 package unix_test 8 9 import ( 10 "io/ioutil" 11 "os" 12 "runtime" 13 "strings" 14 "testing" 15 16 "github.com/go-xe2/third/golang.org/x/sys/unix" 17 ) 18 19 func TestXattr(t *testing.T) { 20 defer chtmpdir(t)() 21 22 f := "xattr1" 23 touch(t, f) 24 25 xattrName := "user.test" 26 xattrDataSet := "gopher" 27 28 err := unix.Setxattr(f, xattrName, []byte{}, 0) 29 if err == unix.ENOTSUP || err == unix.EOPNOTSUPP { 30 t.Skip("filesystem does not support extended attributes, skipping test") 31 } else if err != nil { 32 t.Fatalf("Setxattr: %v", err) 33 } 34 35 err = unix.Setxattr(f, xattrName, []byte(xattrDataSet), 0) 36 if err != nil { 37 t.Fatalf("Setxattr: %v", err) 38 } 39 40 // find size 41 size, err := unix.Listxattr(f, nil) 42 if err != nil { 43 t.Fatalf("Listxattr: %v", err) 44 } 45 46 if size <= 0 { 47 t.Fatalf("Listxattr returned an empty list of attributes") 48 } 49 50 buf := make([]byte, size) 51 read, err := unix.Listxattr(f, buf) 52 if err != nil { 53 t.Fatalf("Listxattr: %v", err) 54 } 55 56 xattrs := stringsFromByteSlice(buf[:read]) 57 58 xattrWant := xattrName 59 if runtime.GOOS == "freebsd" { 60 // On FreeBSD, the namespace is stored separately from the xattr 61 // name and Listxattr doesn't return the namespace prefix. 62 xattrWant = strings.TrimPrefix(xattrWant, "user.") 63 } 64 found := false 65 for _, name := range xattrs { 66 if name == xattrWant { 67 found = true 68 } 69 } 70 71 if !found { 72 t.Errorf("Listxattr did not return previously set attribute '%s'", xattrName) 73 } 74 75 // find size 76 size, err = unix.Getxattr(f, xattrName, nil) 77 if err != nil { 78 t.Fatalf("Getxattr: %v", err) 79 } 80 81 if size <= 0 { 82 t.Fatalf("Getxattr returned an empty attribute") 83 } 84 85 xattrDataGet := make([]byte, size) 86 _, err = unix.Getxattr(f, xattrName, xattrDataGet) 87 if err != nil { 88 t.Fatalf("Getxattr: %v", err) 89 } 90 91 got := string(xattrDataGet) 92 if got != xattrDataSet { 93 t.Errorf("Getxattr: expected attribute value %s, got %s", xattrDataSet, got) 94 } 95 96 err = unix.Removexattr(f, xattrName) 97 if err != nil { 98 t.Fatalf("Removexattr: %v", err) 99 } 100 101 n := "nonexistent" 102 err = unix.Lsetxattr(n, xattrName, []byte(xattrDataSet), 0) 103 if err != unix.ENOENT { 104 t.Errorf("Lsetxattr: expected %v on non-existent file, got %v", unix.ENOENT, err) 105 } 106 107 _, err = unix.Lgetxattr(n, xattrName, nil) 108 if err != unix.ENOENT { 109 t.Errorf("Lgetxattr: %v", err) 110 } 111 112 s := "symlink1" 113 err = os.Symlink(n, s) 114 if err != nil { 115 t.Fatal(err) 116 } 117 118 err = unix.Lsetxattr(s, xattrName, []byte(xattrDataSet), 0) 119 if err != nil { 120 // Linux and Android doen't support xattrs on symlinks according 121 // to xattr(7), so just test that we get the proper error. 122 if (runtime.GOOS != "linux" && runtime.GOOS != "android") || err != unix.EPERM { 123 t.Fatalf("Lsetxattr: %v", err) 124 } 125 } 126 } 127 128 func TestFdXattr(t *testing.T) { 129 file, err := ioutil.TempFile("", "TestFdXattr") 130 if err != nil { 131 t.Fatal(err) 132 } 133 defer os.Remove(file.Name()) 134 defer file.Close() 135 136 fd := int(file.Fd()) 137 xattrName := "user.test" 138 xattrDataSet := "gopher" 139 140 err = unix.Fsetxattr(fd, xattrName, []byte(xattrDataSet), 0) 141 if err == unix.ENOTSUP || err == unix.EOPNOTSUPP { 142 t.Skip("filesystem does not support extended attributes, skipping test") 143 } else if err != nil { 144 t.Fatalf("Fsetxattr: %v", err) 145 } 146 147 // find size 148 size, err := unix.Flistxattr(fd, nil) 149 if err != nil { 150 t.Fatalf("Flistxattr: %v", err) 151 } 152 153 if size <= 0 { 154 t.Fatalf("Flistxattr returned an empty list of attributes") 155 } 156 157 buf := make([]byte, size) 158 read, err := unix.Flistxattr(fd, buf) 159 if err != nil { 160 t.Fatalf("Flistxattr: %v", err) 161 } 162 163 xattrs := stringsFromByteSlice(buf[:read]) 164 165 xattrWant := xattrName 166 if runtime.GOOS == "freebsd" { 167 // On FreeBSD, the namespace is stored separately from the xattr 168 // name and Listxattr doesn't return the namespace prefix. 169 xattrWant = strings.TrimPrefix(xattrWant, "user.") 170 } 171 found := false 172 for _, name := range xattrs { 173 if name == xattrWant { 174 found = true 175 } 176 } 177 178 if !found { 179 t.Errorf("Flistxattr did not return previously set attribute '%s'", xattrName) 180 } 181 182 // find size 183 size, err = unix.Fgetxattr(fd, xattrName, nil) 184 if err != nil { 185 t.Fatalf("Fgetxattr: %v", err) 186 } 187 188 if size <= 0 { 189 t.Fatalf("Fgetxattr returned an empty attribute") 190 } 191 192 xattrDataGet := make([]byte, size) 193 _, err = unix.Fgetxattr(fd, xattrName, xattrDataGet) 194 if err != nil { 195 t.Fatalf("Fgetxattr: %v", err) 196 } 197 198 got := string(xattrDataGet) 199 if got != xattrDataSet { 200 t.Errorf("Fgetxattr: expected attribute value %s, got %s", xattrDataSet, got) 201 } 202 203 err = unix.Fremovexattr(fd, xattrName) 204 if err != nil { 205 t.Fatalf("Fremovexattr: %v", err) 206 } 207 }