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