diff options
author | Andreas Gruenbacher <agruen@linbit.com> | 2013-10-22 18:59:58 +0200 |
---|---|---|
committer | Andreas Gruenbacher <agruen@linbit.com> | 2013-11-18 21:38:12 +0100 |
commit | 1c80572042ea4909d8487fa6eabf35d240e6c7f7 (patch) | |
tree | a4cdbc48512f306d9c2cce11b31f03028b3abd58 | |
parent | da8435b86268e29f597d748bcdf4da18900f30a6 (diff) | |
download | attr-1c80572042ea4909d8487fa6eabf35d240e6c7f7.tar.gz |
Make attr_get and attr_getf behave as described in the man page
This addresses bug http://savannah.nongnu.org/bugs/?40337.
-rw-r--r-- | libattr/libattr.c | 23 |
1 files changed, 19 insertions, 4 deletions
diff --git a/libattr/libattr.c b/libattr/libattr.c index 4582e27..21ffd92 100644 --- a/libattr/libattr.c +++ b/libattr/libattr.c @@ -104,20 +104,27 @@ int attr_get(const char *path, const char *attrname, char *attrvalue, int *valuelength, int flags) { + ssize_t (*get)(const char *, const char *, void *, size_t) = + flags & ATTR_DONTFOLLOW ? lgetxattr : getxattr; int c, compat; char name[MAXNAMELEN+16]; for (compat = 0; compat < 2; compat++) { if ((c = api_convert(name, attrname, flags, compat)) < 0) return c; - if (flags & ATTR_DONTFOLLOW) - c = lgetxattr(path, name, attrvalue, *valuelength); - else - c = getxattr(path, name, attrvalue, *valuelength); + c = get(path, name, attrvalue, *valuelength); if (c < 0 && (errno == ENOATTR || errno == ENOTSUP)) continue; break; } + if (c < 0 && errno == ERANGE) { + int size = get(path, name, NULL, 0); + if (size >= 0) { + *valuelength = size; + errno = E2BIG; + } + return c; + } if (c < 0) return c; *valuelength = c; @@ -139,6 +146,14 @@ attr_getf(int fd, const char *attrname, char *attrvalue, continue; break; } + if (c < 0 && errno == ERANGE) { + int size = fgetxattr(fd, name, NULL, 0); + if (size >= 0) { + *valuelength = size; + errno = E2BIG; + } + return c; + } if (c < 0) return c; *valuelength = c; |