pkg/system.getxattr: handle changed size case

lgetxattr(2) man page says:

> If size is specified as zero, these calls return the  current  size  of
> the  named extended attribute (and leave value unchanged).  This can be
> used to determine the size of the buffer that should be supplied  in  a
> subsequent  call.   (But, bear in mind that there is a possibility that
> the attribute value may change between the two calls,  so  that  it  is
> still necessary to check the return status from the second call.)

The current code does not handle the case when the size changes between
the two calls, and the new size is larger.

Fix the above problem, and slightly simplify the code.

Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
This commit is contained in:
Kir Kolyshkin 2020-02-26 06:44:25 -08:00
parent 28f62c5a35
commit 669056f93d
1 changed files with 8 additions and 9 deletions

View File

@ -10,24 +10,23 @@ func Lgetxattr(path string, attr string) ([]byte, error) {
dest := make([]byte, 128)
sz, errno := unix.Lgetxattr(path, attr, dest)
switch {
case errno == unix.ENODATA:
return nil, nil
case errno == unix.ERANGE:
// 128 byte array might just not be good enough. A dummy buffer is used
// to get the real size of the xattrs on disk
for errno == unix.ERANGE {
// Buffer too small, use zero-sized buffer to get the actual size
sz, errno = unix.Lgetxattr(path, attr, []byte{})
if errno != nil {
return nil, errno
}
dest = make([]byte, sz)
sz, errno = unix.Lgetxattr(path, attr, dest)
if errno != nil {
return nil, errno
}
}
switch {
case errno == unix.ENODATA:
return nil, nil
case errno != nil:
return nil, errno
}
return dest[:sz], nil
}