golang.org/x/sys@v0.20.1-0.20240517151509-673e0f94c16d/unix/xattr_zos_test.go (about) 1 // Copyright 2024 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 zos 6 7 package unix_test 8 9 import ( 10 "os" 11 "testing" 12 13 "golang.org/x/sys/unix" 14 ) 15 16 func TestXattr(t *testing.T) { 17 defer chtmpdir(t)() 18 19 f := "xattr1" 20 touch(t, f) 21 22 xattrName := "system.filetag" 23 xattrDataSet := make([]byte, 4) 24 xattrDataSet[0] = 0xFF 25 xattrDataSet[1] = 0xFF 26 xattrDataSet[2] = 0 27 xattrDataSet[3] = 0 28 29 err := unix.Setxattr(f, xattrName, xattrDataSet, 0) 30 if err != nil { 31 t.Fatalf("Setxattr: %v", err) 32 } 33 34 // find size 35 size, err := unix.Listxattr(f, nil) 36 if err != nil { 37 t.Fatalf("Listxattr: %v", err) 38 } 39 40 if size <= 0 { 41 t.Fatalf("Listxattr returned an empty list of attributes") 42 } 43 44 buf := make([]byte, size) 45 read, err := unix.Listxattr(f, buf) 46 if err != nil { 47 t.Fatalf("Listxattr: %v", err) 48 } 49 50 xattrs := stringsFromByteSlice(buf[:read]) 51 52 xattrWant := xattrName 53 found := false 54 for _, name := range xattrs { 55 if name == xattrWant { 56 found = true 57 break 58 } 59 } 60 61 if !found { 62 t.Errorf("Listxattr did not return previously set attribute '%s'", xattrName) 63 } 64 65 // find size 66 size, err = unix.Getxattr(f, xattrName, nil) 67 if err != nil { 68 t.Fatalf("Getxattr: %v", err) 69 } 70 71 if size <= 0 { 72 t.Fatalf("Getxattr returned an empty attribute") 73 } 74 75 xattrDataGet := make([]byte, size) 76 _, err = unix.Getxattr(f, xattrName, xattrDataGet) 77 if err != nil { 78 t.Fatalf("Getxattr: %v", err) 79 } 80 got := string([]byte(xattrDataGet)) 81 if got != string(xattrDataSet) { 82 t.Errorf("Getxattr: expected attribute value %s, got %s", xattrDataSet, got) 83 } 84 85 err = unix.Removexattr(f, xattrName) 86 if err != nil { 87 t.Fatalf("Removexattr: %v", err) 88 } 89 90 //confirm xattr removed 91 // find size 92 size, err = unix.Listxattr(f, nil) 93 if err != nil { 94 t.Fatalf("Listxattr: %v", err) 95 } 96 if size != 0 { 97 buf := make([]byte, size) 98 read, err = unix.Listxattr(f, buf) 99 if err != nil { 100 t.Fatalf("Listxattr: %v", err) 101 } 102 103 xattrs = stringsFromByteSlice(buf[:read]) 104 105 found = false 106 for _, name := range xattrs { 107 if name == xattrWant { 108 found = true 109 break 110 } 111 if found { 112 t.Errorf("Removexattr failed to remove attribute '%s'", xattrName) 113 } 114 } 115 } 116 n := "nonexistent" 117 err = unix.Lsetxattr(n, xattrName, xattrDataSet, 0) 118 if err != unix.ENOENT { 119 t.Errorf("Lsetxattr: expected %v on non-existent file, got %v", unix.ENODATA, err) 120 } 121 122 _, err = unix.Lgetxattr(f, n, nil) 123 if err != unix.ENODATA { 124 t.Errorf("Lgetxattr: %v", err) 125 } 126 127 _, err = unix.Lgetxattr(n, xattrName, nil) 128 if err != unix.ENOENT { 129 t.Errorf("Lgetxattr: %v", err) 130 } 131 } 132 133 func TestFdXattr(t *testing.T) { 134 file, err := os.CreateTemp("", "TestFdXattr") 135 if err != nil { 136 t.Fatal(err) 137 } 138 defer os.Remove(file.Name()) 139 defer file.Close() 140 141 fd := int(file.Fd()) 142 xattrName := "system.filetag" 143 xattrDataSet := make([]byte, 4) 144 xattrDataSet[0] = 0xFF 145 xattrDataSet[1] = 0xFF 146 xattrDataSet[2] = 0 147 xattrDataSet[3] = 0 148 149 err = unix.Fsetxattr(fd, xattrName, xattrDataSet, 0) 150 if err == unix.ENOTSUP || err == unix.EOPNOTSUPP { 151 t.Skip("filesystem does not support extended attributes, skipping test") 152 } else if err != nil { 153 t.Fatalf("Fsetxattr: %v", err) 154 } 155 156 // find size 157 size, err := unix.Flistxattr(fd, nil) 158 if err != nil { 159 t.Fatalf("Flistxattr: %v", err) 160 } 161 if size <= 0 { 162 t.Fatalf("Flistxattr returned an empty list of attributes") 163 } 164 165 buf := make([]byte, size) 166 read, err := unix.Flistxattr(fd, buf) 167 if err != nil { 168 t.Fatalf("Flistxattr: %v", err) 169 } 170 171 xattrs := stringsFromByteSlice(buf[:read]) 172 173 xattrWant := xattrName 174 found := false 175 for _, name := range xattrs { 176 if name == xattrWant { 177 found = true 178 break 179 } 180 } 181 182 if !found { 183 t.Errorf("Flistxattr did not return previously set attribute '%s'", xattrName) 184 } 185 186 // find size 187 size, err = unix.Fgetxattr(fd, xattrName, nil) 188 if err != nil { 189 t.Fatalf("Fgetxattr: %v", err) 190 } 191 192 if size <= 0 { 193 t.Fatalf("Fgetxattr returned an empty attribute") 194 } 195 196 xattrDataGet := make([]byte, size) 197 _, err = unix.Fgetxattr(fd, xattrName, xattrDataGet) 198 if err != nil { 199 t.Fatalf("Fgetxattr: %v", err) 200 } 201 202 got := string([]byte(xattrDataGet)) 203 if got != string(xattrDataSet) { 204 t.Errorf("Getxattr: expected attribute value %s, got %s", xattrDataSet, got) 205 } 206 207 err = unix.Fremovexattr(fd, xattrName) 208 if err != nil { 209 t.Fatalf("Fremovexattr: %v", err) 210 } 211 212 //confirm xattr removed 213 // find size 214 size, err = unix.Flistxattr(fd, nil) 215 if err != nil { 216 t.Fatalf("Flistxattr: %v", err) 217 } 218 if size != 0 { 219 buf := make([]byte, size) 220 read, err = unix.Flistxattr(fd, buf) 221 if err != nil { 222 t.Fatalf("Flistxattr: %v", err) 223 } 224 225 xattrs = stringsFromByteSlice(buf[:read]) 226 227 found = false 228 for _, name := range xattrs { 229 if name == xattrWant { 230 found = true 231 break 232 } 233 if found { 234 t.Errorf("Fremovexattr failed to remove attribute '%s'", xattrName) 235 } 236 } 237 } 238 }