Skip to content

Commit bbd0be0

Browse files
committed
sysx/xattr: improve listxattrAll
The current code * is hard to read (at least for me, that is); * is suboptimal (always calls listxattr() twice); * doesn't handle the condition when attributes size is changed in between the two calls to listxattr(). Fix all three issues by reusing the logic from getxattrAll(). Signed-off-by: Kir Kolyshkin <[email protected]>
1 parent 9e256e6 commit bbd0be0

1 file changed

Lines changed: 18 additions & 20 deletions

File tree

sysx/xattr.go

Lines changed: 18 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -70,32 +70,30 @@ const defaultXattrBufferSize = 128
7070
type listxattrFunc func(path string, dest []byte) (int, error)
7171

7272
func listxattrAll(path string, listFunc listxattrFunc) ([]string, error) {
73-
var p []byte // nil on first execution
74-
75-
for {
76-
n, err := listFunc(path, p) // first call gets buffer size.
73+
buf := make([]byte, defaultXattrBufferSize)
74+
n, err := listFunc(path, buf)
75+
for err == unix.ERANGE {
76+
// Buffer too small, use zero-sized buffer to get the actual size
77+
n, err = listFunc(path, []byte{})
7778
if err != nil {
7879
return nil, err
7980
}
81+
buf = make([]byte, n)
82+
n, err = listFunc(path, buf)
83+
}
84+
if err != nil {
85+
return nil, err
86+
}
8087

81-
if n > len(p) {
82-
p = make([]byte, n)
83-
continue
84-
}
85-
86-
p = p[:n]
87-
88-
ps := bytes.Split(bytes.TrimSuffix(p, []byte{0}), []byte{0})
89-
var entries []string
90-
for _, p := range ps {
91-
s := string(p)
92-
if s != "" {
93-
entries = append(entries, s)
94-
}
88+
ps := bytes.Split(bytes.TrimSuffix(buf[:n], []byte{0}), []byte{0})
89+
var entries []string
90+
for _, p := range ps {
91+
if len(p) > 0 {
92+
entries = append(entries, string(p))
9593
}
96-
97-
return entries, nil
9894
}
95+
96+
return entries, nil
9997
}
10098

10199
type getxattrFunc func(string, string, []byte) (int, error)

0 commit comments

Comments
 (0)