123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118 |
- //go:build linux || darwin
- // +build linux darwin
- /*
- Copyright The containerd Authors.
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
- http://www.apache.org/licenses/LICENSE-2.0
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
- */
- package sysx
- import (
- "bytes"
- "golang.org/x/sys/unix"
- )
- // Listxattr calls syscall listxattr and reads all content
- // and returns a string array
- func Listxattr(path string) ([]string, error) {
- return listxattrAll(path, unix.Listxattr)
- }
- // Removexattr calls syscall removexattr
- func Removexattr(path string, attr string) (err error) {
- return unix.Removexattr(path, attr)
- }
- // Setxattr calls syscall setxattr
- func Setxattr(path string, attr string, data []byte, flags int) (err error) {
- return unix.Setxattr(path, attr, data, flags)
- }
- // Getxattr calls syscall getxattr
- func Getxattr(path, attr string) ([]byte, error) {
- return getxattrAll(path, attr, unix.Getxattr)
- }
- // LListxattr lists xattrs, not following symlinks
- func LListxattr(path string) ([]string, error) {
- return listxattrAll(path, unix.Llistxattr)
- }
- // LRemovexattr removes an xattr, not following symlinks
- func LRemovexattr(path string, attr string) (err error) {
- return unix.Lremovexattr(path, attr)
- }
- // LSetxattr sets an xattr, not following symlinks
- func LSetxattr(path string, attr string, data []byte, flags int) (err error) {
- return unix.Lsetxattr(path, attr, data, flags)
- }
- // LGetxattr gets an xattr, not following symlinks
- func LGetxattr(path, attr string) ([]byte, error) {
- return getxattrAll(path, attr, unix.Lgetxattr)
- }
- const defaultXattrBufferSize = 128
- type listxattrFunc func(path string, dest []byte) (int, error)
- func listxattrAll(path string, listFunc listxattrFunc) ([]string, error) {
- buf := make([]byte, defaultXattrBufferSize)
- n, err := listFunc(path, buf)
- for err == unix.ERANGE {
- // Buffer too small, use zero-sized buffer to get the actual size
- n, err = listFunc(path, []byte{})
- if err != nil {
- return nil, err
- }
- buf = make([]byte, n)
- n, err = listFunc(path, buf)
- }
- if err != nil {
- return nil, err
- }
- ps := bytes.Split(bytes.TrimSuffix(buf[:n], []byte{0}), []byte{0})
- var entries []string
- for _, p := range ps {
- if len(p) > 0 {
- entries = append(entries, string(p))
- }
- }
- return entries, nil
- }
- type getxattrFunc func(string, string, []byte) (int, error)
- func getxattrAll(path, attr string, getFunc getxattrFunc) ([]byte, error) {
- buf := make([]byte, defaultXattrBufferSize)
- n, err := getFunc(path, attr, buf)
- for err == unix.ERANGE {
- // Buffer too small, use zero-sized buffer to get the actual size
- n, err = getFunc(path, attr, []byte{})
- if err != nil {
- return nil, err
- }
- buf = make([]byte, n)
- n, err = getFunc(path, attr, buf)
- }
- if err != nil {
- return nil, err
- }
- return buf[:n], nil
- }
|