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  }